From: Wesley Chalmers <wesley.chalm...@amd.com>

[WHY]
It is possible to commit state multiple times in rapid succession with
FAMS enabled; if each of these commits were to set optimized_required,
then the user may see latency.

[HOW]
fw_based_mclk_switching is currently not used in dc->clk_mgr; use it
to track whether the current state has FAMS enabled;
if it has, then do not disable FAMS in prepare_bandwidth, and do not set
optimized_required.

Reviewed-by: Rodrigo Siqueira <rodrigo.sique...@amd.com>
Signed-off-by: Wesley Chalmers <wesley.chalm...@amd.com>
---
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |  3 +++
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    | 22 ++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 6ce10fd4bb1a..422fbf79da64 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -2117,6 +2117,9 @@ void dcn20_optimize_bandwidth(
                dc_dmub_srv_p_state_delegate(dc,
                        true, context);
                context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
+               dc->clk_mgr->clks.fw_based_mclk_switching = true;
+       } else {
+               dc->clk_mgr->clks.fw_based_mclk_switching = false;
        }
 
        dc->clk_mgr->funcs->update_clocks(
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 0411867654dd..8263a07f265f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -983,9 +983,13 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,
 }
 
 void dcn30_prepare_bandwidth(struct dc *dc,
-       struct dc_state *context)
+       struct dc_state *context)
 {
-       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
+       bool p_state_change_support = 
context->bw_ctx.bw.dcn.clk.p_state_change_support;
+       /* Any transition into an FPO config should disable MCLK switching 
first to avoid
+        * driver and FW P-State synchronization issues.
+        */
+       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || 
dc->clk_mgr->clks.fw_based_mclk_switching) {
                dc->optimized_required = true;
                context->bw_ctx.bw.dcn.clk.p_state_change_support = false;
        }
@@ -996,7 +1000,19 @@ void dcn30_prepare_bandwidth(struct dc *dc,
                        dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, 
dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries
 - 1].memclk_mhz);
 
        dcn20_prepare_bandwidth(dc, context);
+       /*
+        * enabled -> enabled: do not disable
+        * enabled -> disabled: disable
+        * disabled -> enabled: don't care
+        * disabled -> disabled: don't care
+        */
+       if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching)
+               dc_dmub_srv_p_state_delegate(dc, false, context);
 
-       dc_dmub_srv_p_state_delegate(dc, false, context);
+       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || 
dc->clk_mgr->clks.fw_based_mclk_switching) {
+               /* After disabling P-State, restore the original value to 
ensure we get the correct P-State
+                * on the next optimize. */
+               context->bw_ctx.bw.dcn.clk.p_state_change_support = 
p_state_change_support;
+       }
 }
 
-- 
2.34.1

Reply via email to