drm/i915/dg2: Add vswing programming for SNPS phys
authorMatt Roper <matthew.d.roper@intel.com>
Fri, 23 Jul 2021 17:42:34 +0000 (10:42 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Thu, 29 Jul 2021 16:07:05 +0000 (09:07 -0700)
Vswing programming for SNPS PHYs is just a single step -- look up the
value that corresponds to the voltage level from a table and program it
into the SNPS_PHY_TX_EQ register.

Bspec: 53920
Cc: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210723174239.1551352-26-matthew.d.roper@intel.com
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_snps_phy.c
drivers/gpu/drm/i915/display/intel_snps_phy.h
drivers/gpu/drm/i915/i915_reg.h

index f48bc9786329db9f6af748c1feaf930ff129b9bd..3f166761a2034338b6286ac278f04bd257e47980 100644 (file)
@@ -1496,6 +1496,16 @@ static int intel_ddi_dp_level(struct intel_dp *intel_dp)
        return translate_signal_level(intel_dp, signal_levels);
 }
 
+static void
+dg2_set_signal_levels(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state)
+{
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       int level = intel_ddi_dp_level(intel_dp);
+
+       intel_snps_phy_ddi_vswing_sequence(encoder, level);
+}
+
 static void
 tgl_set_signal_levels(struct intel_dp *intel_dp,
                      const struct intel_crtc_state *crtc_state)
@@ -2563,7 +2573,10 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
         */
 
        /* 7.e Configure voltage swing and related IO settings */
-       tgl_ddi_vswing_sequence(encoder, crtc_state, level);
+       if (IS_DG2(dev_priv))
+               intel_snps_phy_ddi_vswing_sequence(encoder, level);
+       else
+               tgl_ddi_vswing_sequence(encoder, crtc_state, level);
 
        /*
         * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
@@ -3102,7 +3115,9 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
                            "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n",
                            connector->base.id, connector->name);
 
-       if (DISPLAY_VER(dev_priv) >= 12)
+       if (IS_DG2(dev_priv))
+               intel_snps_phy_ddi_vswing_sequence(encoder, U32_MAX);
+       else if (DISPLAY_VER(dev_priv) >= 12)
                tgl_ddi_vswing_sequence(encoder, crtc_state, level);
        else if (DISPLAY_VER(dev_priv) == 11)
                icl_ddi_vswing_sequence(encoder, crtc_state, level);
@@ -4084,7 +4099,9 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
        dig_port->dp.set_link_train = intel_ddi_set_link_train;
        dig_port->dp.set_idle_link_train = intel_ddi_set_idle_link_train;
 
-       if (DISPLAY_VER(dev_priv) >= 12)
+       if (IS_DG2(dev_priv))
+               dig_port->dp.set_signal_levels = dg2_set_signal_levels;
+       else if (DISPLAY_VER(dev_priv) >= 12)
                dig_port->dp.set_signal_levels = tgl_set_signal_levels;
        else if (DISPLAY_VER(dev_priv) >= 11)
                dig_port->dp.set_signal_levels = icl_set_signal_levels;
index 1317b4e94b50345a708de391c957a1e2a7e79afd..77759bda98a489a0f54311f96b26752cbb8e29a7 100644 (file)
  * since it is not handled by the shared DPLL framework as on other platforms.
  */
 
+static const u32 dg2_ddi_translations[] = {
+       /* VS 0, pre-emph 0 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 26),
+
+       /* VS 0, pre-emph 1 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 33) |
+               REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 6),
+
+       /* VS 0, pre-emph 2 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 38) |
+               REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 12),
+
+       /* VS 0, pre-emph 3 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 43) |
+               REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 19),
+
+       /* VS 1, pre-emph 0 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 39),
+
+       /* VS 1, pre-emph 1 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 44) |
+               REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 8),
+
+       /* VS 1, pre-emph 2 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 47) |
+               REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 15),
+
+       /* VS 2, pre-emph 0 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 52),
+
+       /* VS 2, pre-emph 1 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 51) |
+               REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 10),
+
+       /* VS 3, pre-emph 0 */
+       REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 62),
+};
+
+void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+                                       u32 level)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+       int n_entries, ln;
+
+       n_entries = ARRAY_SIZE(dg2_ddi_translations);
+       if (level >= n_entries)
+               level = n_entries - 1;
+
+       for (ln = 0; ln < 4; ln++)
+               intel_de_write(dev_priv, SNPS_PHY_TX_EQ(ln, phy),
+                              dg2_ddi_translations[level]);
+}
+
 /*
  * Basic DP link rates with 100 MHz reference clock.
  */
index ca4c2a25182b7c5ed98b294a0109d57806e4fff1..3ce92d424f66c2f0b459fcd249ddd922d9c867fc 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef __INTEL_SNPS_PHY_H__
 #define __INTEL_SNPS_PHY_H__
 
+#include <linux/types.h>
+
 struct intel_encoder;
 struct intel_crtc_state;
 struct intel_mpllb_state;
@@ -21,5 +23,7 @@ int intel_mpllb_calc_port_clock(struct intel_encoder *encoder,
                                const struct intel_mpllb_state *pll_state);
 
 int intel_snps_phy_check_hdmi_link_rate(int clock);
+void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+                                       u32 level);
 
 #endif /* __INTEL_SNPS_PHY_H__ */
index f82a7e24b5ccb411bdb9846a134d558d1e68928c..4b0ce34ef9bb341172bee0dd0540ecfbd68b146d 100644 (file)
@@ -2332,6 +2332,11 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
 #define SNPS_PHY_REF_CONTROL(phy)              _MMIO_SNPS(phy, 0x168188)
 #define   SNPS_PHY_REF_CONTROL_REF_RANGE       REG_GENMASK(31, 27)
 
+#define SNPS_PHY_TX_EQ(ln, phy)                        _MMIO_SNPS_LN(ln, phy, 0x168300)
+#define   SNPS_PHY_TX_EQ_MAIN                  REG_GENMASK(23, 18)
+#define   SNPS_PHY_TX_EQ_POST                  REG_GENMASK(15, 10)
+#define   SNPS_PHY_TX_EQ_PRE                   REG_GENMASK(7, 2)
+
 /* The spec defines this only for BXT PHY0, but lets assume that this
  * would exist for PHY1 too if it had a second channel.
  */