Message ID | 20180222035519.13486-12-paulo.r.zanoni@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Em Qui, 2018-02-22 às 00:55 -0300, Paulo Zanoni escreveu: > From: Manasi Navare <manasi.d.navare@intel.com> > > This sequence is used to setup voltage swing before enabling MG PHY > DDI > as well as for changing the voltage during DisplayPort Link training. > > For ICL, there are two types of DDIs. This sequence needs to be used > for MG PHY DDI which is ports C-F. > > v5 (from Paulo): > * Checkpatch. > v4 (from Paulo): > * Fix bogus error message > * Fix copy+paste bugs (missing s/TX1/TX2/ after copy+paste) > * Use the new mask names > * Stay under 80 columns > * Add some blank lines > v3: > * Clear the regs before writing (Paulo) > v2: > * Rename to MG PHY in the function def (Jani Nikula) > * Rebase on top of new revision of other patches in series The spec has changed since this patch was written. There are two new tables to consider. Manasi, can you look into this? > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> > Cc: Jani Nikula <jani.nikula@linux.intel.com> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com> > Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> > --- > drivers/gpu/drm/i915/intel_ddi.c | 85 > +++++++++++++++++++++++++++++++++++++++- > 1 file changed, 83 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c > b/drivers/gpu/drm/i915/intel_ddi.c > index 98471b5c5f70..88a6c5107975 100644 > --- a/drivers/gpu/drm/i915/intel_ddi.c > +++ b/drivers/gpu/drm/i915/intel_ddi.c > @@ -2364,6 +2364,88 @@ static void > icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32 > I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val); > } > > +static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder > *encoder, > + u32 level) > +{ > + struct drm_i915_private *dev_priv = to_i915(encoder- > >base.dev); > + enum port port = encoder->port; > + const struct icl_mg_phy_ddi_buf_trans *ddi_translations; > + u32 n_entries, val; > + int ln; > + > + /* > + * Values are listed in voltage swing programming tables. > + * Same values for all voltage levels and port types. > + */ > + n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations); > + ddi_translations = icl_mg_phy_ddi_translations; > + /* The table does not have values for level 3 and level 9. > */ > + if (level >= n_entries || level == 3 || level == 9) { > + DRM_DEBUG_KMS("DDI translation not found for level > %d. Using %d instead.", > + level, n_entries - 2); > + level = n_entries - 2; > + } > + > + /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */ > + for (ln = 0; ln < 2; ln++) { > + val = I915_READ(ICL_PORT_MG_TX1_LINK_PARAMS(port, > ln)); > + val &= ~CRI_USE_FS32; > + I915_WRITE(ICL_PORT_MG_TX1_LINK_PARAMS(port, ln), > val); > + > + val = I915_READ(ICL_PORT_MG_TX2_LINK_PARAMS(port, > ln)); > + val &= ~CRI_USE_FS32; > + I915_WRITE(ICL_PORT_MG_TX2_LINK_PARAMS(port, ln), > val); > + } > + > + /* Program MG_TX_SWINGCTRL with values from vswing table */ > + for (ln = 0; ln < 2; ln++) { > + val = I915_READ(ICL_PORT_MG_TX1_SWINGCTRL(port, > ln)); > + val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK; > + val |= CRI_TXDEEMPH_OVERRIDE_17_12( > + ddi_translations[level].cri_txdeemph_overrid > e_17_12); > + I915_WRITE(ICL_PORT_MG_TX1_SWINGCTRL(port, ln), > val); > + > + val = I915_READ(ICL_PORT_MG_TX2_SWINGCTRL(port, > ln)); > + val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK; > + val |= CRI_TXDEEMPH_OVERRIDE_17_12( > + ddi_translations[level].cri_txdeemph_overrid > e_17_12); > + I915_WRITE(ICL_PORT_MG_TX2_SWINGCTRL(port, ln), > val); > + } > + > + /* Program MG_TX_DRVCTRL with values from vswing table */ > + for (ln = 0; ln < 2; ln++) { > + val = I915_READ(ICL_PORT_MG_TX1_DRVCTRL(port, ln)); > + val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK | > + CRI_TXDEEMPH_OVERRIDE_5_0_MASK); > + val |= CRI_TXDEEMPH_OVERRIDE_5_0( > + ddi_translations[level].cri_txdeemph_overrid > e_5_0) | > + CRI_TXDEEMPH_OVERRIDE_11_6( > + ddi_translations[level].cri_txdeemph_overrid > e_11_6) | > + CRI_TXDEEMPH_OVERRIDE_EN; > + I915_WRITE(ICL_PORT_MG_TX1_DRVCTRL(port, ln), val); > + > + val = I915_READ(ICL_PORT_MG_TX2_DRVCTRL(port, ln)); > + val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK | > + CRI_TXDEEMPH_OVERRIDE_5_0_MASK); > + val |= CRI_TXDEEMPH_OVERRIDE_5_0( > + ddi_translations[level].cri_txdeemph_overrid > e_5_0) | > + CRI_TXDEEMPH_OVERRIDE_11_6( > + ddi_translations[level].cri_txdeemph_overrid > e_11_6) | > + CRI_TXDEEMPH_OVERRIDE_EN; > + I915_WRITE(ICL_PORT_MG_TX2_DRVCTRL(port, ln), val); > + } > + /* Program MG_TX_PISO_READLOAD with values from vswing table > */ > + for (ln = 0; ln < 2; ln++) { > + val = I915_READ(ICL_PORT_MG_TX1_PISO_READLOAD(port, > ln)); > + val |= CRI_CALCINIT; > + I915_WRITE(ICL_PORT_MG_TX1_PISO_READLOAD(port, ln), > val); > + > + val = I915_READ(ICL_PORT_MG_TX2_PISO_READLOAD(port, > ln)); > + val |= CRI_CALCINIT; > + I915_WRITE(ICL_PORT_MG_TX2_PISO_READLOAD(port, ln), > val); > + } > +} > + > static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, > u32 level) > { > enum port port = encoder->port; > @@ -2371,8 +2453,7 @@ static void icl_ddi_vswing_sequence(struct > intel_encoder *encoder, u32 level) > if (port == PORT_A || port == PORT_B) > icl_combo_phy_ddi_vswing_sequence(encoder, level); > else > - /* Not Implemented Yet */ > - WARN_ON(1); > + icl_mg_phy_ddi_vswing_sequence(encoder, level); > } > > static uint32_t translate_signal_level(int signal_levels)
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 98471b5c5f70..88a6c5107975 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -2364,6 +2364,88 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder, u32 I915_WRITE(ICL_PORT_TX_DW5_GRP(port), val); } +static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder, + u32 level) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum port port = encoder->port; + const struct icl_mg_phy_ddi_buf_trans *ddi_translations; + u32 n_entries, val; + int ln; + + /* + * Values are listed in voltage swing programming tables. + * Same values for all voltage levels and port types. + */ + n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations); + ddi_translations = icl_mg_phy_ddi_translations; + /* The table does not have values for level 3 and level 9. */ + if (level >= n_entries || level == 3 || level == 9) { + DRM_DEBUG_KMS("DDI translation not found for level %d. Using %d instead.", + level, n_entries - 2); + level = n_entries - 2; + } + + /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */ + for (ln = 0; ln < 2; ln++) { + val = I915_READ(ICL_PORT_MG_TX1_LINK_PARAMS(port, ln)); + val &= ~CRI_USE_FS32; + I915_WRITE(ICL_PORT_MG_TX1_LINK_PARAMS(port, ln), val); + + val = I915_READ(ICL_PORT_MG_TX2_LINK_PARAMS(port, ln)); + val &= ~CRI_USE_FS32; + I915_WRITE(ICL_PORT_MG_TX2_LINK_PARAMS(port, ln), val); + } + + /* Program MG_TX_SWINGCTRL with values from vswing table */ + for (ln = 0; ln < 2; ln++) { + val = I915_READ(ICL_PORT_MG_TX1_SWINGCTRL(port, ln)); + val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK; + val |= CRI_TXDEEMPH_OVERRIDE_17_12( + ddi_translations[level].cri_txdeemph_override_17_12); + I915_WRITE(ICL_PORT_MG_TX1_SWINGCTRL(port, ln), val); + + val = I915_READ(ICL_PORT_MG_TX2_SWINGCTRL(port, ln)); + val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK; + val |= CRI_TXDEEMPH_OVERRIDE_17_12( + ddi_translations[level].cri_txdeemph_override_17_12); + I915_WRITE(ICL_PORT_MG_TX2_SWINGCTRL(port, ln), val); + } + + /* Program MG_TX_DRVCTRL with values from vswing table */ + for (ln = 0; ln < 2; ln++) { + val = I915_READ(ICL_PORT_MG_TX1_DRVCTRL(port, ln)); + val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK | + CRI_TXDEEMPH_OVERRIDE_5_0_MASK); + val |= CRI_TXDEEMPH_OVERRIDE_5_0( + ddi_translations[level].cri_txdeemph_override_5_0) | + CRI_TXDEEMPH_OVERRIDE_11_6( + ddi_translations[level].cri_txdeemph_override_11_6) | + CRI_TXDEEMPH_OVERRIDE_EN; + I915_WRITE(ICL_PORT_MG_TX1_DRVCTRL(port, ln), val); + + val = I915_READ(ICL_PORT_MG_TX2_DRVCTRL(port, ln)); + val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK | + CRI_TXDEEMPH_OVERRIDE_5_0_MASK); + val |= CRI_TXDEEMPH_OVERRIDE_5_0( + ddi_translations[level].cri_txdeemph_override_5_0) | + CRI_TXDEEMPH_OVERRIDE_11_6( + ddi_translations[level].cri_txdeemph_override_11_6) | + CRI_TXDEEMPH_OVERRIDE_EN; + I915_WRITE(ICL_PORT_MG_TX2_DRVCTRL(port, ln), val); + } + /* Program MG_TX_PISO_READLOAD with values from vswing table */ + for (ln = 0; ln < 2; ln++) { + val = I915_READ(ICL_PORT_MG_TX1_PISO_READLOAD(port, ln)); + val |= CRI_CALCINIT; + I915_WRITE(ICL_PORT_MG_TX1_PISO_READLOAD(port, ln), val); + + val = I915_READ(ICL_PORT_MG_TX2_PISO_READLOAD(port, ln)); + val |= CRI_CALCINIT; + I915_WRITE(ICL_PORT_MG_TX2_PISO_READLOAD(port, ln), val); + } +} + static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level) { enum port port = encoder->port; @@ -2371,8 +2453,7 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder, u32 level) if (port == PORT_A || port == PORT_B) icl_combo_phy_ddi_vswing_sequence(encoder, level); else - /* Not Implemented Yet */ - WARN_ON(1); + icl_mg_phy_ddi_vswing_sequence(encoder, level); } static uint32_t translate_signal_level(int signal_levels)