Message ID | 20210311223632.3191939-57-matthew.d.roper@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Introduce Alder Lake-P | expand |
On Thu, 2021-03-11 at 14:36 -0800, Matt Roper wrote: > From: José Roberto de Souza <jose.souza@intel.com> > > Implements changes around PSR for alderlake-P: > > - EDP_SU_TRACK_ENABLE was removed and bit 30 now has other function > - Some bits of PSR2_MAN_TRK_CTL moved and SF_PARTIAL_FRAME_UPDATE was > removed setting SU_REGION_START/END_ADDR will do this job > - SU_REGION_START/END_ADDR have now line granularity but will need to > be aligned with DSC when the PSRS + DSC support lands > > BSpec: 50422 > BSpec: 50424 > Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com> > Cc: Anusha Srivatsa <anusha.srivatsa@intel.com> > Signed-off-by: José Roberto de Souza <jose.souza@intel.com> > Signed-off-by: Clinton Taylor <Clinton.A.Taylor@intel.com> > Signed-off-by: Matt Roper <matthew.d.roper@intel.com> > --- > drivers/gpu/drm/i915/display/intel_psr.c | 51 +++++++++++++++++++--- > -- > drivers/gpu/drm/i915/i915_reg.h | 26 +++++++----- > 2 files changed, 56 insertions(+), 21 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_psr.c > b/drivers/gpu/drm/i915/display/intel_psr.c > index e71d2dd6a4a5..752de6f8df61 100644 > --- a/drivers/gpu/drm/i915/display/intel_psr.c > +++ b/drivers/gpu/drm/i915/display/intel_psr.c > @@ -519,11 +519,13 @@ static u32 intel_psr2_get_tp_time(struct > intel_dp *intel_dp) > static void hsw_activate_psr2(struct intel_dp *intel_dp) > { > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > - u32 val; > + u32 val = EDP_PSR2_ENABLE; > > val = psr_compute_idle_frames(intel_dp) << > EDP_PSR2_IDLE_FRAME_SHIFT; It over-writes the variable val. it also should be changed like this. val |= psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT; > > - val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE; > + if (!IS_ALDERLAKE_P(dev_priv)) > + val |= EDP_SU_TRACK_ENABLE; > + > if (DISPLAY_VER(dev_priv) >= 10) > val |= EDP_Y_COORDINATE_ENABLE; > > @@ -1245,21 +1247,32 @@ void > intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state > *crtc_st > static void psr2_man_trk_ctl_calc(struct intel_crtc_state > *crtc_state, > struct drm_rect *clip, bool > full_update) > { > + struct intel_crtc *crtc = to_intel_crtc(crtc_state- > >uapi.crtc); > + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > u32 val = PSR2_MAN_TRK_CTL_ENABLE; > > if (full_update) { > - val |= PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; > + if (IS_ALDERLAKE_P(dev_priv)) > + val |= > ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; > + else > + val |= PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; > + > goto exit; > } > > if (clip->y1 == -1) > goto exit; > > - drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 || clip- > >y2 % 4); > + if (IS_ALDERLAKE_P(dev_priv)) { > + val |= > ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1); > + val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip- > >y2); > + } else { > + drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 > || clip->y2 % 4); > > - val |= PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE; > - val |= PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1 / 4 + > 1); > - val |= PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 / 4 + 1); > + val |= PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE; > + val |= PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1 > / 4 + 1); > + val |= PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 / > 4 + 1); > + } > exit: > crtc_state->psr2_man_track_ctl = val; > } > @@ -1280,6 +1293,25 @@ static void clip_area_update(struct drm_rect > *overlap_damage_area, > overlap_damage_area->y2 = damage_area->y2; > } > > +static void intel_psr2_sel_fetch_pipe_alignment(const struct > intel_crtc_state *crtc_state, > + struct drm_rect > *pipe_clip) > +{ > + struct intel_crtc *crtc = to_intel_crtc(crtc_state- > >uapi.crtc); > + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > + > + if (IS_ALDERLAKE_P(dev_priv)) { > + /* > + * TODO: ADL-P have line granularity but when DSC is > enabled it > + * needs to be aligned with DSC boundaries. > + */ > + } else { > + /* It must be aligned to 4 lines/1 block */ > + pipe_clip->y1 -= pipe_clip->y1 % 4; > + if (pipe_clip->y2 % 4) > + pipe_clip->y2 = ((pipe_clip->y2 / 4) + 1) * > 4; > + } > +} > + > int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, > struct intel_crtc *crtc) > { > @@ -1388,10 +1420,7 @@ int intel_psr2_sel_fetch_update(struct > intel_atomic_state *state, > if (full_update) > goto skip_sel_fetch_set_loop; > > - /* It must be aligned to 4 lines */ > - pipe_clip.y1 -= pipe_clip.y1 % 4; > - if (pipe_clip.y2 % 4) > - pipe_clip.y2 = ((pipe_clip.y2 / 4) + 1) * 4; > + intel_psr2_sel_fetch_pipe_alignment(crtc_state, &pipe_clip); > > /* > * Now that we have the pipe damaged area check if it > intersect with > diff --git a/drivers/gpu/drm/i915/i915_reg.h > b/drivers/gpu/drm/i915/i915_reg.h > index d48a9dec8476..37caab2a4215 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -4563,7 +4563,7 @@ enum { > #define _PSR2_CTL_EDP 0x6f900 > #define EDP_PSR2_CTL(tran) _MMIO_TRANS2(tran, > _PSR2_CTL_A) > #define EDP_PSR2_ENABLE (1 << 31) > -#define EDP_SU_TRACK_ENABLE (1 << 30) > +#define EDP_SU_TRACK_ENABLE (1 << 30) /* up to > adl-p */ > #define TGL_EDP_PSR2_BLOCK_COUNT_NUM_2 (0 << 28) > #define TGL_EDP_PSR2_BLOCK_COUNT_NUM_3 (1 << 28) > #define EDP_Y_COORDINATE_VALID (1 << 26) /* GLK and > CNL+ */ > @@ -4630,17 +4630,23 @@ enum { > #define PSR2_SU_STATUS_MASK(frame) (0x3ff << > PSR2_SU_STATUS_SHIFT(frame)) > #define PSR2_SU_STATUS_FRAMES 8 > > -#define _PSR2_MAN_TRK_CTL_A 0x60910 > -#define _PSR2_MAN_TRK_CTL_EDP 0x6f910 > -#define > PSR2_MAN_TRK_CTL(tran) _MMIO_TRANS2(tran, > _PSR2_MAN_TRK_CTL_A) > -#define PSR2_MAN_TRK_CTL_ENABLE REG_BIT(31) > -#define > PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(30, 21) > -#define > PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(PSR2_MAN > _TRK_CTL_SU_REGION_START_ADDR_MASK, val) > +#define > _PSR2_MAN_TRK_CTL_A 0x60910 > +#define > _PSR2_MAN_TRK_CTL_EDP 0x6f910 > +#define > PSR2_MAN_TRK_CTL(tran) _MMIO_TRANS2(t > ran, _PSR2_MAN_TRK_CTL_A) > +#define > PSR2_MAN_TRK_CTL_ENABLE REG_BIT(31) > +#define > PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(30, > 21) > +#define > PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP( > PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) > #define > PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK REG_GENMASK(20, > 11) > #define > PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val) REG_FIELD_PREP( > PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val) > -#define PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(3) > -#define PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(2) > -#define PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE REG_BIT(1) > +#define > PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(3) > +#define > PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(2) > +#define > PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE REG_BIT(1) > +#define > ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(28, > 16) > +#define > ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP( > ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) > +#define > ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK REG_GENMASK(12, > 0) > +#define > ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val) REG_FIELD_PREP( > ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val) > +#define > ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(14) > +#define > ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(13) > > /* Icelake DSC Rate Control Range Parameter Registers */ > #define DSCA_RC_RANGE_PARAMETERS_0 _MMIO(0x6B240)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index e71d2dd6a4a5..752de6f8df61 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -519,11 +519,13 @@ static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp) static void hsw_activate_psr2(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u32 val; + u32 val = EDP_PSR2_ENABLE; val = psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT; - val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE; + if (!IS_ALDERLAKE_P(dev_priv)) + val |= EDP_SU_TRACK_ENABLE; + if (DISPLAY_VER(dev_priv) >= 10) val |= EDP_Y_COORDINATE_ENABLE; @@ -1245,21 +1247,32 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, struct drm_rect *clip, bool full_update) { + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 val = PSR2_MAN_TRK_CTL_ENABLE; if (full_update) { - val |= PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; + if (IS_ALDERLAKE_P(dev_priv)) + val |= ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; + else + val |= PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; + goto exit; } if (clip->y1 == -1) goto exit; - drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 || clip->y2 % 4); + if (IS_ALDERLAKE_P(dev_priv)) { + val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1); + val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2); + } else { + drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 || clip->y2 % 4); - val |= PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE; - val |= PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1 / 4 + 1); - val |= PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 / 4 + 1); + val |= PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE; + val |= PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1 / 4 + 1); + val |= PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 / 4 + 1); + } exit: crtc_state->psr2_man_track_ctl = val; } @@ -1280,6 +1293,25 @@ static void clip_area_update(struct drm_rect *overlap_damage_area, overlap_damage_area->y2 = damage_area->y2; } +static void intel_psr2_sel_fetch_pipe_alignment(const struct intel_crtc_state *crtc_state, + struct drm_rect *pipe_clip) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + + if (IS_ALDERLAKE_P(dev_priv)) { + /* + * TODO: ADL-P have line granularity but when DSC is enabled it + * needs to be aligned with DSC boundaries. + */ + } else { + /* It must be aligned to 4 lines/1 block */ + pipe_clip->y1 -= pipe_clip->y1 % 4; + if (pipe_clip->y2 % 4) + pipe_clip->y2 = ((pipe_clip->y2 / 4) + 1) * 4; + } +} + int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -1388,10 +1420,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, if (full_update) goto skip_sel_fetch_set_loop; - /* It must be aligned to 4 lines */ - pipe_clip.y1 -= pipe_clip.y1 % 4; - if (pipe_clip.y2 % 4) - pipe_clip.y2 = ((pipe_clip.y2 / 4) + 1) * 4; + intel_psr2_sel_fetch_pipe_alignment(crtc_state, &pipe_clip); /* * Now that we have the pipe damaged area check if it intersect with diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d48a9dec8476..37caab2a4215 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4563,7 +4563,7 @@ enum { #define _PSR2_CTL_EDP 0x6f900 #define EDP_PSR2_CTL(tran) _MMIO_TRANS2(tran, _PSR2_CTL_A) #define EDP_PSR2_ENABLE (1 << 31) -#define EDP_SU_TRACK_ENABLE (1 << 30) +#define EDP_SU_TRACK_ENABLE (1 << 30) /* up to adl-p */ #define TGL_EDP_PSR2_BLOCK_COUNT_NUM_2 (0 << 28) #define TGL_EDP_PSR2_BLOCK_COUNT_NUM_3 (1 << 28) #define EDP_Y_COORDINATE_VALID (1 << 26) /* GLK and CNL+ */ @@ -4630,17 +4630,23 @@ enum { #define PSR2_SU_STATUS_MASK(frame) (0x3ff << PSR2_SU_STATUS_SHIFT(frame)) #define PSR2_SU_STATUS_FRAMES 8 -#define _PSR2_MAN_TRK_CTL_A 0x60910 -#define _PSR2_MAN_TRK_CTL_EDP 0x6f910 -#define PSR2_MAN_TRK_CTL(tran) _MMIO_TRANS2(tran, _PSR2_MAN_TRK_CTL_A) -#define PSR2_MAN_TRK_CTL_ENABLE REG_BIT(31) -#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(30, 21) -#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) +#define _PSR2_MAN_TRK_CTL_A 0x60910 +#define _PSR2_MAN_TRK_CTL_EDP 0x6f910 +#define PSR2_MAN_TRK_CTL(tran) _MMIO_TRANS2(tran, _PSR2_MAN_TRK_CTL_A) +#define PSR2_MAN_TRK_CTL_ENABLE REG_BIT(31) +#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(30, 21) +#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) #define PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK REG_GENMASK(20, 11) #define PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val) -#define PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(3) -#define PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(2) -#define PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE REG_BIT(1) +#define PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(3) +#define PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(2) +#define PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE REG_BIT(1) +#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(28, 16) +#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) +#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK REG_GENMASK(12, 0) +#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val) REG_FIELD_PREP(ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val) +#define ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(14) +#define ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(13) /* Icelake DSC Rate Control Range Parameter Registers */ #define DSCA_RC_RANGE_PARAMETERS_0 _MMIO(0x6B240)