On Thu, Sep 11, 2025 at 08:15:50AM +0530, Ankit Nautiyal wrote:
> When VRR TG is always enabled and an optimized guardband is used, the pipe
> vblank start is derived from the guardband.
> Currently TRANS_SET_CONTEXT_LATENCY is programmed with crtc_vblank_start -
> crtc_vdisplay, which is ~1 when guardband matches the vblank length.
> With shorter guardband this become a large window.
> 
> To avoid misprogramming TRANS_SET_CONTEXT_LATENCY, clamp the scl value to 1
> when using optimized guardband.
> 
> Also update the VRR get config logic to set crtc_vblank_start based on
> vtotal - guardband, during readback.
> 
> Signed-off-by: Ankit Nautiyal <ankit.k.nauti...@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 36 ++++++++++++++++----
>  drivers/gpu/drm/i915/display/intel_vrr.c     |  9 ++++-
>  2 files changed, 38 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 55bea1374dc4..73aec6d4686a 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -2638,6 +2638,30 @@ transcoder_has_vrr(const struct intel_crtc_state 
> *crtc_state)
>       return HAS_VRR(display) && !transcoder_is_dsi(cpu_transcoder);
>  }
>  
> +static int intel_set_context_latency(const struct intel_crtc_state 
> *crtc_state,
> +                                  int crtc_vblank_start,
> +                                  int crtc_vdisplay)
> +{
> +     struct intel_display *display = to_intel_display(crtc_state);
> +
> +     /*
> +      * When VRR TG is always on and optimized guardband is used,
> +      * the pipe vblank start is based on the guardband,
> +      * TRANS_SET_CONTEXT_LATENCY cannot be used to configure it.
> +      */
> +     if (intel_vrr_always_use_vrr_tg(display))
> +             return clamp(crtc_vblank_start - crtc_vdisplay, 0, 1);

What are you trying to achieve with this? As in what problem are you
seeing with the current SCL programming?

> +
> +     /*
> +      * VBLANK_START no longer works on ADL+, instead we must use
> +      * TRANS_SET_CONTEXT_LATENCY to configure the pipe vblank start.
> +      */
> +     if (DISPLAY_VER(display) >= 13)
> +             return crtc_vblank_start - crtc_vdisplay;
> +
> +     return 0;
> +}
> +
>  static void intel_set_transcoder_timings(const struct intel_crtc_state 
> *crtc_state)
>  {
>       struct intel_display *display = to_intel_display(crtc_state);
> @@ -2671,14 +2695,12 @@ static void intel_set_transcoder_timings(const struct 
> intel_crtc_state *crtc_sta
>                       vsyncshift += adjusted_mode->crtc_htotal;
>       }
>  
> -     /*
> -      * VBLANK_START no longer works on ADL+, instead we must use
> -      * TRANS_SET_CONTEXT_LATENCY to configure the pipe vblank start.
> -      */
>       if (DISPLAY_VER(display) >= 13) {
>               intel_de_write(display,
>                              TRANS_SET_CONTEXT_LATENCY(display, 
> cpu_transcoder),
> -                            crtc_vblank_start - crtc_vdisplay);
> +                            intel_set_context_latency(crtc_state,
> +                                                      crtc_vblank_start,
> +                                                      crtc_vdisplay));
>  
>               /*
>                * VBLANK_START not used by hw, just clear it
> @@ -2768,7 +2790,9 @@ static void intel_set_transcoder_timings_lrr(const 
> struct intel_crtc_state *crtc
>       if (DISPLAY_VER(display) >= 13) {
>               intel_de_write(display,
>                              TRANS_SET_CONTEXT_LATENCY(display, 
> cpu_transcoder),
> -                            crtc_vblank_start - crtc_vdisplay);
> +                            intel_set_context_latency(crtc_state,
> +                                                      crtc_vblank_start,
> +                                                      crtc_vdisplay));
>  
>               /*
>                * VBLANK_START not used by hw, just clear it
> diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
> b/drivers/gpu/drm/i915/display/intel_vrr.c
> index 855974174afd..e124ef4e0ff4 100644
> --- a/drivers/gpu/drm/i915/display/intel_vrr.c
> +++ b/drivers/gpu/drm/i915/display/intel_vrr.c
> @@ -749,11 +749,18 @@ void intel_vrr_get_config(struct intel_crtc_state 
> *crtc_state)
>                * bits are not filled. Since vrr.vsync_start is computed as:
>                * crtc_vtotal - crtc_vsync_start, we can derive vtotal from
>                * vrr.vsync_start and crtc_vsync_start.
> +              *
> +              * With Optimized guardband, the vblank start is Vtotal - 
> guardband
>                */
> -             if (intel_vrr_always_use_vrr_tg(display))
> +             if (intel_vrr_always_use_vrr_tg(display)) {
>                       crtc_state->hw.adjusted_mode.crtc_vtotal =
>                               crtc_state->hw.adjusted_mode.crtc_vsync_start +
>                               crtc_state->vrr.vsync_start;
> +
> +                     crtc_state->hw.adjusted_mode.crtc_vblank_start =
> +                             crtc_state->hw.adjusted_mode.crtc_vtotal -
> +                             crtc_state->vrr.guardband;
> +             }
>       }
>  
>       vrr_enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE;
> -- 
> 2.45.2

-- 
Ville Syrjälä
Intel

Reply via email to