drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c
Extension
.c
Size
45800 bytes
Lines
859
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

if (dram_bw_table->entries[i].pre_derate_dram_bw_kbps >= bandwidth_kbps) {
				uclk_khz = dram_bw_table->entries[i].min_uclk_khz;
				break;
			}
	}

	return uclk_khz;
}

static void get_minimum_clocks_for_latency(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out,
	double *uclk,
	double *fclk,
	double *dcfclk)
{
	int min_clock_index_for_latency;

	if (in_out->display_cfg->stage3.success)
		min_clock_index_for_latency = in_out->display_cfg->stage3.min_clk_index_for_latency;
	else
		min_clock_index_for_latency = in_out->display_cfg->stage1.min_clk_index_for_latency;

	*dcfclk = in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].min_dcfclk_khz;
	*fclk = in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].min_fclk_khz;
	*uclk = dram_bw_kbps_to_uclk_khz(in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].pre_derate_dram_bw_kbps,
		&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
}

static unsigned long dml_round_up(double a)
{
	if (a - (unsigned long)a > 0) {
		return ((unsigned long)a) + 1;
	}
	return (unsigned long)a;
}

static void calculate_system_active_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
{
	double min_uclk_avg, min_uclk_urgent, min_uclk_bw;
	double min_fclk_avg, min_fclk_urgent, min_fclk_bw;
	double min_dcfclk_avg, min_dcfclk_urgent, min_dcfclk_bw;
	double min_uclk_latency, min_fclk_latency, min_dcfclk_latency;
	const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;

	min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.average_bw_dram_kbps
											/ ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100)),
							&in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);

	if (in_out->display_cfg->display_config.hostvm_enable)
		min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.urgent_bw_dram_kbps
										/ ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel_and_vm / 100)),
							 &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);
	else
		min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.urgent_bw_dram_kbps
										/ ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100)),
							 &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table);

	min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg;

	min_fclk_avg = (double)mode_support_result->global.active.average_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes;
	min_fclk_avg = (double)min_fclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.fclk_derate_percent / 100);

	min_fclk_urgent = (double)mode_support_result->global.active.urgent_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes;
	min_fclk_urgent = (double)min_fclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.fclk_derate_percent / 100);

	min_fclk_bw = min_fclk_urgent > min_fclk_avg ? min_fclk_urgent : min_fclk_avg;

	min_dcfclk_avg = (double)mode_support_result->global.active.average_bw_sdp_kbps / in_out->soc_bb->return_bus_width_bytes;
	min_dcfclk_avg = (double)min_dcfclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dcfclk_derate_percent / 100);

	min_dcfclk_urgent = (double)mode_support_result->global.active.urgent_bw_sdp_kbps / in_out->soc_bb->return_bus_width_bytes;
	min_dcfclk_urgent = (double)min_dcfclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dcfclk_derate_percent / 100);

	min_dcfclk_bw = min_dcfclk_urgent > min_dcfclk_avg ? min_dcfclk_urgent : min_dcfclk_avg;

	get_minimum_clocks_for_latency(in_out, &min_uclk_latency, &min_fclk_latency, &min_dcfclk_latency);

	in_out->programming->min_clocks.dcn4x.active.uclk_khz = dml_round_up(min_uclk_bw > min_uclk_latency ? min_uclk_bw : min_uclk_latency);
	in_out->programming->min_clocks.dcn4x.active.fclk_khz = dml_round_up(min_fclk_bw > min_fclk_latency ? min_fclk_bw : min_fclk_latency);
	in_out->programming->min_clocks.dcn4x.active.dcfclk_khz = dml_round_up(min_dcfclk_bw > min_dcfclk_latency ? min_dcfclk_bw : min_dcfclk_latency);
}

static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out)
{
	double min_uclk_avg, min_uclk_urgent, min_uclk_bw;
	double min_fclk_avg, min_fclk_urgent, min_fclk_bw;
	double min_dcfclk_avg, min_dcfclk_urgent, min_dcfclk_bw;
	double min_fclk_latency, min_dcfclk_latency;
	double min_uclk_latency;
	const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result;

Annotation

Implementation Notes