The maximum guardband value is constrained by two factors:
- The actual vblank length minus set context latency (SCL)
- The hardware register field width:
  - 8 bits for ICL/TGL (VRR_CTL_PIPELINE_FULL_MASK -> max 255)
  - 16 bits for ADL+ (XELPD_VRR_CTL_VRR_GUARDBAND_MASK -> max 65535)

Remove the #FIXME and clamp the guardband to the maximum allowed value.

Signed-off-by: Ankit Nautiyal <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_vrr.c | 36 ++++++++++++++++++++----
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 5fa86356a791..9bed273f96df 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -409,6 +409,34 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
        }
 }
 
+static int intel_vrr_max_hw_guardband(const struct intel_crtc_state 
*crtc_state)
+{
+#define VRR_GUARDBAND_MAX 65535   /* based on XELPD_VRR_CTL_VRR_GUARDBAND_MASK 
*/
+#define VRR_PIPELINE_FULL_MAX 255 /* based on VRR_CTL_PIPELINE_FULL_MASK */
+       struct intel_display *display = to_intel_display(crtc_state);
+
+       if (!HAS_VRR(display))
+               return 0;
+
+       if (DISPLAY_VER(display) >= 13)
+               return VRR_GUARDBAND_MAX;
+
+       return intel_vrr_pipeline_full_to_guardband(crtc_state, 
VRR_PIPELINE_FULL_MAX);
+}
+
+static int clamp_guardband(struct intel_crtc_state *crtc_state, int guardband)
+{
+       const struct drm_display_mode *adjusted_mode = 
&crtc_state->hw.adjusted_mode;
+       int vblank_length = adjusted_mode->crtc_vtotal - 
adjusted_mode->crtc_vdisplay;
+       int set_context_latency = crtc_state->set_context_latency;
+       int max_hw_guardband = intel_vrr_max_hw_guardband(crtc_state);
+       int max_guardband;
+
+       max_guardband = min(max_hw_guardband, vblank_length - 
set_context_latency);
+
+       return min(guardband, max_guardband);
+}
+
 void intel_vrr_compute_config_late(struct intel_crtc_state *crtc_state)
 {
        struct intel_display *display = to_intel_display(crtc_state);
@@ -421,16 +449,12 @@ void intel_vrr_compute_config_late(struct 
intel_crtc_state *crtc_state)
                crtc_state->vrr.vmin - adjusted_mode->crtc_vblank_start -
                intel_vrr_extra_vblank_delay(display);
 
-       if (DISPLAY_VER(display) < 13) {
-               /* FIXME handle the limit in a proper way */
-               crtc_state->vrr.guardband =
-                       min(crtc_state->vrr.guardband,
-                           intel_vrr_pipeline_full_to_guardband(crtc_state, 
255));
+       crtc_state->vrr.guardband = clamp_guardband(crtc_state, 
crtc_state->vrr.guardband);
 
+       if (DISPLAY_VER(display) < 13)
                crtc_state->vrr.pipeline_full =
                        intel_vrr_guardband_to_pipeline_full(crtc_state,
                                                             
crtc_state->vrr.guardband);
-       }
 }
 
 static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state)
-- 
2.45.2

Reply via email to