From: Austin Zheng <[email protected]>

[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 <[email protected]>
Signed-off-by: Austin Zheng <[email protected]>
Signed-off-by: George Zhang <[email protected]>
---
 .../dml21/inc/dml_top_soc_parameter_types.h   | 13 ++++++
 .../src/dml2_core/dml2_core_dcn4_calcs.c      | 41 +++++++++++++------
 2 files changed, 41 insertions(+), 13 deletions(-)

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 6152155d6073..672b96a3da74 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
@@ -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;
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 f338e733318e..51a66e1be7a1 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
@@ -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(
--
2.54.0

Reply via email to