Re: [Intel-gfx] [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be transmitted one frame earlier

2023-11-06 Thread Kahola, Mika
> -Original Message-
> From: Ville Syrjälä 
> Sent: Monday, November 6, 2023 10:54 AM
> To: Hogander, Jouni 
> Cc: Kahola, Mika ; intel-gfx@lists.freedesktop.org
> Subject: Re: [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be 
> transmitted one frame earlier
> 
> On Mon, Nov 06, 2023 at 08:40:52AM +, Hogander, Jouni wrote:
> > On Fri, 2023-11-03 at 11:32 +0200, Mika Kahola wrote:
> > > Display driver shall read DPCD 00071h[3:1] during configuration to
> > > get PSR setup time. This register provides the setup time
> > > requirement on the VSC SDP entry packet. If setup time cannot be met
> > > with the current timings (e.g., PSR setup time + other blanking
> > > requirements > blanking time), driver should enable sending VSC SDP
> > > one frame earlier before sending the capture frame.
> > >
> > > BSpec: 69895 (PSR Entry Setup Frames 17:16)
> > >
> > > v2: Write frames before su entry to correct register (Ville, Jouni)
> > >     Move frames before su entry calculation to it's
> > >     own function (Ville, Jouni)
> > >     Rename PSR Entry Setup Frames register to indicate
> > >     Lunarlake specificity (Jouni)
> > > v3: Modify setup entry frames calculation function to
> > >     return the actual frames (Ville)
> > >     Match comment with actual implementation (Jouni)
> > >
> > > Signed-off-by: Mika Kahola 
> > > ---
> > >  .../drm/i915/display/intel_display_types.h    |  1 +
> > >  drivers/gpu/drm/i915/display/intel_psr.c  | 82
> > > +++--
> > > --
> > >  drivers/gpu/drm/i915/display/intel_psr_regs.h |  2 +
> > >  3 files changed, 71 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > index 047fe3f8905a..92f06d67fd1e 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -1708,6 +1708,7 @@ struct intel_psr {
> > > u32 dc3co_exitline;
> > > u32 dc3co_exit_delay;
> > > struct delayed_work dc3co_work;
> > > +   u8 entry_setup_frames;
> > >  };
> > >
> > >  struct intel_dp {
> > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > > b/drivers/gpu/drm/i915/display/intel_psr.c
> > > index ecd24a0b86cb..497e4c26f4a6 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > > @@ -592,6 +592,9 @@ static void intel_psr_enable_sink(struct
> > > intel_dp
> > > *intel_dp)
> > > if (intel_dp->psr.req_psr2_sdp_prior_scanline)
> > > dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
> > >
> > > +   if (intel_dp->psr.entry_setup_frames > 0)
> > > +   dpcd_val |= DP_PSR_FRAME_CAPTURE;
> > > +
> > > drm_dp_dpcd_writeb(_dp->aux, DP_PSR_EN_CFG, dpcd_val);
> > >
> > > drm_dp_dpcd_writeb(_dp->aux, DP_SET_POWER,
> > > DP_SET_POWER_D0); @@ -690,6 +693,9 @@ static void
> > > hsw_activate_psr1(struct intel_dp
> > > *intel_dp)
> > > if (DISPLAY_VER(dev_priv) >= 8)
> > > val |= EDP_PSR_CRC_ENABLE;
> > >
> > > +   if (DISPLAY_VER(dev_priv) >= 20)
> > > +   val |= LNL_EDP_PSR_ENTRY_SETUP_FRAMES(intel_dp-
> > > >psr.entry_setup_frames);
> > > +
> > > intel_de_rmw(dev_priv, psr_ctl_reg(dev_priv,
> > > cpu_transcoder),
> > >  ~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
> > >  }
> > > @@ -727,11 +733,27 @@ static int psr2_block_count(struct intel_dp
> > > *intel_dp)
> > > return psr2_block_count_lines(intel_dp) / 4;
> > >  }
> > >
> > > +static u8 get_frames_before_su_entry(struct intel_dp *intel_dp) {
> > > +   u8 frames_before_su_entry;
> > > +
> > > +   frames_before_su_entry = max_t(u8,
> > > +  intel_dp-
> > > >psr.sink_sync_latency + 1,
> > > +  2);
> > > +
> > > +   /* Entry setup frames must be at least 1 less than frames
> > > before SU entry */
> > > +   if (intel_dp->psr.entry_setup_frames >=
> > > frames_before_su_entry)
> > > +   frames_before_su_entry = intel_dp-
> > > >psr.entry_setup_frames + 1;
> > > +
> > > +   return frames_before_su_entry; }
> > > +
> > >  static void hsw_activate_psr2(struct intel_dp *intel_dp)
> > >  {
> > > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > > enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
> > > u32 val = EDP_PSR2_ENABLE;
> > > +   u32 psr_val = 0;
> > >
> > > val |=
> > > EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
> > >
> > > @@ -741,7 +763,8 @@ static void hsw_activate_psr2(struct intel_dp
> > > *intel_dp)
> > > if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <=
> > > 12)
> > > val |= EDP_Y_COORDINATE_ENABLE;
> > >
> > > -   val |= EDP_PSR2_FRAME_BEFORE_SU(max_t(u8, intel_dp-
> > > >psr.sink_sync_latency + 

Re: [Intel-gfx] [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be transmitted one frame earlier

2023-11-06 Thread Kahola, Mika
> -Original Message-
> From: Hogander, Jouni 
> Sent: Monday, November 6, 2023 10:41 AM
> To: Kahola, Mika ; intel-gfx@lists.freedesktop.org
> Cc: ville.syrj...@linux.intel.com
> Subject: Re: [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be 
> transmitted one frame earlier
> 
> On Fri, 2023-11-03 at 11:32 +0200, Mika Kahola wrote:
> > Display driver shall read DPCD 00071h[3:1] during configuration to get
> > PSR setup time. This register provides the setup time requirement on
> > the VSC SDP entry packet. If setup time cannot be met with the current
> > timings (e.g., PSR setup time + other blanking requirements > blanking
> > time), driver should enable sending VSC SDP one frame earlier before
> > sending the capture frame.
> >
> > BSpec: 69895 (PSR Entry Setup Frames 17:16)
> >
> > v2: Write frames before su entry to correct register (Ville, Jouni)
> >     Move frames before su entry calculation to it's
> >     own function (Ville, Jouni)
> >     Rename PSR Entry Setup Frames register to indicate
> >     Lunarlake specificity (Jouni)
> > v3: Modify setup entry frames calculation function to
> >     return the actual frames (Ville)
> >     Match comment with actual implementation (Jouni)
> >
> > Signed-off-by: Mika Kahola 
> > ---
> >  .../drm/i915/display/intel_display_types.h    |  1 +
> >  drivers/gpu/drm/i915/display/intel_psr.c  | 82 +++--
> > --
> >  drivers/gpu/drm/i915/display/intel_psr_regs.h |  2 +
> >  3 files changed, 71 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 047fe3f8905a..92f06d67fd1e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1708,6 +1708,7 @@ struct intel_psr {
> > u32 dc3co_exitline;
> > u32 dc3co_exit_delay;
> > struct delayed_work dc3co_work;
> > +   u8 entry_setup_frames;
> >  };
> >
> >  struct intel_dp {
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > b/drivers/gpu/drm/i915/display/intel_psr.c
> > index ecd24a0b86cb..497e4c26f4a6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > @@ -592,6 +592,9 @@ static void intel_psr_enable_sink(struct intel_dp
> > *intel_dp)
> > if (intel_dp->psr.req_psr2_sdp_prior_scanline)
> > dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
> >
> > +   if (intel_dp->psr.entry_setup_frames > 0)
> > +   dpcd_val |= DP_PSR_FRAME_CAPTURE;
> > +
> > drm_dp_dpcd_writeb(_dp->aux, DP_PSR_EN_CFG, dpcd_val);
> >
> > drm_dp_dpcd_writeb(_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0); @@ -690,6 +693,9 @@ static void
> > hsw_activate_psr1(struct intel_dp
> > *intel_dp)
> > if (DISPLAY_VER(dev_priv) >= 8)
> > val |= EDP_PSR_CRC_ENABLE;
> >
> > +   if (DISPLAY_VER(dev_priv) >= 20)
> > +   val |= LNL_EDP_PSR_ENTRY_SETUP_FRAMES(intel_dp-
> > >psr.entry_setup_frames);
> > +
> > intel_de_rmw(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder),
> >  ~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
> >  }
> > @@ -727,11 +733,27 @@ static int psr2_block_count(struct intel_dp
> > *intel_dp)
> > return psr2_block_count_lines(intel_dp) / 4;
> >  }
> >
> > +static u8 get_frames_before_su_entry(struct intel_dp *intel_dp) {
> > +   u8 frames_before_su_entry;
> > +
> > +   frames_before_su_entry = max_t(u8,
> > +  intel_dp-
> > >psr.sink_sync_latency + 1,
> > +  2);
> > +
> > +   /* Entry setup frames must be at least 1 less than frames
> > before SU entry */
> > +   if (intel_dp->psr.entry_setup_frames >=
> > frames_before_su_entry)
> > +   frames_before_su_entry = intel_dp-
> > >psr.entry_setup_frames + 1;
> > +
> > +   return frames_before_su_entry; }
> > +
> >  static void hsw_activate_psr2(struct intel_dp *intel_dp)
> >  {
> > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
> > u32 val = EDP_PSR2_ENABLE;
> > +   u32 psr_val = 0;
> >
> > val |=
> > EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
> >
> > @@ -741,7 +763,8 @@ static void hsw_activate_psr2(struct intel_dp
> > *intel_dp)
> > if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <=
> > 12)
> > val |= EDP_Y_COORDINATE_ENABLE;
> >
> > -   val |= EDP_PSR2_FRAME_BEFORE_SU(max_t(u8, intel_dp-
> > >psr.sink_sync_latency + 1, 2));
> > +   val |=
> > EDP_PSR2_FRAME_BEFORE_SU(get_frames_before_su_entry(intel_dp));
> > +
> > val |= intel_psr2_get_tp_time(intel_dp);
> >
> > if (DISPLAY_VER(dev_priv) >= 12) { @@ -785,6 +808,9 @@ static
> > void hsw_activate_psr2(struct intel_dp
> > 

Re: [Intel-gfx] [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be transmitted one frame earlier

2023-11-06 Thread Ville Syrjälä
On Mon, Nov 06, 2023 at 08:40:52AM +, Hogander, Jouni wrote:
> On Fri, 2023-11-03 at 11:32 +0200, Mika Kahola wrote:
> > Display driver shall read DPCD 00071h[3:1] during configuration
> > to get PSR setup time. This register provides the setup time
> > requirement on the VSC SDP entry packet. If setup time cannot be
> > met with the current timings
> > (e.g., PSR setup time + other blanking requirements > blanking time),
> > driver should enable sending VSC SDP one frame earlier before sending
> > the capture frame.
> > 
> > BSpec: 69895 (PSR Entry Setup Frames 17:16)
> > 
> > v2: Write frames before su entry to correct register (Ville, Jouni)
> >     Move frames before su entry calculation to it's
> >     own function (Ville, Jouni)
> >     Rename PSR Entry Setup Frames register to indicate
> >     Lunarlake specificity (Jouni)
> > v3: Modify setup entry frames calculation function to
> >     return the actual frames (Ville)
> >     Match comment with actual implementation (Jouni)
> > 
> > Signed-off-by: Mika Kahola 
> > ---
> >  .../drm/i915/display/intel_display_types.h    |  1 +
> >  drivers/gpu/drm/i915/display/intel_psr.c  | 82 +++--
> > --
> >  drivers/gpu/drm/i915/display/intel_psr_regs.h |  2 +
> >  3 files changed, 71 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 047fe3f8905a..92f06d67fd1e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1708,6 +1708,7 @@ struct intel_psr {
> > u32 dc3co_exitline;
> > u32 dc3co_exit_delay;
> > struct delayed_work dc3co_work;
> > +   u8 entry_setup_frames;
> >  };
> >  
> >  struct intel_dp {
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > b/drivers/gpu/drm/i915/display/intel_psr.c
> > index ecd24a0b86cb..497e4c26f4a6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > @@ -592,6 +592,9 @@ static void intel_psr_enable_sink(struct intel_dp
> > *intel_dp)
> > if (intel_dp->psr.req_psr2_sdp_prior_scanline)
> > dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
> >  
> > +   if (intel_dp->psr.entry_setup_frames > 0)
> > +   dpcd_val |= DP_PSR_FRAME_CAPTURE;
> > +
> > drm_dp_dpcd_writeb(_dp->aux, DP_PSR_EN_CFG, dpcd_val);
> >  
> > drm_dp_dpcd_writeb(_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0);
> > @@ -690,6 +693,9 @@ static void hsw_activate_psr1(struct intel_dp
> > *intel_dp)
> > if (DISPLAY_VER(dev_priv) >= 8)
> > val |= EDP_PSR_CRC_ENABLE;
> >  
> > +   if (DISPLAY_VER(dev_priv) >= 20)
> > +   val |= LNL_EDP_PSR_ENTRY_SETUP_FRAMES(intel_dp-
> > >psr.entry_setup_frames);
> > +
> > intel_de_rmw(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder),
> >  ~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
> >  }
> > @@ -727,11 +733,27 @@ static int psr2_block_count(struct intel_dp
> > *intel_dp)
> > return psr2_block_count_lines(intel_dp) / 4;
> >  }
> >  
> > +static u8 get_frames_before_su_entry(struct intel_dp *intel_dp)
> > +{
> > +   u8 frames_before_su_entry;
> > +
> > +   frames_before_su_entry = max_t(u8,
> > +  intel_dp-
> > >psr.sink_sync_latency + 1,
> > +  2);
> > +
> > +   /* Entry setup frames must be at least 1 less than frames
> > before SU entry */
> > +   if (intel_dp->psr.entry_setup_frames >=
> > frames_before_su_entry)
> > +   frames_before_su_entry = intel_dp-
> > >psr.entry_setup_frames + 1;
> > +
> > +   return frames_before_su_entry;
> > +}
> > +
> >  static void hsw_activate_psr2(struct intel_dp *intel_dp)
> >  {
> > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
> > u32 val = EDP_PSR2_ENABLE;
> > +   u32 psr_val = 0;
> >  
> > val |=
> > EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
> >  
> > @@ -741,7 +763,8 @@ static void hsw_activate_psr2(struct intel_dp
> > *intel_dp)
> > if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <=
> > 12)
> > val |= EDP_Y_COORDINATE_ENABLE;
> >  
> > -   val |= EDP_PSR2_FRAME_BEFORE_SU(max_t(u8, intel_dp-
> > >psr.sink_sync_latency + 1, 2));
> > +   val |=
> > EDP_PSR2_FRAME_BEFORE_SU(get_frames_before_su_entry(intel_dp));
> > +
> > val |= intel_psr2_get_tp_time(intel_dp);
> >  
> > if (DISPLAY_VER(dev_priv) >= 12) {
> > @@ -785,6 +808,9 @@ static void hsw_activate_psr2(struct intel_dp
> > *intel_dp)
> > if (intel_dp->psr.req_psr2_sdp_prior_scanline)
> > val |= EDP_PSR2_SU_SDP_SCANLINE;
> >  
> > +   if (DISPLAY_VER(dev_priv) >= 20)
> > +   psr_val |= 

Re: [Intel-gfx] [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be transmitted one frame earlier

2023-11-06 Thread Kahola, Mika


> -Original Message-
> From: Hogander, Jouni 
> Sent: Monday, November 6, 2023 10:41 AM
> To: Kahola, Mika ; intel-gfx@lists.freedesktop.org
> Cc: ville.syrj...@linux.intel.com
> Subject: Re: [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be 
> transmitted one frame earlier
> 
> On Fri, 2023-11-03 at 11:32 +0200, Mika Kahola wrote:
> > Display driver shall read DPCD 00071h[3:1] during configuration to get
> > PSR setup time. This register provides the setup time requirement on
> > the VSC SDP entry packet. If setup time cannot be met with the current
> > timings (e.g., PSR setup time + other blanking requirements > blanking
> > time), driver should enable sending VSC SDP one frame earlier before
> > sending the capture frame.
> >
> > BSpec: 69895 (PSR Entry Setup Frames 17:16)
> >
> > v2: Write frames before su entry to correct register (Ville, Jouni)
> >     Move frames before su entry calculation to it's
> >     own function (Ville, Jouni)
> >     Rename PSR Entry Setup Frames register to indicate
> >     Lunarlake specificity (Jouni)
> > v3: Modify setup entry frames calculation function to
> >     return the actual frames (Ville)
> >     Match comment with actual implementation (Jouni)
> >
> > Signed-off-by: Mika Kahola 
> > ---
> >  .../drm/i915/display/intel_display_types.h    |  1 +
> >  drivers/gpu/drm/i915/display/intel_psr.c  | 82 +++--
> > --
> >  drivers/gpu/drm/i915/display/intel_psr_regs.h |  2 +
> >  3 files changed, 71 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 047fe3f8905a..92f06d67fd1e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1708,6 +1708,7 @@ struct intel_psr {
> > u32 dc3co_exitline;
> > u32 dc3co_exit_delay;
> > struct delayed_work dc3co_work;
> > +   u8 entry_setup_frames;
> >  };
> >
> >  struct intel_dp {
> > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> > b/drivers/gpu/drm/i915/display/intel_psr.c
> > index ecd24a0b86cb..497e4c26f4a6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> > @@ -592,6 +592,9 @@ static void intel_psr_enable_sink(struct intel_dp
> > *intel_dp)
> > if (intel_dp->psr.req_psr2_sdp_prior_scanline)
> > dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
> >
> > +   if (intel_dp->psr.entry_setup_frames > 0)
> > +   dpcd_val |= DP_PSR_FRAME_CAPTURE;
> > +
> > drm_dp_dpcd_writeb(_dp->aux, DP_PSR_EN_CFG, dpcd_val);
> >
> > drm_dp_dpcd_writeb(_dp->aux, DP_SET_POWER,
> > DP_SET_POWER_D0); @@ -690,6 +693,9 @@ static void
> > hsw_activate_psr1(struct intel_dp
> > *intel_dp)
> > if (DISPLAY_VER(dev_priv) >= 8)
> > val |= EDP_PSR_CRC_ENABLE;
> >
> > +   if (DISPLAY_VER(dev_priv) >= 20)
> > +   val |= LNL_EDP_PSR_ENTRY_SETUP_FRAMES(intel_dp-
> > >psr.entry_setup_frames);
> > +
> > intel_de_rmw(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder),
> >  ~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
> >  }
> > @@ -727,11 +733,27 @@ static int psr2_block_count(struct intel_dp
> > *intel_dp)
> > return psr2_block_count_lines(intel_dp) / 4;
> >  }
> >
> > +static u8 get_frames_before_su_entry(struct intel_dp *intel_dp) {
> > +   u8 frames_before_su_entry;
> > +
> > +   frames_before_su_entry = max_t(u8,
> > +  intel_dp-
> > >psr.sink_sync_latency + 1,
> > +  2);
> > +
> > +   /* Entry setup frames must be at least 1 less than frames
> > before SU entry */
> > +   if (intel_dp->psr.entry_setup_frames >=
> > frames_before_su_entry)
> > +   frames_before_su_entry = intel_dp-
> > >psr.entry_setup_frames + 1;
> > +
> > +   return frames_before_su_entry; }
> > +
> >  static void hsw_activate_psr2(struct intel_dp *intel_dp)
> >  {
> > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
> > u32 val = EDP_PSR2_ENABLE;
> > +   u32 psr_val = 0;
> >
> > val |=
> > EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
> >
> > @@ -741,7 +763,8 @@ static void hsw_activate_psr2(struct intel_dp
> > *intel_dp)
> > if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <=
> > 12)
> > val |= EDP_Y_COORDINATE_ENABLE;
> >
> > -   val |= EDP_PSR2_FRAME_BEFORE_SU(max_t(u8, intel_dp-
> > >psr.sink_sync_latency + 1, 2));
> > +   val |=
> > EDP_PSR2_FRAME_BEFORE_SU(get_frames_before_su_entry(intel_dp));
> > +
> > val |= intel_psr2_get_tp_time(intel_dp);
> >
> > if (DISPLAY_VER(dev_priv) >= 12) { @@ -785,6 +808,9 @@ static
> > void hsw_activate_psr2(struct intel_dp
> > 

Re: [Intel-gfx] [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be transmitted one frame earlier

2023-11-06 Thread Hogander, Jouni
On Fri, 2023-11-03 at 11:32 +0200, Mika Kahola wrote:
> Display driver shall read DPCD 00071h[3:1] during configuration
> to get PSR setup time. This register provides the setup time
> requirement on the VSC SDP entry packet. If setup time cannot be
> met with the current timings
> (e.g., PSR setup time + other blanking requirements > blanking time),
> driver should enable sending VSC SDP one frame earlier before sending
> the capture frame.
> 
> BSpec: 69895 (PSR Entry Setup Frames 17:16)
> 
> v2: Write frames before su entry to correct register (Ville, Jouni)
>     Move frames before su entry calculation to it's
>     own function (Ville, Jouni)
>     Rename PSR Entry Setup Frames register to indicate
>     Lunarlake specificity (Jouni)
> v3: Modify setup entry frames calculation function to
>     return the actual frames (Ville)
>     Match comment with actual implementation (Jouni)
> 
> Signed-off-by: Mika Kahola 
> ---
>  .../drm/i915/display/intel_display_types.h    |  1 +
>  drivers/gpu/drm/i915/display/intel_psr.c  | 82 +++--
> --
>  drivers/gpu/drm/i915/display/intel_psr_regs.h |  2 +
>  3 files changed, 71 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 047fe3f8905a..92f06d67fd1e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1708,6 +1708,7 @@ struct intel_psr {
> u32 dc3co_exitline;
> u32 dc3co_exit_delay;
> struct delayed_work dc3co_work;
> +   u8 entry_setup_frames;
>  };
>  
>  struct intel_dp {
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index ecd24a0b86cb..497e4c26f4a6 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -592,6 +592,9 @@ static void intel_psr_enable_sink(struct intel_dp
> *intel_dp)
> if (intel_dp->psr.req_psr2_sdp_prior_scanline)
> dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
>  
> +   if (intel_dp->psr.entry_setup_frames > 0)
> +   dpcd_val |= DP_PSR_FRAME_CAPTURE;
> +
> drm_dp_dpcd_writeb(_dp->aux, DP_PSR_EN_CFG, dpcd_val);
>  
> drm_dp_dpcd_writeb(_dp->aux, DP_SET_POWER,
> DP_SET_POWER_D0);
> @@ -690,6 +693,9 @@ static void hsw_activate_psr1(struct intel_dp
> *intel_dp)
> if (DISPLAY_VER(dev_priv) >= 8)
> val |= EDP_PSR_CRC_ENABLE;
>  
> +   if (DISPLAY_VER(dev_priv) >= 20)
> +   val |= LNL_EDP_PSR_ENTRY_SETUP_FRAMES(intel_dp-
> >psr.entry_setup_frames);
> +
> intel_de_rmw(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder),
>  ~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
>  }
> @@ -727,11 +733,27 @@ static int psr2_block_count(struct intel_dp
> *intel_dp)
> return psr2_block_count_lines(intel_dp) / 4;
>  }
>  
> +static u8 get_frames_before_su_entry(struct intel_dp *intel_dp)
> +{
> +   u8 frames_before_su_entry;
> +
> +   frames_before_su_entry = max_t(u8,
> +  intel_dp-
> >psr.sink_sync_latency + 1,
> +  2);
> +
> +   /* Entry setup frames must be at least 1 less than frames
> before SU entry */
> +   if (intel_dp->psr.entry_setup_frames >=
> frames_before_su_entry)
> +   frames_before_su_entry = intel_dp-
> >psr.entry_setup_frames + 1;
> +
> +   return frames_before_su_entry;
> +}
> +
>  static void hsw_activate_psr2(struct intel_dp *intel_dp)
>  {
> struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
> u32 val = EDP_PSR2_ENABLE;
> +   u32 psr_val = 0;
>  
> val |=
> EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
>  
> @@ -741,7 +763,8 @@ static void hsw_activate_psr2(struct intel_dp
> *intel_dp)
> if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <=
> 12)
> val |= EDP_Y_COORDINATE_ENABLE;
>  
> -   val |= EDP_PSR2_FRAME_BEFORE_SU(max_t(u8, intel_dp-
> >psr.sink_sync_latency + 1, 2));
> +   val |=
> EDP_PSR2_FRAME_BEFORE_SU(get_frames_before_su_entry(intel_dp));
> +
> val |= intel_psr2_get_tp_time(intel_dp);
>  
> if (DISPLAY_VER(dev_priv) >= 12) {
> @@ -785,6 +808,9 @@ static void hsw_activate_psr2(struct intel_dp
> *intel_dp)
> if (intel_dp->psr.req_psr2_sdp_prior_scanline)
> val |= EDP_PSR2_SU_SDP_SCANLINE;
>  
> +   if (DISPLAY_VER(dev_priv) >= 20)
> +   psr_val |= LNL_EDP_PSR_ENTRY_SETUP_FRAMES(intel_dp-
> >psr.entry_setup_frames);
> +
> if (intel_dp->psr.psr2_sel_fetch_enabled) {
> u32 tmp;
>  
> @@ -798,7 +824,7 @@ static void hsw_activate_psr2(struct intel_dp
> *intel_dp)
>  * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec
> is
> 

[Intel-gfx] [PATCH v3] drm/i915/display: Support PSR entry VSC packet to be transmitted one frame earlier

2023-11-03 Thread Mika Kahola
Display driver shall read DPCD 00071h[3:1] during configuration
to get PSR setup time. This register provides the setup time
requirement on the VSC SDP entry packet. If setup time cannot be
met with the current timings
(e.g., PSR setup time + other blanking requirements > blanking time),
driver should enable sending VSC SDP one frame earlier before sending
the capture frame.

BSpec: 69895 (PSR Entry Setup Frames 17:16)

v2: Write frames before su entry to correct register (Ville, Jouni)
Move frames before su entry calculation to it's
own function (Ville, Jouni)
Rename PSR Entry Setup Frames register to indicate
Lunarlake specificity (Jouni)
v3: Modify setup entry frames calculation function to
return the actual frames (Ville)
Match comment with actual implementation (Jouni)

Signed-off-by: Mika Kahola 
---
 .../drm/i915/display/intel_display_types.h|  1 +
 drivers/gpu/drm/i915/display/intel_psr.c  | 82 +++
 drivers/gpu/drm/i915/display/intel_psr_regs.h |  2 +
 3 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 047fe3f8905a..92f06d67fd1e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1708,6 +1708,7 @@ struct intel_psr {
u32 dc3co_exitline;
u32 dc3co_exit_delay;
struct delayed_work dc3co_work;
+   u8 entry_setup_frames;
 };
 
 struct intel_dp {
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c 
b/drivers/gpu/drm/i915/display/intel_psr.c
index ecd24a0b86cb..497e4c26f4a6 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -592,6 +592,9 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
if (intel_dp->psr.req_psr2_sdp_prior_scanline)
dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
 
+   if (intel_dp->psr.entry_setup_frames > 0)
+   dpcd_val |= DP_PSR_FRAME_CAPTURE;
+
drm_dp_dpcd_writeb(_dp->aux, DP_PSR_EN_CFG, dpcd_val);
 
drm_dp_dpcd_writeb(_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
@@ -690,6 +693,9 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
if (DISPLAY_VER(dev_priv) >= 8)
val |= EDP_PSR_CRC_ENABLE;
 
+   if (DISPLAY_VER(dev_priv) >= 20)
+   val |= 
LNL_EDP_PSR_ENTRY_SETUP_FRAMES(intel_dp->psr.entry_setup_frames);
+
intel_de_rmw(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder),
 ~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val);
 }
@@ -727,11 +733,27 @@ static int psr2_block_count(struct intel_dp *intel_dp)
return psr2_block_count_lines(intel_dp) / 4;
 }
 
+static u8 get_frames_before_su_entry(struct intel_dp *intel_dp)
+{
+   u8 frames_before_su_entry;
+
+   frames_before_su_entry = max_t(u8,
+  intel_dp->psr.sink_sync_latency + 1,
+  2);
+
+   /* Entry setup frames must be at least 1 less than frames before SU 
entry */
+   if (intel_dp->psr.entry_setup_frames >= frames_before_su_entry)
+   frames_before_su_entry = intel_dp->psr.entry_setup_frames + 1;
+
+   return frames_before_su_entry;
+}
+
 static void hsw_activate_psr2(struct intel_dp *intel_dp)
 {
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
u32 val = EDP_PSR2_ENABLE;
+   u32 psr_val = 0;
 
val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp));
 
@@ -741,7 +763,8 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <= 12)
val |= EDP_Y_COORDINATE_ENABLE;
 
-   val |= EDP_PSR2_FRAME_BEFORE_SU(max_t(u8, 
intel_dp->psr.sink_sync_latency + 1, 2));
+   val |= EDP_PSR2_FRAME_BEFORE_SU(get_frames_before_su_entry(intel_dp));
+
val |= intel_psr2_get_tp_time(intel_dp);
 
if (DISPLAY_VER(dev_priv) >= 12) {
@@ -785,6 +808,9 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
if (intel_dp->psr.req_psr2_sdp_prior_scanline)
val |= EDP_PSR2_SU_SDP_SCANLINE;
 
+   if (DISPLAY_VER(dev_priv) >= 20)
+   psr_val |= 
LNL_EDP_PSR_ENTRY_SETUP_FRAMES(intel_dp->psr.entry_setup_frames);
+
if (intel_dp->psr.psr2_sel_fetch_enabled) {
u32 tmp;
 
@@ -798,7 +824,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
 * recommending keep this bit unset while PSR2 is enabled.
 */
-   intel_de_write(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder), 0);
+   intel_de_write(dev_priv, psr_ctl_reg(dev_priv, cpu_transcoder), 
psr_val);
 
intel_de_write(dev_priv, EDP_PSR2_CTL(cpu_transcoder), val);
 }
@@