On Fri, 2022-02-18 at 14:31 +0200, Imre Deak wrote: > Add display workaround # 1309179469 , which fixes a PHY hang when > switching from TBT mode to DP-alt/legacy mode. The workaround also > requires an IFWI/PHY firmware change, before that this change has no > effect (the DKL_PCS_DW5/SOFTRESET flag is always cleared). > > HSDES: 18018237866 > HSDES: 16014473319 > > v2: Add the WA comment and make the WA func name more accurate. > Reviewed-by: José Roberto de Souza <jose.souza@xxxxxxxxx> > Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> > --- > drivers/gpu/drm/i915/display/intel_ddi.c | 20 +++++++++++++++++++- > drivers/gpu/drm/i915/i915_reg.h | 6 ++++++ > 2 files changed, 25 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c > index 9dee12986991c..e6e26e4cd87d7 100644 > --- a/drivers/gpu/drm/i915/display/intel_ddi.c > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c > @@ -3101,10 +3101,24 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, > crtc_state->lane_lat_optim_mask); > } > > +/* Display WA #1309179469: adl-p */ > +static void adlp_tbt_to_dp_alt_legacy_switch_wa(struct intel_encoder *encoder) > +{ > + struct drm_i915_private *i915 = to_i915(encoder->base.dev); > + enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); > + int ln; > + > + for (ln = 0; ln < 2; ln++) { > + intel_de_write(i915, HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, ln)); > + intel_de_rmw(i915, DKL_PCS_DW5(tc_port), DKL_PCS_DW5_CORE_SOFTRESET, 0); > + } > +} > + > static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, > const struct intel_crtc_state *crtc_state) > { > - struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; > + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > + struct intel_encoder *encoder = &dig_port->base; > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > enum port port = encoder->port; > u32 dp_tp_ctl, ddi_buf_ctl; > @@ -3140,6 +3154,10 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, > intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); > intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); > > + if (IS_ALDERLAKE_P(dev_priv) && > + (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port))) > + adlp_tbt_to_dp_alt_legacy_switch_wa(encoder); > + > intel_dp->DP |= DDI_BUF_CTL_ENABLE; > intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); > intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 26b496fa31972..8abbdc62b981f 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -7907,6 +7907,12 @@ enum skl_power_gate { > #define _DKL_PHY6_BASE 0x16D000 > > /* DEKEL PHY MMIO Address = Phy base + (internal address & ~index_mask) */ > +#define _DKL_PCS_DW5 0x14 > +#define DKL_PCS_DW5(tc_port) _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \ > + _DKL_PHY2_BASE) + \ > + _DKL_PCS_DW5) > +#define DKL_PCS_DW5_CORE_SOFTRESET REG_BIT(11) > + > #define _DKL_PLL_DIV0 0x200 > #define DKL_PLL_DIV0_INTEG_COEFF(x) ((x) << 16) > #define DKL_PLL_DIV0_INTEG_COEFF_MASK (0x1F << 16)