Message ID | 20230905073551.958368-4-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/20230905-154811 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/r/20230905073551.958368-4-animesh.manna%40intel.com patch subject: [Intel-gfx] [PATCH v5 3/6] drm/i915/panelreplay: Initializaton and compute config for panel replay config: i386-randconfig-r036-20230905 (https://download.01.org/0day-ci/archive/20230905/202309051831.AMUjJOcB-lkp@intel.com/config) compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230905/202309051831.AMUjJOcB-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/202309051831.AMUjJOcB-lkp@intel.com/ All warnings (new ones prefixed by >>): >> drivers/gpu/drm/i915/display/intel_dp.c:3779:27: warning: overlapping comparisons always evaluate to true [-Wtautological-overlap-compare] if (vsc->revision != 0x5 || vsc->revision != 0x7) ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~ 1 warning generated. vim +3779 drivers/gpu/drm/i915/display/intel_dp.c 3754 3755 static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, 3756 struct dp_sdp *sdp, size_t size) 3757 { 3758 size_t length = sizeof(struct dp_sdp); 3759 3760 if (size < length) 3761 return -ENOSPC; 3762 3763 memset(sdp, 0, size); 3764 3765 /* 3766 * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119 3767 * VSC SDP Header Bytes 3768 */ 3769 sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */ 3770 sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */ 3771 sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */ 3772 sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */ 3773 3774 /* 3775 * Other than revision 0x5 which supports Pixel Encoding/Colorimetry 3776 * Format as per DP 1.4a spec, revision 0x7 also supports Pixel 3777 * Encoding/Colorimetry Format as per DP 2.0 spec. 3778 */ > 3779 if (vsc->revision != 0x5 || vsc->revision != 0x7) 3780 goto out; 3781 3782 /* VSC SDP Payload for DB16 through DB18 */ 3783 /* Pixel Encoding and Colorimetry Formats */ 3784 sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */ 3785 sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */ 3786 3787 switch (vsc->bpc) { 3788 case 6: 3789 /* 6bpc: 0x0 */ 3790 break; 3791 case 8: 3792 sdp->db[17] = 0x1; /* DB17[3:0] */ 3793 break; 3794 case 10: 3795 sdp->db[17] = 0x2; 3796 break; 3797 case 12: 3798 sdp->db[17] = 0x3; 3799 break; 3800 case 16: 3801 sdp->db[17] = 0x4; 3802 break; 3803 default: 3804 MISSING_CASE(vsc->bpc); 3805 break; 3806 } 3807 /* Dynamic Range and Component Bit Depth */ 3808 if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA) 3809 sdp->db[17] |= 0x80; /* DB17[7] */ 3810 3811 /* Content Type */ 3812 sdp->db[18] = vsc->content_type & 0x7; 3813 3814 out: 3815 return length; 3816 } 3817
Hi Animesh, kernel test robot noticed the following build errors: [auto build test ERROR on drm-tip/drm-tip] url: https://github.com/intel-lab-lkp/linux/commits/Animesh-Manna/drm-panelreplay-dpcd-register-definition-for-panelreplay/20230905-154811 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/r/20230905073551.958368-4-animesh.manna%40intel.com patch subject: [Intel-gfx] [PATCH v5 3/6] drm/i915/panelreplay: Initializaton and compute config for panel replay config: i386-randconfig-003-20230905 (https://download.01.org/0day-ci/archive/20230905/202309051920.FD7yiD3K-lkp@intel.com/config) compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230905/202309051920.FD7yiD3K-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/202309051920.FD7yiD3K-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/gpu/drm/i915/display/intel_dp.c:3779:27: error: overlapping comparisons always evaluate to true [-Werror,-Wtautological-overlap-compare] if (vsc->revision != 0x5 || vsc->revision != 0x7) ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. vim +3779 drivers/gpu/drm/i915/display/intel_dp.c 3754 3755 static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, 3756 struct dp_sdp *sdp, size_t size) 3757 { 3758 size_t length = sizeof(struct dp_sdp); 3759 3760 if (size < length) 3761 return -ENOSPC; 3762 3763 memset(sdp, 0, size); 3764 3765 /* 3766 * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119 3767 * VSC SDP Header Bytes 3768 */ 3769 sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */ 3770 sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */ 3771 sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */ 3772 sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */ 3773 3774 /* 3775 * Other than revision 0x5 which supports Pixel Encoding/Colorimetry 3776 * Format as per DP 1.4a spec, revision 0x7 also supports Pixel 3777 * Encoding/Colorimetry Format as per DP 2.0 spec. 3778 */ > 3779 if (vsc->revision != 0x5 || vsc->revision != 0x7) 3780 goto out; 3781 3782 /* VSC SDP Payload for DB16 through DB18 */ 3783 /* Pixel Encoding and Colorimetry Formats */ 3784 sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */ 3785 sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */ 3786 3787 switch (vsc->bpc) { 3788 case 6: 3789 /* 6bpc: 0x0 */ 3790 break; 3791 case 8: 3792 sdp->db[17] = 0x1; /* DB17[3:0] */ 3793 break; 3794 case 10: 3795 sdp->db[17] = 0x2; 3796 break; 3797 case 12: 3798 sdp->db[17] = 0x3; 3799 break; 3800 case 16: 3801 sdp->db[17] = 0x4; 3802 break; 3803 default: 3804 MISSING_CASE(vsc->bpc); 3805 break; 3806 } 3807 /* Dynamic Range and Component Bit Depth */ 3808 if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA) 3809 sdp->db[17] |= 0x80; /* DB17[7] */ 3810 3811 /* Content Type */ 3812 sdp->db[18] = vsc->content_type & 0x7; 3813 3814 out: 3815 return length; 3816 } 3817
Hi Animesh, kernel test robot noticed the following build warnings: url: https://github.com/intel-lab-lkp/linux/commits/Animesh-Manna/drm-panelreplay-dpcd-register-definition-for-panelreplay/20230905-154811 base: git://anongit.freedesktop.org/drm/drm-tip drm-tip patch link: https://lore.kernel.org/r/20230905073551.958368-4-animesh.manna%40intel.com patch subject: [Intel-gfx] [PATCH v5 3/6] drm/i915/panelreplay: Initializaton and compute config for panel replay config: i386-randconfig-141-20230906 (https://download.01.org/0day-ci/archive/20230906/202309060644.uWp5zW4i-lkp@intel.com/config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce: (https://download.01.org/0day-ci/archive/20230906/202309060644.uWp5zW4i-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> | Reported-by: Dan Carpenter <dan.carpenter@linaro.org> | Closes: https://lore.kernel.org/r/202309060644.uWp5zW4i-lkp@intel.com/ smatch warnings: drivers/gpu/drm/i915/display/intel_dp.c:3779 intel_dp_vsc_sdp_pack() warn: was && intended here instead of ||? vim +3779 drivers/gpu/drm/i915/display/intel_dp.c 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3755 static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3756 struct dp_sdp *sdp, size_t size) 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3757 { 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3758 size_t length = sizeof(struct dp_sdp); 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3759 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3760 if (size < length) 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3761 return -ENOSPC; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3762 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3763 memset(sdp, 0, size); 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3764 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3765 /* 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3766 * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3767 * VSC SDP Header Bytes 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3768 */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3769 sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3770 sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3771 sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3772 sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3773 cafac5a9836199 Gwan-gyeong Mun 2020-05-14 3774 /* 4dd2d4a2ffcae4 Animesh Manna 2023-09-05 3775 * Other than revision 0x5 which supports Pixel Encoding/Colorimetry 4dd2d4a2ffcae4 Animesh Manna 2023-09-05 3776 * Format as per DP 1.4a spec, revision 0x7 also supports Pixel 4dd2d4a2ffcae4 Animesh Manna 2023-09-05 3777 * Encoding/Colorimetry Format as per DP 2.0 spec. cafac5a9836199 Gwan-gyeong Mun 2020-05-14 3778 */ 4dd2d4a2ffcae4 Animesh Manna 2023-09-05 @3779 if (vsc->revision != 0x5 || vsc->revision != 0x7) This changes the rest of the function into a no-op. Ideally this sort bug would be caught in testing. cafac5a9836199 Gwan-gyeong Mun 2020-05-14 3780 goto out; cafac5a9836199 Gwan-gyeong Mun 2020-05-14 3781 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3782 /* VSC SDP Payload for DB16 through DB18 */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3783 /* Pixel Encoding and Colorimetry Formats */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3784 sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3785 sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3786 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3787 switch (vsc->bpc) { 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3788 case 6: 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3789 /* 6bpc: 0x0 */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3790 break; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3791 case 8: 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3792 sdp->db[17] = 0x1; /* DB17[3:0] */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3793 break; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3794 case 10: 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3795 sdp->db[17] = 0x2; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3796 break; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3797 case 12: 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3798 sdp->db[17] = 0x3; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3799 break; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3800 case 16: 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3801 sdp->db[17] = 0x4; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3802 break; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3803 default: 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3804 MISSING_CASE(vsc->bpc); 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3805 break; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3806 } 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3807 /* Dynamic Range and Component Bit Depth */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3808 if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA) 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3809 sdp->db[17] |= 0x80; /* DB17[7] */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3810 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3811 /* Content Type */ 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3812 sdp->db[18] = vsc->content_type & 0x7; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3813 cafac5a9836199 Gwan-gyeong Mun 2020-05-14 3814 out: 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3815 return length; 03c761b00c87d6 Gwan-gyeong Mun 2020-02-11 3816 }
On Tue, 2023-09-05 at 13:05 +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_PANEL_REPLAY() > condition 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] > > v4: > - HAS_PANEL_REPLAY() check not needed during sink capability check. > [Jouni] > - Set either panel replay source support or psr. [Jouni] > > v5: > - HAS_PANEL_REPLAY() removed and use HAS_DP20() instead. [Jouni] > - Move psr related code to intel_psr.c. [Jani] > - Reset sink_panel_replay_support flag during disconnection. [Jani] > > Cc: Jouni Högander <jouni.hogander@intel.com> > Signed-off-by: Animesh Manna <animesh.manna@intel.com> > --- > .../drm/i915/display/intel_display_types.h | 14 +-- > drivers/gpu/drm/i915/display/intel_dp.c | 45 +++++++-- > drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 + > drivers/gpu/drm/i915/display/intel_psr.c | 96 +++++++++++++---- > -- > drivers/gpu/drm/i915/display/intel_psr.h | 7 ++ > 5 files changed, 118 insertions(+), 47 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h > b/drivers/gpu/drm/i915/display/intel_display_types.h > index c21064794f32..4022d6d8281a 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_panel_replay; > 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; > @@ -1980,17 +1983,6 @@ dp_to_lspcon(struct intel_dp *intel_dp) > > #define dp_to_i915(__intel_dp) to_i915(dp_to_dig_port(__intel_dp)- > >base.base.dev) > > -#define CAN_PSR(intel_dp) ((intel_dp)->psr.sink_support && \ > - (intel_dp)->psr.source_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)); > -} > - > static inline struct intel_digital_port * > hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) > { > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c > b/drivers/gpu/drm/i915/display/intel_dp.c > index 3faa68989d85..d8c151196a81 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp.c > +++ b/drivers/gpu/drm/i915/display/intel_dp.c > @@ -2338,12 +2338,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_panel_replay) { > + /* > + * 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 */ > @@ -2452,6 +2462,21 @@ void intel_dp_compute_psr_vsc_sdp(struct > intel_dp *intel_dp, > vsc->revision = 0x4; > vsc->length = 0xe; > } > + } else if (crtc_state->has_panel_replay) { > + 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] > @@ -3747,10 +3772,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 */ > @@ -5275,6 +5301,7 @@ intel_dp_detect(struct drm_connector > *connector, > if (status == connector_status_disconnected) { > memset(&intel_dp->compliance, 0, sizeof(intel_dp- > >compliance)); > memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp- > >dsc_dpcd)); > + intel_dp->psr.sink_panel_replay_support = false; > > if (intel_dp->is_mst) { > drm_dbg_kms(&dev_priv->drm, > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c > b/drivers/gpu/drm/i915/display/intel_dp_mst.c > index 2d1c42a5e684..65f68997281e 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c > @@ -43,6 +43,7 @@ > #include "intel_dpio_phy.h" > #include "intel_hdcp.h" > #include "intel_hotplug.h" > +#include "intel_psr.h" > #include "skl_scaler.h" > > static int intel_dp_mst_check_constraints(struct drm_i915_private > *i915, int bpp, > @@ -383,6 +384,8 @@ static int intel_dp_mst_compute_config(struct > intel_encoder *encoder, > > intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); > > + intel_psr_compute_config(intel_dp, pipe_config, conn_state); > + > return 0; > } > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c > b/drivers/gpu/drm/i915/display/intel_psr.c > index 24eed99e8811..f2209fc94125 100644 > --- a/drivers/gpu/drm/i915/display/intel_psr.c > +++ b/drivers/gpu/drm/i915/display/intel_psr.c > @@ -171,6 +171,15 @@ > * irrelevant for normal operation. > */ > > +bool intel_encoder_can_psr(struct intel_encoder *encoder) > +{ > + if (intel_encoder_is_dp(encoder) || encoder->type == > INTEL_OUTPUT_DP_MST) > + return CAN_PSR(enc_to_intel_dp(encoder)) || > + CAN_PANEL_REPLAY(enc_to_intel_dp(encoder)); > + else > + return false; > +} > + > static bool psr_global_enabled(struct intel_dp *intel_dp) > { > struct intel_connector *connector = intel_dp- > >attached_connector; > @@ -473,6 +482,24 @@ 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; > + > + 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 = > @@ -522,12 +549,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 = > @@ -1208,13 +1236,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; > > /* > @@ -1222,10 +1248,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"); > @@ -1235,7 +1287,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; You should not remove this return here? BR, Jouni Högander > } > > if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { > @@ -1244,23 +1295,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_panel_replay = 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); > @@ -2705,7 +2744,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_DP20(dev_priv))) > return; > > /* > @@ -2723,7 +2762,10 @@ void intel_psr_init(struct intel_dp *intel_dp) > return; > } > > - intel_dp->psr.source_support = true; > + if (HAS_DP20(dev_priv) && !intel_dp_is_edp(intel_dp)) > + intel_dp->psr.source_panel_replay_support = true; > + else > + intel_dp->psr.source_support = true; > > /* Set link_standby x link_off defaults */ > if (DISPLAY_VER(dev_priv) < 12) > diff --git a/drivers/gpu/drm/i915/display/intel_psr.h > b/drivers/gpu/drm/i915/display/intel_psr.h > index 0b95e8aa615f..1179abc354df 100644 > --- a/drivers/gpu/drm/i915/display/intel_psr.h > +++ b/drivers/gpu/drm/i915/display/intel_psr.h > @@ -21,6 +21,13 @@ struct intel_encoder; > struct intel_plane; > struct intel_plane_state; > > +#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) > + > +bool intel_encoder_can_psr(struct intel_encoder *encoder); > void intel_psr_init_dpcd(struct intel_dp *intel_dp); > void intel_psr_pre_plane_update(struct intel_atomic_state *state, > struct intel_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index c21064794f32..4022d6d8281a 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_panel_replay; 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; @@ -1980,17 +1983,6 @@ dp_to_lspcon(struct intel_dp *intel_dp) #define dp_to_i915(__intel_dp) to_i915(dp_to_dig_port(__intel_dp)->base.base.dev) -#define CAN_PSR(intel_dp) ((intel_dp)->psr.sink_support && \ - (intel_dp)->psr.source_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)); -} - static inline struct intel_digital_port * hdmi_to_dig_port(struct intel_hdmi *intel_hdmi) { diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 3faa68989d85..d8c151196a81 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2338,12 +2338,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_panel_replay) { + /* + * 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 */ @@ -2452,6 +2462,21 @@ void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp, vsc->revision = 0x4; vsc->length = 0xe; } + } else if (crtc_state->has_panel_replay) { + 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] @@ -3747,10 +3772,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 */ @@ -5275,6 +5301,7 @@ intel_dp_detect(struct drm_connector *connector, if (status == connector_status_disconnected) { memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance)); memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd)); + intel_dp->psr.sink_panel_replay_support = false; if (intel_dp->is_mst) { drm_dbg_kms(&dev_priv->drm, diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 2d1c42a5e684..65f68997281e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -43,6 +43,7 @@ #include "intel_dpio_phy.h" #include "intel_hdcp.h" #include "intel_hotplug.h" +#include "intel_psr.h" #include "skl_scaler.h" static int intel_dp_mst_check_constraints(struct drm_i915_private *i915, int bpp, @@ -383,6 +384,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder, intel_ddi_compute_min_voltage_level(dev_priv, pipe_config); + intel_psr_compute_config(intel_dp, pipe_config, conn_state); + return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 24eed99e8811..f2209fc94125 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -171,6 +171,15 @@ * irrelevant for normal operation. */ +bool intel_encoder_can_psr(struct intel_encoder *encoder) +{ + if (intel_encoder_is_dp(encoder) || encoder->type == INTEL_OUTPUT_DP_MST) + return CAN_PSR(enc_to_intel_dp(encoder)) || + CAN_PANEL_REPLAY(enc_to_intel_dp(encoder)); + else + return false; +} + static bool psr_global_enabled(struct intel_dp *intel_dp) { struct intel_connector *connector = intel_dp->attached_connector; @@ -473,6 +482,24 @@ 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; + + 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 = @@ -522,12 +549,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 = @@ -1208,13 +1236,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; /* @@ -1222,10 +1248,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"); @@ -1235,7 +1287,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) { @@ -1244,23 +1295,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_panel_replay = 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); @@ -2705,7 +2744,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_DP20(dev_priv))) return; /* @@ -2723,7 +2762,10 @@ void intel_psr_init(struct intel_dp *intel_dp) return; } - intel_dp->psr.source_support = true; + if (HAS_DP20(dev_priv) && !intel_dp_is_edp(intel_dp)) + intel_dp->psr.source_panel_replay_support = true; + else + intel_dp->psr.source_support = true; /* Set link_standby x link_off defaults */ if (DISPLAY_VER(dev_priv) < 12) diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index 0b95e8aa615f..1179abc354df 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -21,6 +21,13 @@ struct intel_encoder; struct intel_plane; struct intel_plane_state; +#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) + +bool intel_encoder_can_psr(struct intel_encoder *encoder); void intel_psr_init_dpcd(struct intel_dp *intel_dp); void intel_psr_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc);
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_PANEL_REPLAY() condition 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] v4: - HAS_PANEL_REPLAY() check not needed during sink capability check. [Jouni] - Set either panel replay source support or psr. [Jouni] v5: - HAS_PANEL_REPLAY() removed and use HAS_DP20() instead. [Jouni] - Move psr related code to intel_psr.c. [Jani] - Reset sink_panel_replay_support flag during disconnection. [Jani] Cc: Jouni Högander <jouni.hogander@intel.com> Signed-off-by: Animesh Manna <animesh.manna@intel.com> --- .../drm/i915/display/intel_display_types.h | 14 +-- drivers/gpu/drm/i915/display/intel_dp.c | 45 +++++++-- drivers/gpu/drm/i915/display/intel_dp_mst.c | 3 + drivers/gpu/drm/i915/display/intel_psr.c | 96 +++++++++++++------ drivers/gpu/drm/i915/display/intel_psr.h | 7 ++ 5 files changed, 118 insertions(+), 47 deletions(-)