]> www.infradead.org Git - users/hch/misc.git/commitdiff
drm/amd/display: Increase minimum clock for TMDS 420 with pipe splitting
authorRelja Vojvodic <rvojvodi@amd.com>
Thu, 14 Aug 2025 15:33:22 +0000 (11:33 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 29 Aug 2025 14:13:51 +0000 (10:13 -0400)
[Why]
-Pipe splitting allows for clocks to be reduced, but when using TMDS 420,
reduced clocks lead to missed clocks cycles on clock resyncing

[How]
-Impose a minimum clock when using TMDS 420

Reviewed-by: Chris Park <chris.park@amd.com>
Signed-off-by: Relja Vojvodic <rvojvodi@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c

index b9cff2198511091c084efeeb6bcfba1ac88b0e93..bf62d42b3f78b2eef51f550ca26e39019783df3d 100644 (file)
@@ -1238,18 +1238,27 @@ static void CalculateDETBufferSize(
 
 static double CalculateRequiredDispclk(
        enum dml2_odm_mode ODMMode,
-       double PixelClock)
+       double PixelClock,
+       bool isTMDS420)
 {
+       double DispClk;
 
        if (ODMMode == dml2_odm_mode_combine_4to1) {
-               return PixelClock / 4.0;
+               DispClk = PixelClock / 4.0;
        } else if (ODMMode == dml2_odm_mode_combine_3to1) {
-               return PixelClock / 3.0;
+               DispClk = PixelClock / 3.0;
        } else if (ODMMode == dml2_odm_mode_combine_2to1) {
-               return PixelClock / 2.0;
+               DispClk = PixelClock / 2.0;
        } else {
-               return PixelClock;
+               DispClk = PixelClock;
+       }
+
+       if (isTMDS420) {
+               double TMDS420MinPixClock = PixelClock / 2.0;
+               DispClk = math_max2(DispClk, TMDS420MinPixClock);
        }
+
+       return DispClk;
 }
 
 static double TruncToValidBPP(
@@ -4122,11 +4131,12 @@ static noinline_for_stack void CalculateODMMode(
        bool success;
        bool UseDSC = DSCEnable && (NumberOfDSCSlices > 0);
        enum dml2_odm_mode DecidedODMMode;
+       bool isTMDS420 = (OutFormat == dml2_420 && Output == dml2_hdmi);
 
-       SurfaceRequiredDISPCLKWithoutODMCombine = CalculateRequiredDispclk(dml2_odm_mode_bypass, PixelClock);
-       SurfaceRequiredDISPCLKWithODMCombineTwoToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_2to1, PixelClock);
-       SurfaceRequiredDISPCLKWithODMCombineThreeToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_3to1, PixelClock);
-       SurfaceRequiredDISPCLKWithODMCombineFourToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_4to1, PixelClock);
+       SurfaceRequiredDISPCLKWithoutODMCombine = CalculateRequiredDispclk(dml2_odm_mode_bypass, PixelClock, isTMDS420);
+       SurfaceRequiredDISPCLKWithODMCombineTwoToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_2to1, PixelClock, isTMDS420);
+       SurfaceRequiredDISPCLKWithODMCombineThreeToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_3to1, PixelClock, isTMDS420);
+       SurfaceRequiredDISPCLKWithODMCombineFourToOne = CalculateRequiredDispclk(dml2_odm_mode_combine_4to1, PixelClock, isTMDS420);
 #ifdef __DML_VBA_DEBUG__
        DML_LOG_VERBOSE("DML::%s: ODMUse = %d\n", __func__, ODMUse);
        DML_LOG_VERBOSE("DML::%s: Output = %d\n", __func__, Output);