On Tue, 2025-10-14 at 09:46 +0530, Ankit Nautiyal wrote:
> Panel Replay and PSR2 selective update require sufficient vblank
> duration
> to accommodate wake latencies. However, the current
> wake_lines_fit_into_vblank() logic does not account for the minimum
> Set Context Latency (SCL) lines.
> 
> Separate out _intel_psr_min_set_context_latency() to compute the
> minimum
> SCL requirement based on platform and feature usage.
> 
> The alpm_config_valid() helper is updated to pass the necessary
> context for
> determining whether Panel Replay or PSR2 selective update is enabled.
> 
> v2: While calling alpm_config_valid() for selective_update use false
> flag
>     instead of has_panel_replay. (Jouni)
> 
> Signed-off-by: Ankit Nautiyal <[email protected]>
> Cc: Animesh Manna <[email protected]>
> Cc: Jouni Högander <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 102 ++++++++++++++-------
> --
>  1 file changed, 61 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 2131473cead6..28efa4410c2a 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -1361,14 +1361,64 @@ static int
> intel_psr_entry_setup_frames(struct intel_dp *intel_dp,
>       return entry_setup_frames;
>  }
>  
> +static
> +int _intel_psr_min_set_context_latency(const struct intel_crtc_state
> *crtc_state,
> +                                    bool needs_panel_replay,
> +                                    bool needs_sel_update)
> +{
> +     struct intel_display *display =
> to_intel_display(crtc_state);
> +
> +     if (!crtc_state->has_psr)
> +             return 0;
> +
> +     /* Wa_14015401596 */
> +     if (intel_vrr_possible(crtc_state) &&
> IS_DISPLAY_VER(display, 13, 14))
> +             return 1;
> +
> +     /* Rest is for SRD_STATUS needed on LunarLake and onwards */
> +     if (DISPLAY_VER(display) < 20)
> +             return 0;
> +
> +     /*
> +      * Comment on SRD_STATUS register in Bspec for LunarLake and
> onwards:
> +      *
> +      * To deterministically capture the transition of the state
> machine
> +      * going from SRDOFFACK to IDLE, the delayed V. Blank should
> be at least
> +      * one line after the non-delayed V. Blank.
> +      *
> +      * Legacy TG: TRANS_SET_CONTEXT_LATENCY > 0
> +      * VRR TG: TRANS_VRR_CTL[ VRR Guardband ] < (TRANS_VRR_VMAX[
> VRR Vmax ]
> +      * - TRANS_VTOTAL[ Vertical Active ])
> +      *
> +      * SRD_STATUS is used only by PSR1 on PantherLake.
> +      * SRD_STATUS is used by PSR1 and Panel Replay DP on
> LunarLake.
> +      */
> +
> +     if (DISPLAY_VER(display) >= 30 && (needs_panel_replay ||
> +                                        needs_sel_update))
> +             return 0;
> +     else if (DISPLAY_VER(display) < 30 && (needs_sel_update ||
> +                                           
> intel_crtc_has_type(crtc_state,
> +                                                               
> INTEL_OUTPUT_EDP)))
> +             return 0;
> +     else
> +             return 1;
> +}
> +
>  static bool wake_lines_fit_into_vblank(struct intel_dp *intel_dp,
>                                      const struct intel_crtc_state
> *crtc_state,
> -                                    bool aux_less)
> +                                    bool aux_less,
> +                                    bool needs_sel_update,
> +                                    bool needs_panel_replay)
>  {
>       struct intel_display *display = to_intel_display(intel_dp);
>       int vblank = crtc_state->hw.adjusted_mode.crtc_vblank_end -
>               crtc_state->hw.adjusted_mode.crtc_vblank_start;
>       int wake_lines;
> +     int scl = _intel_psr_min_set_context_latency(crtc_state,
> +                                                 
> needs_sel_update,
> +                                                 
> needs_panel_replay);
> +     vblank -= scl;
>  
>       if (aux_less)
>               wake_lines = crtc_state-
> >alpm_state.aux_less_wake_lines;
> @@ -1390,7 +1440,9 @@ static bool wake_lines_fit_into_vblank(struct
> intel_dp *intel_dp,
>  
>  static bool alpm_config_valid(struct intel_dp *intel_dp,
>                             struct intel_crtc_state *crtc_state,
> -                           bool aux_less)
> +                           bool aux_less,
> +                           bool needs_sel_update,
> +                           bool needs_panel_replay)

Please keep order of parameters same in alpm_config_valid and
intel_psr_min_set_context_latency. With that fixed:

Reviewed-by: Jouni Högander <[email protected]>

>  {
>       struct intel_display *display = to_intel_display(intel_dp);
>  
> @@ -1400,7 +1452,8 @@ static bool alpm_config_valid(struct intel_dp
> *intel_dp,
>               return false;
>       }
>  
> -     if (!wake_lines_fit_into_vblank(intel_dp, crtc_state,
> aux_less)) {
> +     if (!wake_lines_fit_into_vblank(intel_dp, crtc_state,
> aux_less,
> +                                     needs_sel_update,
> needs_panel_replay)) {
>               drm_dbg_kms(display->drm,
>                           "PSR2/Panel Replay not enabled, too
> short vblank time\n");
>               return false;
> @@ -1492,7 +1545,7 @@ static bool intel_psr2_config_valid(struct
> intel_dp *intel_dp,
>               return false;
>       }
>  
> -     if (!alpm_config_valid(intel_dp, crtc_state, false))
> +     if (!alpm_config_valid(intel_dp, crtc_state, false, true,
> false))
>               return false;
>  
>       if (!crtc_state->enable_psr2_sel_fetch &&
> @@ -1643,7 +1696,7 @@ _panel_replay_compute_config(struct intel_dp
> *intel_dp,
>               return false;
>       }
>  
> -     if (!alpm_config_valid(intel_dp, crtc_state, true))
> +     if (!alpm_config_valid(intel_dp, crtc_state, true, false,
> true))
>               return false;
>  
>       return true;
> @@ -2371,43 +2424,10 @@ void
> intel_psr_trigger_frame_change_event(struct intel_dsb *dsb,
>   */
>  int intel_psr_min_set_context_latency(const struct intel_crtc_state
> *crtc_state)
>  {
> -     struct intel_display *display =
> to_intel_display(crtc_state);
> -
> -     if (!crtc_state->has_psr)
> -             return 0;
> -
> -     /* Wa_14015401596 */
> -     if (intel_vrr_possible(crtc_state) &&
> IS_DISPLAY_VER(display, 13, 14))
> -             return 1;
> -
> -     /* Rest is for SRD_STATUS needed on LunarLake and onwards */
> -     if (DISPLAY_VER(display) < 20)
> -             return 0;
>  
> -     /*
> -      * Comment on SRD_STATUS register in Bspec for LunarLake and
> onwards:
> -      *
> -      * To deterministically capture the transition of the state
> machine
> -      * going from SRDOFFACK to IDLE, the delayed V. Blank should
> be at least
> -      * one line after the non-delayed V. Blank.
> -      *
> -      * Legacy TG: TRANS_SET_CONTEXT_LATENCY > 0
> -      * VRR TG: TRANS_VRR_CTL[ VRR Guardband ] < (TRANS_VRR_VMAX[
> VRR Vmax ]
> -      * - TRANS_VTOTAL[ Vertical Active ])
> -      *
> -      * SRD_STATUS is used only by PSR1 on PantherLake.
> -      * SRD_STATUS is used by PSR1 and Panel Replay DP on
> LunarLake.
> -      */
> -
> -     if (DISPLAY_VER(display) >= 30 && (crtc_state-
> >has_panel_replay ||
> -                                        crtc_state-
> >has_sel_update))
> -             return 0;
> -     else if (DISPLAY_VER(display) < 30 && (crtc_state-
> >has_sel_update ||
> -                                           
> intel_crtc_has_type(crtc_state,
> -                                                               
> INTEL_OUTPUT_EDP)))
> -             return 0;
> -     else
> -             return 1;
> +     return _intel_psr_min_set_context_latency(crtc_state,
> +                                               crtc_state-
> >has_panel_replay,
> +                                               crtc_state-
> >has_sel_update);
>  }
>  
>  static u32 man_trk_ctl_enable_bit_get(struct intel_display *display)

Reply via email to