diff mbox series

[4/8] drm/i915/dpio: Introdude bxt_ddi_phy_rmw_grp()

Message ID 20240412175818.29217-5-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915: BXT/GLK per-lane vswing and PHY reg cleanup | expand

Commit Message

Ville Syrjälä April 12, 2024, 5:58 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

Add a helper to do the "read from one per-lane register
and write to the group register" rmw cycle.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 59 ++++++++++++-------
 1 file changed, 38 insertions(+), 21 deletions(-)

Comments

Jani Nikula April 15, 2024, 12:36 p.m. UTC | #1
On Fri, 12 Apr 2024, Ville Syrjala <ville.syrjala@linux.intel.com> wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> Add a helper to do the "read from one per-lane register
> and write to the group register" rmw cycle.

This doesn't turn out to be such a useful helper after going per lane,
but there'll still be two users. It's fine.
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index a793a872dfa3..3d1295da1106 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -270,6 +270,24 @@  void bxt_port_to_phy_channel(struct drm_i915_private *dev_priv, enum port port,
 	*ch = DPIO_CH0;
 }
 
+/*
+ * Like intel_de_rmw() but reads from a single per-lane register and
+ * writes to the group register to write the same value to all the lanes.
+ */
+static u32 bxt_ddi_phy_rmw_grp(struct drm_i915_private *i915,
+			       i915_reg_t reg_single,
+			       i915_reg_t reg_group,
+			       u32 clear, u32 set)
+{
+	u32 old, val;
+
+	old = intel_de_read(i915, reg_single);
+	val = (old & ~clear) | set;
+	intel_de_write(i915, reg_group, val);
+
+	return old;
+}
+
 void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder,
 				   const struct intel_crtc_state *crtc_state)
 {
@@ -291,35 +309,34 @@  void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder,
 	 * While we write to the group register to program all lanes at once we
 	 * can read only lane registers and we pick lanes 0/1 for that.
 	 */
-	val = intel_de_read(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch));
-	val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
-	intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
+	bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch),
+			    BXT_PORT_PCS_DW10_GRP(phy, ch),
+			    TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT, 0);
 
-	val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, 0));
-	val &= ~(MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK);
-	val |= MARGIN_000(trans->entries[level].bxt.margin) |
-		UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale);
-	intel_de_write(dev_priv, BXT_PORT_TX_DW2_GRP(phy, ch), val);
+	bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, 0),
+			    BXT_PORT_TX_DW2_GRP(phy, ch),
+			    MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK,
+			    MARGIN_000(trans->entries[level].bxt.margin) |
+			    UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale));
+
+	bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0),
+			    BXT_PORT_TX_DW3_GRP(phy, ch),
+			    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));
-	val &= ~SCALE_DCOMP_METHOD;
-	if (trans->entries[level].bxt.enable)
-		val |= SCALE_DCOMP_METHOD;
-
 	if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
 		drm_err(&dev_priv->drm,
 			"Disabled scaling while ouniqetrangenmethod was set");
 
-	intel_de_write(dev_priv, BXT_PORT_TX_DW3_GRP(phy, ch), val);
+	bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, 0),
+			    BXT_PORT_TX_DW4_GRP(phy, ch), DE_EMPHASIS_MASK,
+			    DE_EMPHASIS(trans->entries[level].bxt.deemphasis));
 
-	val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, 0));
-	val &= ~DE_EMPHASIS_MASK;
-	val |= DE_EMPHASIS(trans->entries[level].bxt.deemphasis);
-	intel_de_write(dev_priv, BXT_PORT_TX_DW4_GRP(phy, ch), val);
-
-	val = intel_de_read(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch));
-	val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
-	intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
+	bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch),
+			    BXT_PORT_PCS_DW10_GRP(phy, ch),
+			    0, TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
 }
 
 bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,