drm/amd/display: For prefetch mode > 0, extend prefetch if possible
authorjsg <jsg@openbsd.org>
Tue, 6 Feb 2024 03:21:45 +0000 (03:21 +0000)
committerjsg <jsg@openbsd.org>
Tue, 6 Feb 2024 03:21:45 +0000 (03:21 +0000)
From Alvin Lee
6750d1de747f4d2db0046a25b069e15341f6a9ba in linux-6.6.y/6.6.16
dd4e4bb28843393065eed279e869fac248d03f0f in mainline linux

sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c
sys/dev/pci/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h

index cbdfb76..6c84b0f 100644 (file)
@@ -813,6 +813,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
                                        (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ||
                                                v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ?
                                                        mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
+                                       mode_lib->vba.PrefetchModePerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false,
+
                                        /* Output */
                                        &v->DSTXAfterScaler[k],
                                        &v->DSTYAfterScaler[k],
@@ -3317,6 +3319,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
                                                        v->SwathHeightCThisState[k], v->TWait,
                                                        (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ?
                                                                        mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
+                                                       mode_lib->vba.PrefetchModePerState[i][j] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false,
 
                                                        /* Output */
                                                        &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.DSTXAfterScaler[k],
index ecea008..208b89d 100644 (file)
@@ -3423,6 +3423,7 @@ bool dml32_CalculatePrefetchSchedule(
                unsigned int SwathHeightC,
                double TWait,
                double TPreReq,
+               bool ExtendPrefetchIfPossible,
                /* Output */
                double   *DSTXAfterScaler,
                double   *DSTYAfterScaler,
@@ -3892,12 +3893,32 @@ bool dml32_CalculatePrefetchSchedule(
                        /* Clamp to oto for bandwidth calculation */
                        LinesForPrefetchBandwidth = dst_y_prefetch_oto;
                } else {
-                       *DestinationLinesForPrefetch = dst_y_prefetch_equ;
-                       TimeForFetchingMetaPTE = Tvm_equ;
-                       TimeForFetchingRowInVBlank = Tr0_equ;
-                       *PrefetchBandwidth = prefetch_bw_equ;
-                       /* Clamp to equ for bandwidth calculation */
-                       LinesForPrefetchBandwidth = dst_y_prefetch_equ;
+                       /* For mode programming we want to extend the prefetch as much as possible
+                        * (up to oto, or as long as we can for equ) if we're not already applying
+                        * the 60us prefetch requirement. This is to avoid intermittent underflow
+                        * issues during prefetch.
+                        *
+                        * The prefetch extension is applied under the following scenarios:
+                        * 1. We're in prefetch mode > 0 (i.e. we don't support MCLK switch in blank)
+                        * 2. We're using subvp or drr methods of p-state switch, in which case we
+                        *    we don't care if prefetch takes up more of the blanking time
+                        *
+                        * Mode programming typically chooses the smallest prefetch time possible
+                        * (i.e. highest bandwidth during prefetch) presumably to create margin between
+                        * p-states / c-states that happen in vblank and prefetch. Therefore we only
+                        * apply this prefetch extension when p-state in vblank is not required (UCLK
+                        * p-states take up the most vblank time).
+                        */
+                       if (ExtendPrefetchIfPossible && TPreReq == 0 && VStartup < MaxVStartup) {
+                               MyError = true;
+                       } else {
+                               *DestinationLinesForPrefetch = dst_y_prefetch_equ;
+                               TimeForFetchingMetaPTE = Tvm_equ;
+                               TimeForFetchingRowInVBlank = Tr0_equ;
+                               *PrefetchBandwidth = prefetch_bw_equ;
+                               /* Clamp to equ for bandwidth calculation */
+                               LinesForPrefetchBandwidth = dst_y_prefetch_equ;
+                       }
                }
 
                *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0;
index 592d174..5d34735 100644 (file)
@@ -747,6 +747,7 @@ bool dml32_CalculatePrefetchSchedule(
                unsigned int SwathHeightC,
                double TWait,
                double TPreReq,
+               bool ExtendPrefetchIfPossible,
                /* Output */
                double   *DSTXAfterScaler,
                double   *DSTYAfterScaler,