From: Austin Zheng <[email protected]> [Why/How] 1. DPMM also needs to consider the per-DPM derate when calculating the clocks that will be used by mode programming. Otherwise DPMM calculations can result in rounding up to the next DPM anyways.
clk index value used by mode support is not reliable when trying to determine the actual per-dpm derate. 2. Also update how per-dpm derates are stored so each derate applies until an upper bound. Upperbound of 0 signifies this derate is used for the remaining DPMs. To simplify logic, all derates for all clocks should have the same number of entries and the last entry should have an upperbound of 0. 3. Deprecate system_active_average derates from the derate table and move them to the per-DPM structure The remaining derates (urgent, dcn_mall, system idle) are unchanged Reviewed-by: Dillon Varone <[email protected]> Signed-off-by: Austin Zheng <[email protected]> Signed-off-by: James Lin <[email protected]> --- .../dml21/inc/bounding_boxes/dcn42_soc_bb.h | 25 ++--- .../dml21/inc/bounding_boxes/dcn42b_soc_bb.h | 25 ++--- .../dml21/inc/bounding_boxes/dcn4_soc_bb.h | 25 ++--- .../dml21/inc/dml_top_soc_parameter_types.h | 44 +++++++- .../src/dml2_core/dml2_core_dcn4_calcs.c | 19 ++-- .../dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c | 106 +++++++++++++++++- .../src/inc/dml2_internal_shared_types.h | 1 + 7 files changed, 181 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h index b21beebc52bd..52f906e41fb4 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42_soc_bb.h @@ -16,13 +16,6 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params = .fclk_derate_percent = 80, .dcfclk_derate_percent = 80, }, - .system_active_average = { - .dram_derate_percent_pixel = 30, - .dram_derate_percent_vm = 30, - .dram_derate_percent_pixel_and_vm = 30, - .fclk_derate_percent = 60, - .dcfclk_derate_percent = 60, - }, .dcn_mall_prefetch_urgent = { .dram_derate_percent_pixel = 65, .dram_derate_percent_vm = 30, @@ -45,6 +38,17 @@ static const struct dml2_soc_qos_parameters dml_dcn42_variant_a_soc_qos_params = .dcfclk_derate_percent = 60, }, }, + .derate_table_per_dpm = { + .dram_per_dpm_derate_pixel = { + {.derate_percent = 30, .clk_upperbound_threshold_khz = 0}, + }, + .fclk_per_dpm_derate = { + {.derate_percent = 60, .clk_upperbound_threshold_khz = 0}, + }, + .dcfclk_per_dpm_derate = { + {.derate_percent = 60, .clk_upperbound_threshold_khz = 0}, + }, + }, .writeback = { .base_latency_us = 12, .scaling_factor_us = 0, @@ -134,13 +138,6 @@ static const struct dml2_soc_bb dml2_socbb_dcn42 = { .fclk_derate_percent = 80, .dcfclk_derate_percent = 80, }, - .system_active_average = { - .dram_derate_percent_pixel = 30, - .dram_derate_percent_vm = 30, - .dram_derate_percent_pixel_and_vm = 30, - .fclk_derate_percent = 60, - .dcfclk_derate_percent = 60, - }, .dcn_mall_prefetch_urgent = { .dram_derate_percent_pixel = 65, .dram_derate_percent_vm = 30, diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42b_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42b_soc_bb.h index 5d844ff4b671..33eb583e3365 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42b_soc_bb.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn42b_soc_bb.h @@ -17,13 +17,6 @@ static const struct dml2_soc_qos_parameters dml_dcn42b_variant_a_soc_qos_params .fclk_derate_percent = 80, .dcfclk_derate_percent = 80, }, - .system_active_average = { - .dram_derate_percent_pixel = 30, - .dram_derate_percent_vm = 30, - .dram_derate_percent_pixel_and_vm = 30, - .fclk_derate_percent = 60, - .dcfclk_derate_percent = 60, - }, .dcn_mall_prefetch_urgent = { .dram_derate_percent_pixel = 65, .dram_derate_percent_vm = 30, @@ -46,6 +39,17 @@ static const struct dml2_soc_qos_parameters dml_dcn42b_variant_a_soc_qos_params .dcfclk_derate_percent = 60, }, }, + .derate_table_per_dpm = { + .dram_per_dpm_derate_pixel = { + {.derate_percent = 30, .clk_upperbound_threshold_khz = 0}, + }, + .fclk_per_dpm_derate = { + {.derate_percent = 60, .clk_upperbound_threshold_khz = 0}, + }, + .dcfclk_per_dpm_derate = { + {.derate_percent = 60, .clk_upperbound_threshold_khz = 0}, + }, + }, .writeback = { .base_latency_us = 12, .scaling_factor_us = 0, @@ -134,13 +138,6 @@ static const struct dml2_soc_bb dml2_socbb_dcn42b = { .fclk_derate_percent = 80, .dcfclk_derate_percent = 80, }, - .system_active_average = { - .dram_derate_percent_pixel = 30, - .dram_derate_percent_vm = 30, - .dram_derate_percent_pixel_and_vm = 30, - .fclk_derate_percent = 60, - .dcfclk_derate_percent = 60, - }, .dcn_mall_prefetch_urgent = { .dram_derate_percent_pixel = 65, .dram_derate_percent_vm = 30, diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h index 16a4f97bca4e..f26366ebeeda 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/bounding_boxes/dcn4_soc_bb.h @@ -16,13 +16,6 @@ static const struct dml2_soc_qos_parameters dml_dcn4_variant_a_soc_qos_params = .fclk_derate_percent = 76, .dcfclk_derate_percent = 100, }, - .system_active_average = { - .dram_derate_percent_pixel = 17, - .dram_derate_percent_vm = 0, - .dram_derate_percent_pixel_and_vm = 0, - .fclk_derate_percent = 57, - .dcfclk_derate_percent = 75, - }, .dcn_mall_prefetch_urgent = { .dram_derate_percent_pixel = 40, .dram_derate_percent_vm = 0, @@ -45,6 +38,17 @@ static const struct dml2_soc_qos_parameters dml_dcn4_variant_a_soc_qos_params = .dcfclk_derate_percent = 100, }, }, + .derate_table_per_dpm = { + .dram_per_dpm_derate_pixel = { + {.derate_percent = 17, .clk_upperbound_threshold_khz = 0}, + }, + .fclk_per_dpm_derate = { + {.derate_percent = 57, .clk_upperbound_threshold_khz = 0}, + }, + .dcfclk_per_dpm_derate = { + {.derate_percent = 75, .clk_upperbound_threshold_khz = 0}, + }, + }, .writeback = { .base_latency_us = 12, .scaling_factor_us = 0, @@ -142,13 +146,6 @@ static const struct dml2_soc_bb dml2_socbb_dcn401 = { .fclk_derate_percent = 76, .dcfclk_derate_percent = 100, }, - .system_active_average = { - .dram_derate_percent_pixel = 15, - .dram_derate_percent_vm = 0, - .dram_derate_percent_pixel_and_vm = 0, - .fclk_derate_percent = 57, - .dcfclk_derate_percent = 75, - }, .dcn_mall_prefetch_urgent = { .dram_derate_percent_pixel = 40, .dram_derate_percent_vm = 0, diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h index b830e95b27c8..45208f804d2b 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h @@ -20,7 +20,6 @@ struct dml2_soc_derate_values { struct dml2_soc_derates { struct dml2_soc_derate_values system_active_urgent; - struct dml2_soc_derate_values system_active_average; struct dml2_soc_derate_values dcn_mall_prefetch_urgent; struct dml2_soc_derate_values dcn_mall_prefetch_average; struct dml2_soc_derate_values system_idle_average; @@ -71,8 +70,22 @@ enum dml2_qos_param_type { dml2_qos_param_type_dcn4x }; -//Indicies mapped to DPM level -// Unpopulated indicies should fallback to the global derate value. +// Per-DPM derate structure: each element pairs a derate percentage with its clock threshold +// Requirements: +// - Index 0 must always be populated (the base/default derate) +// - Last populated entry must have clk_upperbound_threshold_khz = 0 +// - All clock arrays within a power state should have the same number of entries +// - If a non-zero DPM index has derate_percent = 0, fall back to index 0 +// Unpopulated derates should fallback to the global derate value. +// Each element pairs a derate percentage with its threshold +struct dml2_soc_derate_values_per_dpm_v2 { + unsigned int derate_percent; + unsigned int clk_upperbound_threshold_khz; +}; + +// Legacy structure - for backward compatibility as driver debug values can override the values. (will temporarily break driver overrides) +// Per-DPM derate arrays for system_active_average (the only power state that varies by DPM) +// Urgent derates are constant across DPMs and come from derate_table.system_active_urgent struct dml2_soc_derate_values_per_dpm { unsigned int dram_derate_percent_pixel[DML_MAX_CLK_TABLE_SIZE]; unsigned int fclk_derate_percent[DML_MAX_CLK_TABLE_SIZE]; @@ -80,12 +93,31 @@ struct dml2_soc_derate_values_per_dpm { }; struct dml2_soc_derates_per_dpm { - struct dml2_soc_derate_values_per_dpm system_active_derates_per_dpm; + // Union allows both layouts to coexist without increasing struct size + // Anonymous structs allow direct member access without .v1 or .v2 prefix + union { + // Legacy layout - used by soc_and_ip_translator (unchanged access pattern) + // TODO: Remove after soc_and_ip_translator migration is complete + struct { + struct dml2_soc_derate_values_per_dpm system_active_derates_per_dpm; + unsigned int min_uclk_khz_threshold[DML_MAX_CLK_TABLE_SIZE]; + unsigned int min_fclk_khz_threshold[DML_MAX_CLK_TABLE_SIZE]; + unsigned int min_dcfclk_khz_threshold[DML_MAX_CLK_TABLE_SIZE]; + }; + + // New layout - used by DML internally + // Arrays of derate/threshold pairs, one per DPM level + struct { + struct dml2_soc_derate_values_per_dpm_v2 dram_per_dpm_derate_pixel[DML_MAX_CLK_TABLE_SIZE]; + struct dml2_soc_derate_values_per_dpm_v2 fclk_per_dpm_derate[DML_MAX_CLK_TABLE_SIZE]; + struct dml2_soc_derate_values_per_dpm_v2 dcfclk_per_dpm_derate[DML_MAX_CLK_TABLE_SIZE]; + }; + }; }; struct dml2_soc_qos_parameters { - struct dml2_soc_derates derate_table; - struct dml2_soc_derates_per_dpm derate_table_per_dpm; + struct dml2_soc_derates derate_table; // Single-value derates (source of truth for urgent, idle, mall_prefetch) + struct dml2_soc_derates_per_dpm derate_table_per_dpm; // Per-DPM derates for system_active_average only struct { unsigned int base_latency_us; unsigned int scaling_factor_us; diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c index d943cc8bf60e..475bdeb39d21 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c @@ -2739,16 +2739,15 @@ static double dml_get_return_bandwidth_available( derate_fabric_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_average.fclk_derate_percent / 100.0; derate_dram_factor = soc->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100.0; } else { // just assume sys_active - // use per dpm derates if the values are populated. Otherwise use global derates - derate_sdp_factor = soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dcfclk_derate_percent[uclk_dpm_level] != 0 ? - soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dcfclk_derate_percent[uclk_dpm_level] / 100.0 : - soc->qos_parameters.derate_table.system_active_average.dcfclk_derate_percent / 100.0; - derate_fabric_factor = soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.fclk_derate_percent[uclk_dpm_level] != 0 ? - soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.fclk_derate_percent[uclk_dpm_level] / 100.0 : - soc->qos_parameters.derate_table.system_active_average.fclk_derate_percent / 100.0; - derate_dram_factor = soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dram_derate_percent_pixel[uclk_dpm_level] != 0 ? - soc->qos_parameters.derate_table_per_dpm.system_active_derates_per_dpm.dram_derate_percent_pixel[uclk_dpm_level] / 100.0 : - soc->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100.0; + derate_sdp_factor = (soc->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[uclk_dpm_level].derate_percent != 0 ? + soc->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[uclk_dpm_level].derate_percent : + soc->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[0].derate_percent) / 100.0; + derate_fabric_factor = (soc->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[uclk_dpm_level].derate_percent != 0 ? + soc->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[uclk_dpm_level].derate_percent : + soc->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[0].derate_percent) / 100.0; + derate_dram_factor = (soc->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[uclk_dpm_level].derate_percent != 0 ? + soc->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[uclk_dpm_level].derate_percent : + soc->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[0].derate_percent) / 100.0; } } else { // urgent bw if (state_type == dml2_core_internal_soc_state_svp_prefetch) { diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c index 22c757cdac07..54a1f9c13dbf 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c @@ -6,6 +6,8 @@ #include "dml2_internal_shared_types.h" #include "dml_top_types.h" #include "lib_float_math.h" +#include "dml2_debug.h" + static double dram_bw_kbps_to_uclk_khz(unsigned long long bandwidth_kbps, const struct dml2_dram_params *dram_config, struct dml2_mcg_dram_bw_to_min_clk_table *dram_bw_table) { @@ -55,16 +57,101 @@ static unsigned long dml_round_up(double a) return (unsigned long)a; } +/* Calculate DPM index to use for per-DPM derates + * Iterates through DPM levels - if calculated clocks exceed thresholds increment to next DPM level + */ +static void calculate_derate_index(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out *in_out) +{ + const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result; + double required_bw_dram_kbps, required_bw_sdp_kbps; + int i; + + /* Default to DPM 0 (lowest power state) */ + in_out->derate_dpm_index = 0; + + /* Get required bandwidths from mode support */ + required_bw_dram_kbps = mode_support_result->global.active.average_bw_dram_kbps; + required_bw_sdp_kbps = mode_support_result->global.active.average_bw_sdp_kbps; + + /* Iterate through DPM levels from lowest to highest to find the first level + * whose available bandwidth can satisfy the requirements. + */ + for (i = 0; i < DML_MAX_CLK_TABLE_SIZE; i++) { + unsigned int dram_threshold = in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[i].clk_upperbound_threshold_khz; + unsigned int fclk_threshold = in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[i].clk_upperbound_threshold_khz; + unsigned int dcfclk_threshold = in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[i].clk_upperbound_threshold_khz; + unsigned int uclk_derate = in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[i].derate_percent; + unsigned int fclk_derate = in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[i].derate_percent; + unsigned int dcfclk_derate = in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[i].derate_percent; + double max_dram_bw_for_dpm = 0, max_fclk_bw_for_dpm = 0, max_dcfclk_bw_for_dpm = 0; + + /* Skip entries with 0 derate (use fallback logic) */ + if (uclk_derate == 0 || fclk_derate == 0 || dcfclk_derate == 0) { + DML_ASSERT(0); // derate should be populated (at least 1 entry in the per_dpm table that can be applied for all DPMs + } + + /* Threshold of 0 indicates last entry - this DPM level handles all higher bandwidths */ + if (dram_threshold == 0 && fclk_threshold == 0 && dcfclk_threshold == 0) { + in_out->derate_dpm_index = i; + break; + } + + /* Calculate maximum available bandwidth at this DPM level + * Available BW = max_clock_at_threshold * derate * conversion_factor */ + + /* For DRAM: convert threshold clock to bandwidth */ + if (!in_out->soc_bb->clk_table.dram_config.alt_clock_bw_conversion) { + unsigned long uclk_bytes_per_tick = in_out->soc_bb->clk_table.dram_config.channel_count + * in_out->soc_bb->clk_table.dram_config.channel_width_bytes + * in_out->soc_bb->clk_table.dram_config.transactions_per_clock; + max_dram_bw_for_dpm = (double)dram_threshold * uclk_bytes_per_tick * ((double)uclk_derate / 100.0); + } else { + /* use pre-computed table - find bandwidth at threshold clock */ + for (unsigned int j = 0; j < in_out->min_clk_table->dram_bw_table.num_entries; j++) { + if (in_out->min_clk_table->dram_bw_table.entries[j].min_uclk_khz >= dram_threshold) { + max_dram_bw_for_dpm = (double)in_out->min_clk_table->dram_bw_table.entries[j].pre_derate_dram_bw_kbps; + break; + } + } + } + + max_fclk_bw_for_dpm = (double)fclk_threshold + * in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes + * ((double)fclk_derate / 100.0); + + max_dcfclk_bw_for_dpm = (double)dcfclk_threshold + * in_out->soc_bb->return_bus_width_bytes + * ((double)dcfclk_derate / 100.0); + + /* Check if this DPM level's available bandwidth satisfies all requirements + * All bandwidth paths must be satisfied to use this DPM level */ + if (((dram_threshold == 0) || (required_bw_dram_kbps <= max_dram_bw_for_dpm)) && + ((fclk_threshold == 0) || (required_bw_sdp_kbps <= max_fclk_bw_for_dpm)) && + ((dcfclk_threshold == 0) || (required_bw_sdp_kbps <= max_dcfclk_bw_for_dpm))) { + in_out->derate_dpm_index = i; + break; + } + } +} + 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; + int dpm_index, uclk_avg_derate_percent, fclk_avg_derate_percent, dcfclk_avg_derate_percent; const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result; + dpm_index = in_out->derate_dpm_index; + + /* Get average derates from system_active_average per-DPM table */ + uclk_avg_derate_percent = (in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[dpm_index].derate_percent != 0 || dpm_index == 0) ? + in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[dpm_index].derate_percent : + in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[0].derate_percent; + 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)), + / ((double)uclk_avg_derate_percent / 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) @@ -78,16 +165,22 @@ static void calculate_system_active_minimums(struct dml2_dpmm_map_mode_to_soc_dp min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg; + fclk_avg_derate_percent = (in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[dpm_index].derate_percent != 0 || dpm_index == 0) ? + in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[dpm_index].derate_percent : + in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[0].derate_percent; 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_avg = (double)min_fclk_avg / ((double)fclk_avg_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; + dcfclk_avg_derate_percent = (in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[dpm_index].derate_percent != 0 || dpm_index == 0) ? + in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[dpm_index].derate_percent : + in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[0].derate_percent; 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_avg = (double)min_dcfclk_avg / ((double)dcfclk_avg_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); @@ -145,7 +238,7 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm /* assumes DF throttling is disabled */ min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.average_bw_dram_kbps - / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100)), + / ((double)in_out->soc_bb->qos_parameters.derate_table_per_dpm.dram_per_dpm_derate_pixel[in_out->derate_dpm_index].derate_percent / 100)), &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps @@ -155,7 +248,7 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg; min_fclk_avg = (double)mode_support_result->global.svp_prefetch.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_avg = (double)min_fclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table_per_dpm.fclk_per_dpm_derate[in_out->derate_dpm_index].derate_percent / 100); min_fclk_urgent = (double)mode_support_result->global.svp_prefetch.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); @@ -163,7 +256,7 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm min_fclk_bw = min_fclk_urgent > min_fclk_avg ? min_fclk_urgent : min_fclk_avg; min_dcfclk_avg = (double)mode_support_result->global.svp_prefetch.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_avg = (double)min_dcfclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table_per_dpm.dcfclk_per_dpm_derate[in_out->derate_dpm_index].derate_percent / 100); min_dcfclk_urgent = (double)mode_support_result->global.svp_prefetch.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); @@ -633,6 +726,7 @@ static bool map_mode_to_soc_dpm(struct dml2_dpmm_map_mode_to_soc_dpm_params_in_o double dispclk_khz; const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result; + calculate_derate_index(in_out); calculate_system_active_minimums(in_out); calculate_svp_prefetch_minimums(in_out); calculate_idle_minimums(in_out); diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h index a18f067fe53f..8ddf58da2eed 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h @@ -246,6 +246,7 @@ struct dml2_dpmm_map_mode_to_soc_dpm_params_in_out { * Output */ struct dml2_display_cfg_programming *programming; + int derate_dpm_index; }; struct dml2_dpmm_map_watermarks_params_in_out { -- 2.43.0
