drm/i915/dpio: Program bxt/glk PHY TX registers per-lane
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 12 Apr 2024 17:58:17 +0000 (20:58 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 19 Apr 2024 16:46:54 +0000 (19:46 +0300)
Program each bxt/glk PHY TX lane with its own settings
instead of blasting them all with the same stuff via
group access.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240412175818.29217-8-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_dpio_phy.c

index 77597edb391c21bd4b3cba8c07ff014508ba4618..c72b76b61dff8ac0c8ed8960dab6d558acf04d96 100644 (file)
@@ -292,12 +292,10 @@ void bxt_dpio_phy_set_signal_levels(struct intel_encoder *encoder,
                                    const struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       int level = intel_ddi_level(encoder, crtc_state, 0);
        const struct intel_ddi_buf_trans *trans;
        enum dpio_channel ch;
        enum dpio_phy phy;
-       int n_entries;
-       u32 val;
+       int lane, n_entries;
 
        trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
        if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans))
@@ -313,26 +311,37 @@ void bxt_dpio_phy_set_signal_levels(struct intel_encoder *encoder,
                             BXT_PORT_PCS_DW10_GRP(phy, ch),
                             TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT, 0);
 
-       bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, 0),
-                            BXT_PORT_TX_DW2_GRP(phy, ch),
+       for (lane = 0; lane < crtc_state->lane_count; lane++) {
+               int level = intel_ddi_level(encoder, crtc_state, lane);
+
+               intel_de_rmw(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, lane),
                             MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK,
                             MARGIN_000(trans->entries[level].bxt.margin) |
                             UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale));
+       }
+
+       for (lane = 0; lane < crtc_state->lane_count; lane++) {
+               int level = intel_ddi_level(encoder, crtc_state, lane);
+               u32 val;
 
-       bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0),
-                            BXT_PORT_TX_DW3_GRP(phy, ch),
+               intel_de_rmw(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, lane),
                             SCALE_DCOMP_METHOD,
                             trans->entries[level].bxt.enable ?
                             SCALE_DCOMP_METHOD : 0);
 
-       val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0));
-       if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
-               drm_err(&dev_priv->drm,
-                       "Disabled scaling while ouniqetrangenmethod was set");
+               val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, lane));
+               if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
+                       drm_err(&dev_priv->drm,
+                               "Disabled scaling while ouniqetrangenmethod was set");
+       }
+
+       for (lane = 0; lane < crtc_state->lane_count; lane++) {
+               int level = intel_ddi_level(encoder, crtc_state, lane);
 
-       bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, 0),
-                            BXT_PORT_TX_DW4_GRP(phy, ch), DE_EMPHASIS_MASK,
+               intel_de_rmw(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, lane),
+                            DE_EMPHASIS_MASK,
                             DE_EMPHASIS(trans->entries[level].bxt.deemphasis));
+       }
 
        bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch),
                             BXT_PORT_PCS_DW10_GRP(phy, ch),