]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amd/display: Guard against setting dispclk low for dcn31x
authorJing Zhou <Jing.Zhou@amd.com>
Tue, 4 Mar 2025 15:15:56 +0000 (23:15 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 18 Mar 2025 18:03:46 +0000 (14:03 -0400)
[WHY]
We should never apply a minimum dispclk value while in
prepare_bandwidth or while displays are active. This is
always an optimizaiton for when all displays are disabled.

[HOW]
Defer dispclk optimization until safe_to_lower = true
and display_count reaches 0.

Since 0 has a special value in this logic (ie. no dispclk
required) we also need adjust the logic that clamps it for
the actual request to PMFW.

Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Chris Park <chris.park@amd.com>
Reviewed-by: Eric Yang <eric.yang@amd.com>
Signed-off-by: Jing Zhou <Jing.Zhou@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Alex Hung <alex.hung@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/clk_mgr/dcn315/dcn315_clk_mgr.c
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c

index 19a15acd15095771ac0ad45a480621fdaa793ad0..e4d22f74f9869166b61af7f57af8400608425774 100644 (file)
@@ -130,7 +130,7 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base,
        struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
        struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
        struct dc *dc = clk_mgr_base->ctx->dc;
-       int display_count;
+       int display_count = 0;
        bool update_dppclk = false;
        bool update_dispclk = false;
        bool dpp_clock_lowered = false;
@@ -202,15 +202,19 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base,
                update_dppclk = true;
        }
 
-       if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
-               /* No need to apply the w/a if we haven't taken over from bios yet */
-               if (clk_mgr_base->clks.dispclk_khz)
-                       dcn315_disable_otg_wa(clk_mgr_base, context, true);
+       if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) &&
+           (new_clocks->dispclk_khz > 0 || (safe_to_lower && display_count == 0))) {
+               int requested_dispclk_khz = new_clocks->dispclk_khz;
 
+               dcn315_disable_otg_wa(clk_mgr_base, context, true);
+
+               /* Clamp the requested clock to PMFW based on their limit. */
+               if (dc->debug.min_disp_clk_khz > 0 && requested_dispclk_khz < dc->debug.min_disp_clk_khz)
+                       requested_dispclk_khz = dc->debug.min_disp_clk_khz;
+
+               dcn315_smu_set_dispclk(clk_mgr, requested_dispclk_khz);
                clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
-               dcn315_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
-               if (clk_mgr_base->clks.dispclk_khz)
-                       dcn315_disable_otg_wa(clk_mgr_base, context, false);
+               dcn315_disable_otg_wa(clk_mgr_base, context, false);
 
                update_dispclk = true;
        }
index 4b19d9cf27cee250894539628b35eb21b348454b..49efea0c8fcffa09b698e1bf28589e6c8de677c8 100644 (file)
@@ -140,7 +140,7 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base,
        struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
        struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk;
        struct dc *dc = clk_mgr_base->ctx->dc;
-       int display_count;
+       int display_count = 0;
        bool update_dppclk = false;
        bool update_dispclk = false;
        bool dpp_clock_lowered = false;
@@ -209,11 +209,18 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base,
                update_dppclk = true;
        }
 
-       if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
+       if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) &&
+           (new_clocks->dispclk_khz > 0 || (safe_to_lower && display_count == 0))) {
+               int requested_dispclk_khz = new_clocks->dispclk_khz;
+
                dcn316_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
 
+               /* Clamp the requested clock to PMFW based on their limit. */
+               if (dc->debug.min_disp_clk_khz > 0 && requested_dispclk_khz < dc->debug.min_disp_clk_khz)
+                       requested_dispclk_khz = dc->debug.min_disp_clk_khz;
+
+               dcn316_smu_set_dispclk(clk_mgr, requested_dispclk_khz);
                clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
-               dcn316_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
                dcn316_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false);
 
                update_dispclk = true;