mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-23 18:56:40 -04:00
drm/amd/display: Allow Per-DPM De-rates Instead Of A Single Global Value
[Why] Currently only a singular de-rate is used for all DPM levels. The intent was to limit the bandwidth utilization at high DPMs so the display requirements are not competing with other engines for bandwidth. At lower DPMs, the de-rates could be more lenient so more bandwidth can be utilized without the need to increase the DPM level and result in potential power savings. i.e. DPM0 could be achieved on certain display configs instead of DPM1 if de-rates were a couple percentage points higher The system average de-rates can be adjusted as needed as only urgent de-rates are defined for the SOC. [How] Update QOS parameters to have a table of derates with a per-DPM granularity If the per-DPM value is provided, that will value be used. Otherwise use the global value if there is no DPM specific value. Reviewed-by: Jun Lei <jun.lei@amd.com> Signed-off-by: Austin Zheng <Austin.Zheng@amd.com> Signed-off-by: George Zhang <george.zhang@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
687bd7c811
commit
8af429f6ef
@@ -71,8 +71,21 @@ enum dml2_qos_param_type {
|
||||
dml2_qos_param_type_dcn4x
|
||||
};
|
||||
|
||||
//Indicies mapped to DPM level
|
||||
// Unpopulated indicies should fallback to the global derate value.
|
||||
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];
|
||||
unsigned int dcfclk_derate_percent[DML_MAX_CLK_TABLE_SIZE];
|
||||
};
|
||||
|
||||
struct dml2_soc_derates_per_dpm {
|
||||
struct dml2_soc_derate_values_per_dpm system_active_derates_per_dpm;
|
||||
};
|
||||
|
||||
struct dml2_soc_qos_parameters {
|
||||
struct dml2_soc_derates derate_table;
|
||||
struct dml2_soc_derates_per_dpm derate_table_per_dpm;
|
||||
struct {
|
||||
unsigned int base_latency_us;
|
||||
unsigned int scaling_factor_us;
|
||||
|
||||
@@ -2701,7 +2701,8 @@ static double dml_get_return_bandwidth_available(
|
||||
bool is_hvm_only,
|
||||
double dcfclk_mhz,
|
||||
double fclk_mhz,
|
||||
double dram_bw_mbps)
|
||||
double dram_bw_mbps,
|
||||
unsigned int uclk_dpm_level)
|
||||
{
|
||||
double return_bw_mbps = 0.;
|
||||
double ideal_sdp_bandwidth = (double)soc->return_bus_width_bytes * dcfclk_mhz;
|
||||
@@ -2722,9 +2723,16 @@ 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
|
||||
derate_sdp_factor = soc->qos_parameters.derate_table.system_active_average.dcfclk_derate_percent / 100.0;
|
||||
derate_fabric_factor = soc->qos_parameters.derate_table.system_active_average.fclk_derate_percent / 100.0;
|
||||
derate_dram_factor = soc->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100.0;
|
||||
// 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;
|
||||
}
|
||||
} else { // urgent bw
|
||||
if (state_type == dml2_core_internal_soc_state_svp_prefetch) {
|
||||
@@ -2778,6 +2786,7 @@ static double dml_get_return_bandwidth_available(
|
||||
DML_LOG_VERBOSE("DML::%s: derate_fabric_bandwidth = %f (derate %f)\n", __func__, derate_fabric_bandwidth, derate_fabric_factor);
|
||||
DML_LOG_VERBOSE("DML::%s: derate_dram_bandwidth = %f (derate %f)\n", __func__, derate_dram_bandwidth, derate_dram_factor);
|
||||
DML_LOG_VERBOSE("DML::%s: return_bw_mbps = %f\n", __func__, return_bw_mbps);
|
||||
DML_LOG_VERBOSE("DML::%s: uclk_dpm_level = %u\n", __func__, uclk_dpm_level);
|
||||
return return_bw_mbps;
|
||||
}
|
||||
|
||||
@@ -2793,7 +2802,8 @@ static noinline_for_stack void calculate_bandwidth_available(
|
||||
bool HostVMEnable,
|
||||
double dcfclk_mhz,
|
||||
double fclk_mhz,
|
||||
double dram_bw_mbps)
|
||||
double dram_bw_mbps,
|
||||
unsigned int uclk_dpm_level)
|
||||
{
|
||||
unsigned int n, m;
|
||||
|
||||
@@ -2812,9 +2822,10 @@ static noinline_for_stack void calculate_bandwidth_available(
|
||||
0, // hvm_only
|
||||
dcfclk_mhz,
|
||||
fclk_mhz,
|
||||
dram_bw_mbps);
|
||||
dram_bw_mbps,
|
||||
uclk_dpm_level);
|
||||
|
||||
urg_bandwidth_available[m][n] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 0, dcfclk_mhz, fclk_mhz, dram_bw_mbps);
|
||||
urg_bandwidth_available[m][n] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 0, dcfclk_mhz, fclk_mhz, dram_bw_mbps, uclk_dpm_level);
|
||||
|
||||
|
||||
#ifdef __DML_VBA_DEBUG__
|
||||
@@ -2824,8 +2835,8 @@ static noinline_for_stack void calculate_bandwidth_available(
|
||||
|
||||
// urg_bandwidth_available_vm_only is indexed by soc_state
|
||||
if (n == dml2_core_internal_bw_dram) {
|
||||
urg_bandwidth_available_vm_only[m] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 1, dcfclk_mhz, fclk_mhz, dram_bw_mbps);
|
||||
urg_bandwidth_available_pixel_and_vm[m] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 0, dcfclk_mhz, fclk_mhz, dram_bw_mbps);
|
||||
urg_bandwidth_available_vm_only[m] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 1, dcfclk_mhz, fclk_mhz, dram_bw_mbps, uclk_dpm_level);
|
||||
urg_bandwidth_available_pixel_and_vm[m] = dml_get_return_bandwidth_available(soc, m, n, 0, HostVMEnable, 0, dcfclk_mhz, fclk_mhz, dram_bw_mbps, uclk_dpm_level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9483,7 +9494,8 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
|
||||
display_cfg->hostvm_enable,
|
||||
mode_lib->ms.DCFCLK,
|
||||
mode_lib->ms.FabricClock,
|
||||
mode_lib->ms.dram_bw_mbps);
|
||||
mode_lib->ms.dram_bw_mbps,
|
||||
mode_lib->ms.active_min_uclk_dpm_index);
|
||||
|
||||
calculate_bandwidth_available(
|
||||
mode_lib->ms.support.avg_bandwidth_available_min,
|
||||
@@ -9498,10 +9510,12 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out
|
||||
mode_lib->ms.MaxDCFCLK,
|
||||
mode_lib->ms.MaxFabricClock,
|
||||
#ifdef DML_MODE_SUPPORT_USE_DPM_DRAM_BW
|
||||
mode_lib->ms.dram_bw_mbps);
|
||||
mode_lib->ms.dram_bw_mbps,
|
||||
#else
|
||||
mode_lib->ms.max_dram_bw_mbps);
|
||||
mode_lib->ms.max_dram_bw_mbps,
|
||||
#endif
|
||||
mode_lib->ms.active_min_uclk_dpm_index);
|
||||
|
||||
|
||||
// Average BW support check
|
||||
calculate_avg_bandwidth_required(
|
||||
@@ -10958,7 +10972,8 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex
|
||||
display_cfg->hostvm_enable,
|
||||
mode_lib->mp.Dcfclk,
|
||||
mode_lib->mp.FabricClock,
|
||||
mode_lib->mp.dram_bw_mbps);
|
||||
mode_lib->mp.dram_bw_mbps,
|
||||
mode_lib->mp.active_min_uclk_dpm_index);
|
||||
|
||||
|
||||
calculate_hostvm_inefficiency_factor(
|
||||
|
||||
Reference in New Issue
Block a user