Message ID | 20230728124609.2911830-5-animesh.manna@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Panel replay phase1 implementation | expand |
Hi Animesh, kernel test robot noticed the following build warnings: [auto build test WARNING on drm-tip/drm-tip] url: https://github.com/intel-lab-lkp/linux/commits/Animesh-Manna/drm-panelreplay-dpcd-register-definition-for-panelreplay/20230728-205902 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/r/20230728124609.2911830-5-animesh.manna%40intel.com patch subject: [Intel-gfx] [PATCH v3 4/6] drm/i915/panelreplay: Initializaton and compute config for panel replay config: x86_64-randconfig-x001-20230728 (https://download.01.org/0day-ci/archive/20230728/202307282318.EVEl6EsL-lkp@intel.com/config) compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) reproduce: (https://download.01.org/0day-ci/archive/20230728/202307282318.EVEl6EsL-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202307282318.EVEl6EsL-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/gpu/drm/i915/display/intel_dp.c:3386:27: warning: overlapping comparisons always evaluate to true [-Wtautological-overlap-compare] if (vsc->revision != 0x5 || vsc->revision != 0x7) ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. vim +3386 drivers/gpu/drm/i915/display/intel_dp.c 3361 3362 static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, 3363 struct dp_sdp *sdp, size_t size) 3364 { 3365 size_t length = sizeof(struct dp_sdp); 3366 3367 if (size < length) 3368 return -ENOSPC; 3369 3370 memset(sdp, 0, size); 3371 3372 /* 3373 * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119 3374 * VSC SDP Header Bytes 3375 */ 3376 sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */ 3377 sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */ 3378 sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */ 3379 sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */ 3380 3381 /* 3382 * Other than revision 0x5 which supports Pixel Encoding/Colorimetry 3383 * Format as per DP 1.4a spec, revision 0x7 also supports Pixel 3384 * Encoding/Colorimetry Format as per DP 2.0 spec. 3385 */ > 3386 if (vsc->revision != 0x5 || vsc->revision != 0x7) 3387 goto out; 3388 3389 /* VSC SDP Payload for DB16 through DB18 */ 3390 /* Pixel Encoding and Colorimetry Formats */ 3391 sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */ 3392 sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */ 3393 3394 switch (vsc->bpc) { 3395 case 6: 3396 /* 6bpc: 0x0 */ 3397 break; 3398 case 8: 3399 sdp->db[17] = 0x1; /* DB17[3:0] */ 3400 break; 3401 case 10: 3402 sdp->db[17] = 0x2; 3403 break; 3404 case 12: 3405 sdp->db[17] = 0x3; 3406 break; 3407 case 16: 3408 sdp->db[17] = 0x4; 3409 break; 3410 default: 3411 MISSING_CASE(vsc->bpc); 3412 break; 3413 } 3414 /* Dynamic Range and Component Bit Depth */ 3415 if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA) 3416 sdp->db[17] |= 0x80; /* DB17[7] */ 3417 3418 /* Content Type */ 3419 sdp->db[18] = vsc->content_type & 0x7; 3420 3421 out: 3422 return length; 3423 } 3424
On Fri, 2023-07-28 at 18:16 +0530, Animesh Manna wrote: > Modify existing PSR implementation to enable panel replay feature of > DP 2.0 > which is similar to PSR feature of EDP panel. There is different DPCD > address to check panel capability compare to PSR and vsc sdp header > is different. > > v1: Initial version. > v2: > - Set source_panel_replay_support flag under HAS_PNEL_REPLAY() check. > [Jouni] > - Code restructured around intel_panel_replay_init > and renamed to intel_panel_replay_init_dpcd. [Jouni] > - Remove the initial code modification around has_psr2 flag. [Jouni] > - Add CAN_PANEL_REPLAY() in intel_encoder_can_psr which is used to > enable in intel_psr_post_plane_update. [Jouni] > v3: > - Initialize both psr and panel-replay. [Jouni] > - Initialize both panel replay and psr if detected. [Jouni] > - Refactoring psr function by introducing _psr_compute_config(). > [Jouni] > - Add check for !is_edp while deriving source_panel_replay_support. > [Jouni] > - Enable panel replay dpcd initialization in a separate patch. > [Jouni] > > Cc: Jouni Högander <jouni.hogander@intel.com> > Signed-off-by: Animesh Manna <animesh.manna@intel.com> > --- > .../drm/i915/display/intel_display_types.h | 8 +- > drivers/gpu/drm/i915/display/intel_dp.c | 44 ++++++++-- > drivers/gpu/drm/i915/display/intel_psr.c | 88 +++++++++++++---- > -- > 3 files changed, 104 insertions(+), 36 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h > b/drivers/gpu/drm/i915/display/intel_display_types.h > index 731f2ec04d5c..1ff7e6c03b44 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_types.h > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h > @@ -1202,6 +1202,7 @@ struct intel_crtc_state { > bool has_psr2; > bool enable_psr2_sel_fetch; > bool req_psr2_sdp_prior_scanline; > + bool has_pr; > bool wm_level_disabled; > u32 dc3co_exitline; > u16 su_y_granularity; > @@ -1693,6 +1694,8 @@ struct intel_psr { > bool irq_aux_error; > u16 su_w_granularity; > u16 su_y_granularity; > + bool source_panel_replay_support; > + bool sink_panel_replay_support; > u32 dc3co_exitline; > u32 dc3co_exit_delay; > struct delayed_work dc3co_work; > @@ -1983,12 +1986,15 @@ dp_to_lspcon(struct intel_dp *intel_dp) > #define CAN_PSR(intel_dp) ((intel_dp)->psr.sink_support && \ > (intel_dp)->psr.source_support) > > +#define CAN_PANEL_REPLAY(intel_dp) ((intel_dp)- > >psr.sink_panel_replay_support && \ > + (intel_dp)- > >psr.source_panel_replay_support) > + > static inline bool intel_encoder_can_psr(struct intel_encoder > *encoder) > { > if (!intel_encoder_is_dp(encoder)) > return false; > > - return CAN_PSR(enc_to_intel_dp(encoder)); > + return CAN_PSR(enc_to_intel_dp(encoder)) || > CAN_PANEL_REPLAY(enc_to_intel_dp(encoder)); > } > > static inline struct intel_digital_port * > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 03675620e3ea..0ba231ee6e34 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -1946,12 +1946,22 @@ static void > intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc > struct intel_crtc *crtc = to_intel_crtc(crtc_state- > >uapi.crtc); > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > > - /* > - * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118 > - * VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/ > - * Colorimetry Format indication. > - */ > - vsc->revision = 0x5; > + if (crtc_state->has_pr) { > + /* > + * Prepare VSC Header for SU as per DP 2.0 spec, > Table 2-223 > + * VSC SDP supporting 3D stereo, Panel Replay, and > Pixel > + * Encoding/Colorimetry Format indication. > + */ > + vsc->revision = 0x7; > + } else { > + /* > + * Prepare VSC Header for SU as per DP 1.4 spec, > Table 2-118 > + * VSC SDP supporting 3D stereo, PSR2, and Pixel > Encoding/ > + * Colorimetry Format indication. > + */ > + vsc->revision = 0x5; > + } > + > vsc->length = 0x13; > > /* DP 1.4a spec, Table 2-120 */ > @@ -2060,6 +2070,21 @@ void intel_dp_compute_psr_vsc_sdp(struct > intel_dp *intel_dp, > vsc->revision = 0x4; > vsc->length = 0xe; > } > + } else if (crtc_state->has_pr) { > + if (intel_dp->psr.colorimetry_support && > + intel_dp_needs_vsc_sdp(crtc_state, conn_state)) { > + /* [Panel Replay with colorimetry info] */ > + intel_dp_compute_vsc_colorimetry(crtc_state, > conn_state, > + vsc); > + } else { > + /* > + * [Panel Replay without colorimetry info] > + * Prepare VSC Header for SU as per DP 2.0 > spec, Table 2-223 > + * VSC SDP supporting 3D stereo + Panel > Replay. > + */ > + vsc->revision = 0x6; > + vsc->length = 0x10; > + } > } else { > /* > * [PSR1] > @@ -3354,10 +3379,11 @@ static ssize_t intel_dp_vsc_sdp_pack(const > struct drm_dp_vsc_sdp *vsc, > sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data > Bytes */ > > /* > - * Only revision 0x5 supports Pixel Encoding/Colorimetry > Format as > - * per DP 1.4a spec. > + * Other than revision 0x5 which supports Pixel > Encoding/Colorimetry > + * Format as per DP 1.4a spec, revision 0x7 also supports > Pixel > + * Encoding/Colorimetry Format as per DP 2.0 spec. > */ > - if (vsc->revision != 0x5) > + if (vsc->revision != 0x5 || vsc->revision != 0x7) > goto out; > > /* VSC SDP Payload for DB16 through DB18 */ > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c > b/drivers/gpu/drm/i915/display/intel_psr.c > index 9fbcb4b93f11..7508e6c967e2 100644 > --- a/drivers/gpu/drm/i915/display/intel_psr.c > +++ b/drivers/gpu/drm/i915/display/intel_psr.c > @@ -472,6 +472,27 @@ static void intel_dp_get_su_granularity(struct > intel_dp *intel_dp) > intel_dp->psr.su_y_granularity = y; > } > > +static void _panel_replay_init_dpcd(struct intel_dp *intel_dp) > +{ > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + u8 pr_dpcd = 0; > + > + if (!HAS_PANEL_REPLAY(dev_priv)) > + return; > + > + drm_dp_dpcd_readb(&intel_dp->aux, DP_PANEL_REPLAY_CAP, > &pr_dpcd); > + > + if (!(pr_dpcd & DP_PANEL_REPLAY_SUPPORT)) { > + drm_dbg_kms(&dev_priv->drm, > + "Panel replay is not supported by > panel\n"); > + return; > + } > + > + drm_dbg_kms(&dev_priv->drm, > + "Panel replay is supported by panel\n"); > + intel_dp->psr.sink_panel_replay_support = true; > +} > + > static void _psr_init_dpcd(struct intel_dp *intel_dp) > { > struct drm_i915_private *i915 = > @@ -521,12 +542,13 @@ static void _psr_init_dpcd(struct intel_dp > *intel_dp) > > void intel_psr_init_dpcd(struct intel_dp *intel_dp) > { > + _panel_replay_init_dpcd(intel_dp); > + > drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp- > >psr_dpcd, > sizeof(intel_dp->psr_dpcd)); > > if (intel_dp->psr_dpcd[0]) > _psr_init_dpcd(intel_dp); > - /* TODO: Add PR case here */ > > if (intel_dp->psr.sink_psr2_support) { > intel_dp->psr.colorimetry_support = > @@ -1207,13 +1229,11 @@ static bool intel_psr2_config_valid(struct > intel_dp *intel_dp, > return false; > } > > -void intel_psr_compute_config(struct intel_dp *intel_dp, > - struct intel_crtc_state *crtc_state, > - struct drm_connector_state *conn_state) > +static bool _psr_compute_config(struct intel_dp *intel_dp, > + struct intel_crtc_state *crtc_state) > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > - const struct drm_display_mode *adjusted_mode = > - &crtc_state->hw.adjusted_mode; > + const struct drm_display_mode *adjusted_mode = &crtc_state- > >hw.adjusted_mode; > int psr_setup_time; > > /* > @@ -1221,10 +1241,36 @@ void intel_psr_compute_config(struct intel_dp > *intel_dp, > * So if VRR is enabled, do not enable PSR. > */ > if (crtc_state->vrr.enable) > - return; > + return false; > > if (!CAN_PSR(intel_dp)) > - return; > + return false; > + > + psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd); > + if (psr_setup_time < 0) { > + drm_dbg_kms(&dev_priv->drm, > + "PSR condition failed: Invalid PSR setup > time (0x%02x)\n", > + intel_dp->psr_dpcd[1]); > + return false; > + } > + > + if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) > > + adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay > - 1) { > + drm_dbg_kms(&dev_priv->drm, > + "PSR condition failed: PSR setup time (%d > us) too long\n", > + psr_setup_time); > + return false; > + } > + > + return true; > +} > + > +void intel_psr_compute_config(struct intel_dp *intel_dp, > + struct intel_crtc_state *crtc_state, > + struct drm_connector_state *conn_state) > +{ > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + const struct drm_display_mode *adjusted_mode = &crtc_state- > >hw.adjusted_mode; > > if (!psr_global_enabled(intel_dp)) { > drm_dbg_kms(&dev_priv->drm, "PSR disabled by > flag\n"); > @@ -1234,7 +1280,6 @@ void intel_psr_compute_config(struct intel_dp > *intel_dp, > if (intel_dp->psr.sink_not_reliable) { > drm_dbg_kms(&dev_priv->drm, > "PSR sink implementation is not > reliable\n"); > - return; > } > > if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { > @@ -1243,23 +1288,11 @@ void intel_psr_compute_config(struct intel_dp > *intel_dp, > return; > } > > - psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd); > - if (psr_setup_time < 0) { > - drm_dbg_kms(&dev_priv->drm, > - "PSR condition failed: Invalid PSR setup > time (0x%02x)\n", > - intel_dp->psr_dpcd[1]); > - return; > - } > - > - if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) > > - adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay > - 1) { > - drm_dbg_kms(&dev_priv->drm, > - "PSR condition failed: PSR setup time (%d > us) too long\n", > - psr_setup_time); > - return; > - } > + if (CAN_PANEL_REPLAY(intel_dp)) > + crtc_state->has_pr = true; > + else > + crtc_state->has_psr = _psr_compute_config(intel_dp, > crtc_state); > > - crtc_state->has_psr = true; > crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, > crtc_state); > > crtc_state->infoframes.enable |= > intel_hdmi_infoframe_enable(DP_SDP_VSC); > @@ -2699,7 +2732,7 @@ void intel_psr_init(struct intel_dp *intel_dp) > struct intel_digital_port *dig_port = > dp_to_dig_port(intel_dp); > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > > - if (!HAS_PSR(dev_priv)) > + if (!(HAS_PSR(dev_priv) || HAS_PANEL_REPLAY(dev_priv))) > return; > > /* > @@ -2719,6 +2752,9 @@ void intel_psr_init(struct intel_dp *intel_dp) > > intel_dp->psr.source_support = true; > > + if (HAS_PANEL_REPLAY(dev_priv) && !intel_dp_is_edp(intel_dp)) > + intel_dp->psr.source_panel_replay_support = true; I don't think it's correct to have both intel_dp->psr.source_support and intel_dp->psr.source_panel_replay_support set. E.g.: if (HAS_PANEL_REPLAY(dev_priv) && !intel_dp_is_edp(intel_dp)) intel_dp->psr.source_panel_replay_support = true; else intel_dp->psr.source_support = true; BR, Jouni Högander > > + if (HAS_PANEL_REPLAY(dev_priv) && !intel_dp_is_edp(intel_dp)) > + intel_dp->psr.source_panel_replay_support = true; > + > /* Set link_standby x link_off defaults */ > if (DISPLAY_VER(dev_priv) < 12) > /* For new platforms up to TGL let's respect VBT back > again */
On Fri, 2023-07-28 at 18:16 +0530, Animesh Manna wrote: > Modify existing PSR implementation to enable panel replay feature of > DP 2.0 > which is similar to PSR feature of EDP panel. There is different DPCD > address to check panel capability compare to PSR and vsc sdp header > is different. > > v1: Initial version. > v2: > - Set source_panel_replay_support flag under HAS_PNEL_REPLAY() check. > [Jouni] > - Code restructured around intel_panel_replay_init > and renamed to intel_panel_replay_init_dpcd. [Jouni] > - Remove the initial code modification around has_psr2 flag. [Jouni] > - Add CAN_PANEL_REPLAY() in intel_encoder_can_psr which is used to > enable in intel_psr_post_plane_update. [Jouni] > v3: > - Initialize both psr and panel-replay. [Jouni] > - Initialize both panel replay and psr if detected. [Jouni] > - Refactoring psr function by introducing _psr_compute_config(). > [Jouni] > - Add check for !is_edp while deriving source_panel_replay_support. > [Jouni] > - Enable panel replay dpcd initialization in a separate patch. > [Jouni] > > Cc: Jouni Högander <jouni.hogander@intel.com> > Signed-off-by: Animesh Manna <animesh.manna@intel.com> > --- > .../drm/i915/display/intel_display_types.h | 8 +- > drivers/gpu/drm/i915/display/intel_dp.c | 44 ++++++++-- > drivers/gpu/drm/i915/display/intel_psr.c | 88 +++++++++++++---- > -- > 3 files changed, 104 insertions(+), 36 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h > b/drivers/gpu/drm/i915/display/intel_display_types.h > index 731f2ec04d5c..1ff7e6c03b44 100644 > --- a/drivers/gpu/drm/i915/display/intel_display_types.h > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h > @@ -1202,6 +1202,7 @@ struct intel_crtc_state { > bool has_psr2; > bool enable_psr2_sel_fetch; > bool req_psr2_sdp_prior_scanline; > + bool has_pr; > bool wm_level_disabled; > u32 dc3co_exitline; > u16 su_y_granularity; > @@ -1693,6 +1694,8 @@ struct intel_psr { > bool irq_aux_error; > u16 su_w_granularity; > u16 su_y_granularity; > + bool source_panel_replay_support; > + bool sink_panel_replay_support; > u32 dc3co_exitline; > u32 dc3co_exit_delay; > struct delayed_work dc3co_work; > @@ -1983,12 +1986,15 @@ dp_to_lspcon(struct intel_dp *intel_dp) > #define CAN_PSR(intel_dp) ((intel_dp)->psr.sink_support && \ > (intel_dp)->psr.source_support) > > +#define CAN_PANEL_REPLAY(intel_dp) ((intel_dp)- > >psr.sink_panel_replay_support && \ > + (intel_dp)- > >psr.source_panel_replay_support) > + > static inline bool intel_encoder_can_psr(struct intel_encoder > *encoder) > { > if (!intel_encoder_is_dp(encoder)) > return false; > > - return CAN_PSR(enc_to_intel_dp(encoder)); > + return CAN_PSR(enc_to_intel_dp(encoder)) || > CAN_PANEL_REPLAY(enc_to_intel_dp(encoder)); > } > > static inline struct intel_digital_port * > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 03675620e3ea..0ba231ee6e34 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -1946,12 +1946,22 @@ static void > intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc > struct intel_crtc *crtc = to_intel_crtc(crtc_state- > >uapi.crtc); > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > > - /* > - * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118 > - * VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/ > - * Colorimetry Format indication. > - */ > - vsc->revision = 0x5; > + if (crtc_state->has_pr) { > + /* > + * Prepare VSC Header for SU as per DP 2.0 spec, > Table 2-223 > + * VSC SDP supporting 3D stereo, Panel Replay, and > Pixel > + * Encoding/Colorimetry Format indication. > + */ > + vsc->revision = 0x7; > + } else { > + /* > + * Prepare VSC Header for SU as per DP 1.4 spec, > Table 2-118 > + * VSC SDP supporting 3D stereo, PSR2, and Pixel > Encoding/ > + * Colorimetry Format indication. > + */ > + vsc->revision = 0x5; > + } > + > vsc->length = 0x13; > > /* DP 1.4a spec, Table 2-120 */ > @@ -2060,6 +2070,21 @@ void intel_dp_compute_psr_vsc_sdp(struct > intel_dp *intel_dp, > vsc->revision = 0x4; > vsc->length = 0xe; > } > + } else if (crtc_state->has_pr) { > + if (intel_dp->psr.colorimetry_support && > + intel_dp_needs_vsc_sdp(crtc_state, conn_state)) { > + /* [Panel Replay with colorimetry info] */ > + intel_dp_compute_vsc_colorimetry(crtc_state, > conn_state, > + vsc); > + } else { > + /* > + * [Panel Replay without colorimetry info] > + * Prepare VSC Header for SU as per DP 2.0 > spec, Table 2-223 > + * VSC SDP supporting 3D stereo + Panel > Replay. > + */ > + vsc->revision = 0x6; > + vsc->length = 0x10; > + } > } else { > /* > * [PSR1] > @@ -3354,10 +3379,11 @@ static ssize_t intel_dp_vsc_sdp_pack(const > struct drm_dp_vsc_sdp *vsc, > sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data > Bytes */ > > /* > - * Only revision 0x5 supports Pixel Encoding/Colorimetry > Format as > - * per DP 1.4a spec. > + * Other than revision 0x5 which supports Pixel > Encoding/Colorimetry > + * Format as per DP 1.4a spec, revision 0x7 also supports > Pixel > + * Encoding/Colorimetry Format as per DP 2.0 spec. > */ > - if (vsc->revision != 0x5) > + if (vsc->revision != 0x5 || vsc->revision != 0x7) > goto out; > > /* VSC SDP Payload for DB16 through DB18 */ > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c > b/drivers/gpu/drm/i915/display/intel_psr.c > index 9fbcb4b93f11..7508e6c967e2 100644 > --- a/drivers/gpu/drm/i915/display/intel_psr.c > +++ b/drivers/gpu/drm/i915/display/intel_psr.c > @@ -472,6 +472,27 @@ static void intel_dp_get_su_granularity(struct > intel_dp *intel_dp) > intel_dp->psr.su_y_granularity = y; > } > > +static void _panel_replay_init_dpcd(struct intel_dp *intel_dp) > +{ > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + u8 pr_dpcd = 0; > + > + if (!HAS_PANEL_REPLAY(dev_priv)) > + return; This check is not needed. It is ok to check sink capabilities regardles of if it's supported by the source. BR, Jouni Högander > + > + drm_dp_dpcd_readb(&intel_dp->aux, DP_PANEL_REPLAY_CAP, > &pr_dpcd); > + > + if (!(pr_dpcd & DP_PANEL_REPLAY_SUPPORT)) { > + drm_dbg_kms(&dev_priv->drm, > + "Panel replay is not supported by > panel\n"); > + return; > + } > + > + drm_dbg_kms(&dev_priv->drm, > + "Panel replay is supported by panel\n"); > + intel_dp->psr.sink_panel_replay_support = true; > +} > + > static void _psr_init_dpcd(struct intel_dp *intel_dp) > { > struct drm_i915_private *i915 = > @@ -521,12 +542,13 @@ static void _psr_init_dpcd(struct intel_dp > *intel_dp) > > void intel_psr_init_dpcd(struct intel_dp *intel_dp) > { > + _panel_replay_init_dpcd(intel_dp); > + > drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp- > >psr_dpcd, > sizeof(intel_dp->psr_dpcd)); > > if (intel_dp->psr_dpcd[0]) > _psr_init_dpcd(intel_dp); > - /* TODO: Add PR case here */ > > if (intel_dp->psr.sink_psr2_support) { > intel_dp->psr.colorimetry_support = > @@ -1207,13 +1229,11 @@ static bool intel_psr2_config_valid(struct > intel_dp *intel_dp, > return false; > } > > -void intel_psr_compute_config(struct intel_dp *intel_dp, > - struct intel_crtc_state *crtc_state, > - struct drm_connector_state *conn_state) > +static bool _psr_compute_config(struct intel_dp *intel_dp, > + struct intel_crtc_state *crtc_state) > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > - const struct drm_display_mode *adjusted_mode = > - &crtc_state->hw.adjusted_mode; > + const struct drm_display_mode *adjusted_mode = &crtc_state- > >hw.adjusted_mode; > int psr_setup_time; > > /* > @@ -1221,10 +1241,36 @@ void intel_psr_compute_config(struct intel_dp > *intel_dp, > * So if VRR is enabled, do not enable PSR. > */ > if (crtc_state->vrr.enable) > - return; > + return false; > > if (!CAN_PSR(intel_dp)) > - return; > + return false; > + > + psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd); > + if (psr_setup_time < 0) { > + drm_dbg_kms(&dev_priv->drm, > + "PSR condition failed: Invalid PSR setup > time (0x%02x)\n", > + intel_dp->psr_dpcd[1]); > + return false; > + } > + > + if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) > > + adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay > - 1) { > + drm_dbg_kms(&dev_priv->drm, > + "PSR condition failed: PSR setup time (%d > us) too long\n", > + psr_setup_time); > + return false; > + } > + > + return true; > +} > + > +void intel_psr_compute_config(struct intel_dp *intel_dp, > + struct intel_crtc_state *crtc_state, > + struct drm_connector_state *conn_state) > +{ > + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > + const struct drm_display_mode *adjusted_mode = &crtc_state- > >hw.adjusted_mode; > > if (!psr_global_enabled(intel_dp)) { > drm_dbg_kms(&dev_priv->drm, "PSR disabled by > flag\n"); > @@ -1234,7 +1280,6 @@ void intel_psr_compute_config(struct intel_dp > *intel_dp, > if (intel_dp->psr.sink_not_reliable) { > drm_dbg_kms(&dev_priv->drm, > "PSR sink implementation is not > reliable\n"); > - return; > } > > if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { > @@ -1243,23 +1288,11 @@ void intel_psr_compute_config(struct intel_dp > *intel_dp, > return; > } > > - psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd); > - if (psr_setup_time < 0) { > - drm_dbg_kms(&dev_priv->drm, > - "PSR condition failed: Invalid PSR setup > time (0x%02x)\n", > - intel_dp->psr_dpcd[1]); > - return; > - } > - > - if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) > > - adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay > - 1) { > - drm_dbg_kms(&dev_priv->drm, > - "PSR condition failed: PSR setup time (%d > us) too long\n", > - psr_setup_time); > - return; > - } > + if (CAN_PANEL_REPLAY(intel_dp)) > + crtc_state->has_pr = true; > + else > + crtc_state->has_psr = _psr_compute_config(intel_dp, > crtc_state); > > - crtc_state->has_psr = true; > crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, > crtc_state); > > crtc_state->infoframes.enable |= > intel_hdmi_infoframe_enable(DP_SDP_VSC); > @@ -2699,7 +2732,7 @@ void intel_psr_init(struct intel_dp *intel_dp) > struct intel_digital_port *dig_port = > dp_to_dig_port(intel_dp); > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > > - if (!HAS_PSR(dev_priv)) > + if (!(HAS_PSR(dev_priv) || HAS_PANEL_REPLAY(dev_priv))) > return; > > /* > @@ -2719,6 +2752,9 @@ void intel_psr_init(struct intel_dp *intel_dp) > > intel_dp->psr.source_support = true; > > + if (HAS_PANEL_REPLAY(dev_priv) && !intel_dp_is_edp(intel_dp)) > + intel_dp->psr.source_panel_replay_support = true; > + > /* Set link_standby x link_off defaults */ > if (DISPLAY_VER(dev_priv) < 12) > /* For new platforms up to TGL let's respect VBT back > again */
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 731f2ec04d5c..1ff7e6c03b44 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1202,6 +1202,7 @@ struct intel_crtc_state { bool has_psr2; bool enable_psr2_sel_fetch; bool req_psr2_sdp_prior_scanline; + bool has_pr; bool wm_level_disabled; u32 dc3co_exitline; u16 su_y_granularity; @@ -1693,6 +1694,8 @@ struct intel_psr { bool irq_aux_error; u16 su_w_granularity; u16 su_y_granularity; + bool source_panel_replay_support; + bool sink_panel_replay_support; u32 dc3co_exitline; u32 dc3co_exit_delay; struct delayed_work dc3co_work; @@ -1983,12 +1986,15 @@ dp_to_lspcon(struct intel_dp *intel_dp) #define CAN_PSR(intel_dp) ((intel_dp)->psr.sink_support && \ (intel_dp)->psr.source_support) +#define CAN_PANEL_REPLAY(intel_dp) ((intel_dp)->psr.sink_panel_replay_support && \ + (intel_dp)->psr.source_panel_replay_support) + static inline bool intel_encoder_can_psr(struct intel_encoder *encoder) { if (!intel_encoder_is_dp(encoder)) return false; - return CAN_PSR(enc_to_intel_dp(encoder)); + return CAN_PSR(enc_to_intel_dp(encoder)) || CAN_PANEL_REPLAY(enc_to_intel_dp(encoder)); } static inline struct intel_digital_port * diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 03675620e3ea..0ba231ee6e34 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1946,12 +1946,22 @@ static void intel_dp_compute_vsc_colorimetry(const struct intel_crtc_state *crtc struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - /* - * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118 - * VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/ - * Colorimetry Format indication. - */ - vsc->revision = 0x5; + if (crtc_state->has_pr) { + /* + * Prepare VSC Header for SU as per DP 2.0 spec, Table 2-223 + * VSC SDP supporting 3D stereo, Panel Replay, and Pixel + * Encoding/Colorimetry Format indication. + */ + vsc->revision = 0x7; + } else { + /* + * Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118 + * VSC SDP supporting 3D stereo, PSR2, and Pixel Encoding/ + * Colorimetry Format indication. + */ + vsc->revision = 0x5; + } + vsc->length = 0x13; /* DP 1.4a spec, Table 2-120 */ @@ -2060,6 +2070,21 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp, vsc->revision = 0x4; vsc->length = 0xe; } + } else if (crtc_state->has_pr) { + if (intel_dp->psr.colorimetry_support && + intel_dp_needs_vsc_sdp(crtc_state, conn_state)) { + /* [Panel Replay with colorimetry info] */ + intel_dp_compute_vsc_colorimetry(crtc_state, conn_state, + vsc); + } else { + /* + * [Panel Replay without colorimetry info] + * Prepare VSC Header for SU as per DP 2.0 spec, Table 2-223 + * VSC SDP supporting 3D stereo + Panel Replay. + */ + vsc->revision = 0x6; + vsc->length = 0x10; + } } else { /* * [PSR1] @@ -3354,10 +3379,11 @@ static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */ /* - * Only revision 0x5 supports Pixel Encoding/Colorimetry Format as - * per DP 1.4a spec. + * Other than revision 0x5 which supports Pixel Encoding/Colorimetry + * Format as per DP 1.4a spec, revision 0x7 also supports Pixel + * Encoding/Colorimetry Format as per DP 2.0 spec. */ - if (vsc->revision != 0x5) + if (vsc->revision != 0x5 || vsc->revision != 0x7) goto out; /* VSC SDP Payload for DB16 through DB18 */ diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 9fbcb4b93f11..7508e6c967e2 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -472,6 +472,27 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp) intel_dp->psr.su_y_granularity = y; } +static void _panel_replay_init_dpcd(struct intel_dp *intel_dp) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + u8 pr_dpcd = 0; + + if (!HAS_PANEL_REPLAY(dev_priv)) + return; + + drm_dp_dpcd_readb(&intel_dp->aux, DP_PANEL_REPLAY_CAP, &pr_dpcd); + + if (!(pr_dpcd & DP_PANEL_REPLAY_SUPPORT)) { + drm_dbg_kms(&dev_priv->drm, + "Panel replay is not supported by panel\n"); + return; + } + + drm_dbg_kms(&dev_priv->drm, + "Panel replay is supported by panel\n"); + intel_dp->psr.sink_panel_replay_support = true; +} + static void _psr_init_dpcd(struct intel_dp *intel_dp) { struct drm_i915_private *i915 = @@ -521,12 +542,13 @@ static void _psr_init_dpcd(struct intel_dp *intel_dp) void intel_psr_init_dpcd(struct intel_dp *intel_dp) { + _panel_replay_init_dpcd(intel_dp); + drm_dp_dpcd_read(&intel_dp->aux, DP_PSR_SUPPORT, intel_dp->psr_dpcd, sizeof(intel_dp->psr_dpcd)); if (intel_dp->psr_dpcd[0]) _psr_init_dpcd(intel_dp); - /* TODO: Add PR case here */ if (intel_dp->psr.sink_psr2_support) { intel_dp->psr.colorimetry_support = @@ -1207,13 +1229,11 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, return false; } -void intel_psr_compute_config(struct intel_dp *intel_dp, - struct intel_crtc_state *crtc_state, - struct drm_connector_state *conn_state) +static bool _psr_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - const struct drm_display_mode *adjusted_mode = - &crtc_state->hw.adjusted_mode; + const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; int psr_setup_time; /* @@ -1221,10 +1241,36 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, * So if VRR is enabled, do not enable PSR. */ if (crtc_state->vrr.enable) - return; + return false; if (!CAN_PSR(intel_dp)) - return; + return false; + + psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd); + if (psr_setup_time < 0) { + drm_dbg_kms(&dev_priv->drm, + "PSR condition failed: Invalid PSR setup time (0x%02x)\n", + intel_dp->psr_dpcd[1]); + return false; + } + + if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) > + adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay - 1) { + drm_dbg_kms(&dev_priv->drm, + "PSR condition failed: PSR setup time (%d us) too long\n", + psr_setup_time); + return false; + } + + return true; +} + +void intel_psr_compute_config(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; if (!psr_global_enabled(intel_dp)) { drm_dbg_kms(&dev_priv->drm, "PSR disabled by flag\n"); @@ -1234,7 +1280,6 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, if (intel_dp->psr.sink_not_reliable) { drm_dbg_kms(&dev_priv->drm, "PSR sink implementation is not reliable\n"); - return; } if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { @@ -1243,23 +1288,11 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, return; } - psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd); - if (psr_setup_time < 0) { - drm_dbg_kms(&dev_priv->drm, - "PSR condition failed: Invalid PSR setup time (0x%02x)\n", - intel_dp->psr_dpcd[1]); - return; - } - - if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) > - adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay - 1) { - drm_dbg_kms(&dev_priv->drm, - "PSR condition failed: PSR setup time (%d us) too long\n", - psr_setup_time); - return; - } + if (CAN_PANEL_REPLAY(intel_dp)) + crtc_state->has_pr = true; + else + crtc_state->has_psr = _psr_compute_config(intel_dp, crtc_state); - crtc_state->has_psr = true; crtc_state->has_psr2 = intel_psr2_config_valid(intel_dp, crtc_state); crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC); @@ -2699,7 +2732,7 @@ void intel_psr_init(struct intel_dp *intel_dp) struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - if (!HAS_PSR(dev_priv)) + if (!(HAS_PSR(dev_priv) || HAS_PANEL_REPLAY(dev_priv))) return; /* @@ -2719,6 +2752,9 @@ void intel_psr_init(struct intel_dp *intel_dp) intel_dp->psr.source_support = true; + if (HAS_PANEL_REPLAY(dev_priv) && !intel_dp_is_edp(intel_dp)) + intel_dp->psr.source_panel_replay_support = true; + /* Set link_standby x link_off defaults */ if (DISPLAY_VER(dev_priv) < 12) /* For new platforms up to TGL let's respect VBT back again */
Modify existing PSR implementation to enable panel replay feature of DP 2.0 which is similar to PSR feature of EDP panel. There is different DPCD address to check panel capability compare to PSR and vsc sdp header is different. v1: Initial version. v2: - Set source_panel_replay_support flag under HAS_PNEL_REPLAY() check. [Jouni] - Code restructured around intel_panel_replay_init and renamed to intel_panel_replay_init_dpcd. [Jouni] - Remove the initial code modification around has_psr2 flag. [Jouni] - Add CAN_PANEL_REPLAY() in intel_encoder_can_psr which is used to enable in intel_psr_post_plane_update. [Jouni] v3: - Initialize both psr and panel-replay. [Jouni] - Initialize both panel replay and psr if detected. [Jouni] - Refactoring psr function by introducing _psr_compute_config(). [Jouni] - Add check for !is_edp while deriving source_panel_replay_support. [Jouni] - Enable panel replay dpcd initialization in a separate patch. [Jouni] Cc: Jouni Högander <jouni.hogander@intel.com> Signed-off-by: Animesh Manna <animesh.manna@intel.com> --- .../drm/i915/display/intel_display_types.h | 8 +- drivers/gpu/drm/i915/display/intel_dp.c | 44 ++++++++-- drivers/gpu/drm/i915/display/intel_psr.c | 88 +++++++++++++------ 3 files changed, 104 insertions(+), 36 deletions(-)