From: Aric Cyr <[email protected]>

[Why]
dc_stream_adjust_vmin_vmax() programmed the OTG on every call. FreeSync
BTR calls it once per vblank, so identical v_total values were rewritten
every frame, each one paying dc_exit_ips_for_hw_access() and, when FAMS
is enabled, a blocking DMUB round trip from setup_manual_trigger().

[How]
Return early when timing_adjust_pending is clear and every v_total field
already matches the request, so hardware is only touched when the values
change. stream->adjust is still updated on every path that continues, so
a later commit programs the requested values.

timing_adjust_pending is the existing "stream->adjust has not reached
hardware" marker, so keep it accurate wherever hardware is left
untouched: set_drr_and_clear_adjust_pending() now sets it when called
with null params, which resets DRR in the OTG during pipe back-end
teardown, and the max_v_total overflow path only clears it when
set_long_vtotal() runs.

Reviewed-by: Josip Pavic <[email protected]>
Signed-off-by: Aric Cyr <[email protected]>
Signed-off-by: Roman Li <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c      | 24 +++++++++++++++----
 .../drm/amd/display/dc/core/dc_hw_sequencer.c |  3 ++-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 17db12fe8022..254c2a9c1b04 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1342,6 +1342,7 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
                struct dc_crtc_timing_adjust *adjust)
 {
        int i;
+       bool drr_unchanged;
 
        /*
         * Don't adjust DRR while there's bandwidth optimizations pending to
@@ -1356,6 +1357,19 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
                }
        }
 
+       /* timing_adjust_pending tracks whether stream->adjust still describes 
the
+        * OTG, so a cleared flag plus matching values means hw is already 
current.
+        */
+       drr_unchanged = !stream->adjust.timing_adjust_pending &&
+                       stream->adjust.v_total_min == adjust->v_total_min &&
+                       stream->adjust.v_total_max == adjust->v_total_max &&
+                       stream->adjust.v_total_mid == adjust->v_total_mid &&
+                       stream->adjust.v_total_mid_frame_num == 
adjust->v_total_mid_frame_num &&
+                       stream->adjust.allow_otg_v_count_halt == 
adjust->allow_otg_v_count_halt;
+
+       if (drr_unchanged)
+               return true;
+
        dc_exit_ips_for_hw_access(dc);
 
        stream->adjust.v_total_max = adjust->v_total_max;
@@ -1366,11 +1380,13 @@ bool dc_stream_adjust_vmin_vmax(struct dc *dc,
 
        if (dc->caps.max_v_total != 0 &&
                (adjust->v_total_max > dc->caps.max_v_total || 
adjust->v_total_min > dc->caps.max_v_total)) {
-               stream->adjust.timing_adjust_pending = false;
-               if (adjust->allow_otg_v_count_halt)
+               if (adjust->allow_otg_v_count_halt) {
+                       stream->adjust.timing_adjust_pending = false;
                        return set_long_vtotal(dc, stream, adjust);
-               else
-                       return false;
+               }
+               /* Nothing reached hw, so stream->adjust no longer describes 
the OTG. */
+               stream->adjust.timing_adjust_pending = true;
+               return false;
        }
 
        for (i = 0; i < MAX_PIPES; i++) {
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index 21a62ca4c8dc..3d88c5c377fc 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -716,7 +716,8 @@ void set_drr_and_clear_adjust_pending(
                                pipe_ctx->stream_res.tg, params);
 
        if (stream)
-               stream->adjust.timing_adjust_pending = false;
+               /* A null params resets DRR in hw, leaving stream->adjust 
stale. */
+               stream->adjust.timing_adjust_pending = (params == NULL);
 }
 
 void get_fams2_visual_confirm_color(
-- 
2.34.1

Reply via email to