From 55223c3bedcffcb81400db7f1ed1f207d523eaba Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Fri, 18 Feb 2022 14:26:11 +0200 Subject: [PATCH] drm/i915/adlp: Add TypeC PHY TBT->DP-alt/legacy mode switch workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Imre Deak Reviewed-by: José Roberto de Souza Link: https://patchwork.freedesktop.org/patch/msgid/20220218122611.767974-1-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 19 ++++++++++++++++++- drivers/gpu/drm/i915/i915_reg.h | 6 ++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 9dee12986991..e4260806c2a4 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3101,10 +3101,23 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, crtc_state->lane_lat_optim_mask); } +static void adlp_tbt_to_dp_alt_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 +3153,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_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 8e1b469a4cd1..b9783584841b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7914,6 +7914,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_AFC_STARTUP_MASK REG_GENMASK(27, 25) #define DKL_PLL_DIV0_AFC_STARTUP(val) REG_FIELD_PREP(DKL_PLL_DIV0_AFC_STARTUP_MASK, (val))