drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
Extension
.c
Size
63828 bytes
Lines
2069
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct dsc_mst_fairness_params {
	struct dc_crtc_timing *timing;
	struct dc_sink *sink;
	struct dc_dsc_bw_range bw_range;
	bool compression_possible;
	struct drm_dp_mst_port *port;
	enum dsc_clock_force_state clock_force_enable;
	uint32_t num_slices_h;
	uint32_t num_slices_v;
	uint32_t bpp_overwrite;
	struct amdgpu_dm_connector *aconnector;
};

#if defined(CONFIG_DRM_AMD_DC_FP)
static uint16_t get_fec_overhead_multiplier(struct dc_link *dc_link)
{
	u8 link_coding_cap;
	uint16_t fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_8B_10B;

	link_coding_cap = dc_link_dp_mst_decide_link_encoding_format(dc_link);
	if (link_coding_cap == DP_128b_132b_ENCODING)
		fec_overhead_multiplier_x1000 = PBN_FEC_OVERHEAD_MULTIPLIER_128B_132B;

	return fec_overhead_multiplier_x1000;
}

static int kbps_to_peak_pbn(int kbps, uint16_t fec_overhead_multiplier_x1000)
{
	u64 peak_kbps = kbps;

	peak_kbps *= 1006;
	peak_kbps *= fec_overhead_multiplier_x1000;
	peak_kbps = div_u64(peak_kbps, 1000 * 1000);
	return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000));
}

static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params,
		struct dsc_mst_fairness_vars *vars,
		int count,
		int k)
{
	struct drm_connector *drm_connector;
	int i;
	struct dc_dsc_config_options dsc_options = {0};

	for (i = 0; i < count; i++) {
		drm_connector = &params[i].aconnector->base;

		dc_dsc_get_default_config_option(params[i].sink->ctx->dc, &dsc_options);
		dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;

		memset(&params[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg));
		if (vars[i + k].dsc_enabled && dc_dsc_compute_config(
					params[i].sink->ctx->dc->res_pool->dscs[0],
					&params[i].sink->dsc_caps.dsc_dec_caps,
					&dsc_options,
					0,
					params[i].timing,
					dc_link_get_highest_encoding_format(params[i].aconnector->dc_link),
					&params[i].timing->dsc_cfg)) {
			params[i].timing->flags.DSC = 1;

			if (params[i].bpp_overwrite)
				params[i].timing->dsc_cfg.bits_per_pixel = params[i].bpp_overwrite;
			else
				params[i].timing->dsc_cfg.bits_per_pixel = vars[i + k].bpp_x16;

			if (params[i].num_slices_h)
				params[i].timing->dsc_cfg.num_slices_h = params[i].num_slices_h;

			if (params[i].num_slices_v)
				params[i].timing->dsc_cfg.num_slices_v = params[i].num_slices_v;
		} else {
			params[i].timing->flags.DSC = 0;
		}
		params[i].timing->dsc_cfg.mst_pbn = vars[i + k].pbn;
	}

	for (i = 0; i < count; i++) {
		if (params[i].sink) {
			if (params[i].sink->sink_signal != SIGNAL_TYPE_VIRTUAL &&
				params[i].sink->sink_signal != SIGNAL_TYPE_NONE)
				DRM_DEBUG_DRIVER("MST_DSC %s i=%d dispname=%s\n", __func__, i,
					params[i].sink->edid_caps.display_name);
		}

		DRM_DEBUG_DRIVER("MST_DSC dsc=%d bits_per_pixel=%d pbn=%d\n",
			params[i].timing->flags.DSC,
			params[i].timing->dsc_cfg.bits_per_pixel,
			vars[i + k].pbn);

Annotation

Implementation Notes