drm/amd/display: Ensure populate uclk in bb construction
authorAlvin Lee <alvin.lee2@amd.com>
Thu, 4 Jan 2024 18:40:04 +0000 (13:40 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 15 Jan 2024 23:35:39 +0000 (18:35 -0500)
[Description]
- For some SKUs, the optimal DCFCLK for each UCLK is less than the
  smallest DCFCLK STA target due to low memory bandwidth. There is
  an assumption that the DCFCLK STA targets will always be less
  than one of the optimal DCFCLK values, but this is not true for
  SKUs that have low memory bandwidth. In this case we need to
  populate the optimal UCLK for each DCFCLK STA targets as the max
  UCLK freq.
- Also fix a bug in DML where start_state is not assigned and used
  correctly.

Reviewed-by: Samson Tam <samson.tam@amd.com>
Reviewed-by: Chaitanya Dhere <chaitanya.dhere@amd.com>
Acked-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c

index 63c48c29ba4910beec4d9e6492b0894f9867d8bb..e7f4a2d491ccf42343afa24ba422e8cb84f57126 100644 (file)
@@ -4273,7 +4273,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 
        //Calculate Swath, DET Configuration, DCFCLKDeepSleep
        //
-       for (i = 0; i < mode_lib->soc.num_states; ++i) {
+       for (i = start_state; i < mode_lib->soc.num_states; ++i) {
                for (j = 0; j <= 1; ++j) {
                        for (k = 0; k < v->NumberOfActivePlanes; ++k) {
                                v->RequiredDPPCLKThisState[k] = v->RequiredDPPCLK[i][j][k];
@@ -4576,7 +4576,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 
        //Calculate Return BW
 
-       for (i = 0; i < mode_lib->soc.num_states; ++i) {
+       for (i = start_state; i < mode_lib->soc.num_states; ++i) {
                for (j = 0; j <= 1; ++j) {
                        for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
                                if (v->BlendingAndTiming[k] == k) {
@@ -4635,7 +4635,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
                                        v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
        v->FinalDRAMClockChangeLatency = (v->DRAMClockChangeLatencyOverride > 0 ? v->DRAMClockChangeLatencyOverride : v->DRAMClockChangeLatency);
 
-       for (i = 0; i < mode_lib->soc.num_states; ++i) {
+       for (i = start_state; i < mode_lib->soc.num_states; ++i) {
                for (j = 0; j <= 1; ++j) {
                        v->DCFCLKState[i][j] = v->DCFCLKPerState[i];
                }
@@ -4646,7 +4646,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 
                if (v->ClampMinDCFCLK) {
                        /* Clamp calculated values to actual minimum */
-                       for (i = 0; i < mode_lib->soc.num_states; ++i) {
+                       for (i = start_state; i < mode_lib->soc.num_states; ++i) {
                                for (j = 0; j <= 1; ++j) {
                                        if (v->DCFCLKState[i][j] < mode_lib->soc.min_dcfclk) {
                                                v->DCFCLKState[i][j] = mode_lib->soc.min_dcfclk;
@@ -4656,7 +4656,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
                }
        }
 
-       for (i = 0; i < mode_lib->soc.num_states; ++i) {
+       for (i = start_state; i < mode_lib->soc.num_states; ++i) {
                for (j = 0; j <= 1; ++j) {
                        v->IdealSDPPortBandwidthPerState[i][j] = dml_min3(
                                        v->ReturnBusWidth * v->DCFCLKState[i][j],
@@ -4674,7 +4674,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 
        //Re-ordering Buffer Support Check
 
-       for (i = 0; i < mode_lib->soc.num_states; ++i) {
+       for (i = start_state; i < mode_lib->soc.num_states; ++i) {
                for (j = 0; j <= 1; ++j) {
                        if ((v->ROBBufferSizeInKByte - v->PixelChunkSizeInKByte) * 1024 / v->ReturnBWPerState[i][j]
                                        > (v->RoundTripPingLatencyCycles + 32) / v->DCFCLKState[i][j] + ReorderingBytes / v->ReturnBWPerState[i][j]) {
@@ -4692,7 +4692,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
                MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
        }
 
-       for (i = 0; i < mode_lib->soc.num_states; ++i) {
+       for (i = start_state; i < mode_lib->soc.num_states; ++i) {
                for (j = 0; j <= 1; ++j) {
                        v->MaxTotalVerticalActiveAvailableBandwidth[i][j] = dml_min(
                                        v->IdealSDPPortBandwidthPerState[i][j] * v->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation / 100,
@@ -4708,7 +4708,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 
        //Prefetch Check
 
-       for (i = 0; i < mode_lib->soc.num_states; ++i) {
+       for (i = start_state; i < mode_lib->soc.num_states; ++i) {
                for (j = 0; j <= 1; ++j) {
                        int NextPrefetchModeState = MinPrefetchMode;
 
index 3eb3a021ab7d72f672b0029d333e32f4f58af559..3f02bb806d421a224401aa2bde415e564f453e8b 100644 (file)
@@ -266,6 +266,17 @@ void dcn303_fpu_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_p
                                        optimal_uclk_for_dcfclk_sta_targets[i] =
                                                        bw_params->clk_table.entries[j].memclk_mhz * 16;
                                        break;
+                               } else {
+                                       /* condition where (dcfclk_sta_targets[i] >= optimal_dcfclk_for_uclk[j]):
+                                        * This is required for dcn303 because it just so happens that the memory
+                                        * bandwidth is low enough such that all the optimal DCFCLK for each UCLK
+                                        * is lower than the smallest DCFCLK STA target. In this case we need to
+                                        * populate the optimal UCLK for each DCFCLK STA target to be the max UCLK.
+                                        */
+                                       if (j == num_uclk_states - 1) {
+                                               optimal_uclk_for_dcfclk_sta_targets[i] =
+                                                               bw_params->clk_table.entries[j].memclk_mhz * 16;
+                                       }
                                }
                        }
                }
index 37a64186f3241a456c4eeea6038cc311fca0de43..ecc477ef8e3b78e1705b8546ac17e1d8490982f7 100644 (file)
@@ -2169,6 +2169,17 @@ void dcn30_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_params
                                        optimal_uclk_for_dcfclk_sta_targets[i] =
                                                        bw_params->clk_table.entries[j].memclk_mhz * 16;
                                        break;
+                               } else {
+                                       /* condition where (dcfclk_sta_targets[i] >= optimal_dcfclk_for_uclk[j]):
+                                        * If it just so happens that the memory bandwidth is low enough such that
+                                        * all the optimal DCFCLK for each UCLK is lower than the smallest DCFCLK STA
+                                        * target, we need to populate the optimal UCLK for each DCFCLK STA target to
+                                        * be the max UCLK.
+                                        */
+                                       if (j == num_uclk_states - 1) {
+                                               optimal_uclk_for_dcfclk_sta_targets[i] =
+                                                               bw_params->clk_table.entries[j].memclk_mhz * 16;
+                                       }
                                }
                        }
                }