[PATCH v4 phy 07/16] phy: lynx-28g: convert iowrite32() calls with magic values to macros

Vladimir Oltean
2025-11-10T09:23:12Z

The driver will need to become more careful with the values it writes to
the TX and RX equalization registers. As a preliminary step, convert the
magic numbers to macros defining the register field meanings.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v2->v4: none
v1->v2: remove duplicate LNaRSCCR0_SMP_AUTOZ_D1F definition

drivers/phy/freescale/phy-fsl-lynx-28g.c | 102 ++++++++++++++++++++---
1 file changed, 90 insertions(+), 12 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 4c699829026c..3b19b7d22b6a 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -70,6 +70,12 @@
#define LNaTGCR0_N_RATE_QUARTER 0x2

#define LNaTECR0(lane) (0x800 + (lane) * 0x100 + 0x30)
+#define LNaTECR0_EQ_TYPE GENMASK(30, 28)
+#define LNaTECR0_EQ_SGN_PREQ BIT(23)
+#define LNaTECR0_EQ_PREQ GENMASK(19, 16)
+#define LNaTECR0_EQ_SGN_POST1Q BIT(15)
+#define LNaTECR0_EQ_POST1Q GENMASK(12, 8)
+#define LNaTECR0_EQ_AMP_RED GENMASK(5, 0)

/* Lane a Rx Reset Control Register */
#define LNaRRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x40)
@@ -89,12 +95,56 @@
#define LNaRGCR0_N_RATE_QUARTER 0x2

#define LNaRGCR1(lane) (0x800 + (lane) * 0x100 + 0x48)
+#define LNaRGCR1_RX_ORD_ELECIDLE BIT(31)
+#define LNaRGCR1_DATA_LOST_FLT BIT(30)
+#define LNaRGCR1_DATA_LOST BIT(29)
+#define LNaRGCR1_IDLE_CONFIG BIT(28)
+#define LNaRGCR1_ENTER_IDLE_FLT_SEL GENMASK(26, 24)
+#define LNaRGCR1_EXIT_IDLE_FLT_SEL GENMASK(22, 20)
+#define LNaRGCR1_DATA_LOST_TH_SEL GENMASK(18, 16)
+#define LNaRGCR1_EXT_REC_CLK_SEL GENMASK(10, 8)
+#define LNaRGCR1_WAKE_TX_DIS BIT(5)
+#define LNaRGCR1_PHY_RDY BIT(4)
+#define LNaRGCR1_CHANGE_RX_CLK BIT(3)
+#define LNaRGCR1_PWR_MGT GENMASK(2, 0)

#define LNaRECR0(lane) (0x800 + (lane) * 0x100 + 0x50)
+#define LNaRECR0_EQ_GAINK2_HF_OV_EN BIT(31)
+#define LNaRECR0_EQ_GAINK2_HF_OV GENMASK(28, 24)
+#define LNaRECR0_EQ_GAINK3_MF_OV_EN BIT(23)
+#define LNaRECR0_EQ_GAINK3_MF_OV GENMASK(20, 16)
+#define LNaRECR0_EQ_GAINK4_LF_OV_EN BIT(7)
+#define LNaRECR0_EQ_GAINK4_LF_DIS BIT(6)
+#define LNaRECR0_EQ_GAINK4_LF_OV GENMASK(4, 0)
+
#define LNaRECR1(lane) (0x800 + (lane) * 0x100 + 0x54)
+#define LNaRECR1_EQ_BLW_OV_EN BIT(31)
+#define LNaRECR1_EQ_BLW_OV GENMASK(28, 24)
+#define LNaRECR1_EQ_OFFSET_OV_EN BIT(23)
+#define LNaRECR1_EQ_OFFSET_OV GENMASK(21, 16)
+
#define LNaRECR2(lane) (0x800 + (lane) * 0x100 + 0x58)
+#define LNaRECR2_EQ_OFFSET_RNG_DBL BIT(31)
+#define LNaRECR2_EQ_BOOST GENMASK(29, 28)
+#define LNaRECR2_EQ_BLW_SEL GENMASK(25, 24)
+#define LNaRECR2_EQ_ZERO GENMASK(17, 16)
+#define LNaRECR2_EQ_IND GENMASK(13, 12)
+#define LNaRECR2_EQ_BIN_DATA_AVG_TC GENMASK(5, 4)
+#define LNaRECR2_SPARE_IN GENMASK(1, 0)

#define LNaRSCCR0(lane) (0x800 + (lane) * 0x100 + 0x74)
+#define LNaRSCCR0_SMP_OFF_EN BIT(31)
+#define LNaRSCCR0_SMP_OFF_OV_EN BIT(30)
+#define LNaRSCCR0_SMP_MAN_OFF_EN BIT(29)
+#define LNaRSCCR0_SMP_OFF_RNG_OV_EN BIT(27)
+#define LNaRSCCR0_SMP_OFF_RNG_4X_OV BIT(25)
+#define LNaRSCCR0_SMP_OFF_RNG_2X_OV BIT(24)
+#define LNaRSCCR0_SMP_AUTOZ_PD BIT(23)
+#define LNaRSCCR0_SMP_AUTOZ_CTRL GENMASK(19, 16)
+#define LNaRSCCR0_SMP_AUTOZ_D1R GENMASK(13, 12)
+#define LNaRSCCR0_SMP_AUTOZ_D1F GENMASK(9, 8)
+#define LNaRSCCR0_SMP_AUTOZ_EG1R GENMASK(5, 4)
+#define LNaRSCCR0_SMP_AUTOZ_EG1F GENMASK(1, 0)

#define LNaPSS(lane) (0x1000 + (lane) * 0x4)
#define LNaPSS_TYPE GENMASK(30, 24)
@@ -104,6 +154,12 @@
#define SGMIIaCR1(lane) (0x1804 + (lane) * 0x10)
#define SGMIIaCR1_SGPCS_EN BIT(11)

+enum lynx_28g_eq_type {
+ EQ_TYPE_NO_EQ = 0,
+ EQ_TYPE_2TAP = 1,
+ EQ_TYPE_3TAP = 2,
+};
+
struct lynx_28g_priv;

struct lynx_28g_pll {
@@ -151,6 +207,8 @@ static void lynx_28g_rmw(struct lynx_28g_priv *priv, unsigned long off,
lynx_28g_rmw((lane)->priv, reg(lane->id), val, mask)
#define lynx_28g_lane_read(lane, reg) \
ioread32((lane)->priv->base + reg((lane)->id))
+#define lynx_28g_lane_write(lane, reg, val) \
+ iowrite32(val, (lane)->priv->base + reg((lane)->id))
#define lynx_28g_pll_read(pll, reg) \
ioread32((pll)->priv->base + reg((pll)->id))

@@ -311,12 +369,22 @@ static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane)
SGMIIaCR1_SGPCS_EN);

/* Configure the appropriate equalization parameters for the protocol */
- iowrite32(0x00808006, priv->base + LNaTECR0(lane->id));
- iowrite32(0x04310000, priv->base + LNaRGCR1(lane->id));
- iowrite32(0x9f800000, priv->base + LNaRECR0(lane->id));
- iowrite32(0x001f0000, priv->base + LNaRECR1(lane->id));
- iowrite32(0x00000000, priv->base + LNaRECR2(lane->id));
- iowrite32(0x00000000, priv->base + LNaRSCCR0(lane->id));
+ lynx_28g_lane_write(lane, LNaTECR0,
+ LNaTECR0_EQ_SGN_PREQ | LNaTECR0_EQ_SGN_POST1Q |
+ FIELD_PREP(LNaTECR0_EQ_AMP_RED, 6));
+ lynx_28g_lane_write(lane, LNaRGCR1,
+ FIELD_PREP(LNaRGCR1_ENTER_IDLE_FLT_SEL, 4) |
+ FIELD_PREP(LNaRGCR1_EXIT_IDLE_FLT_SEL, 3) |
+ LNaRGCR1_DATA_LOST_FLT);
+ lynx_28g_lane_write(lane, LNaRECR0,
+ LNaRECR0_EQ_GAINK2_HF_OV_EN |
+ FIELD_PREP(LNaRECR0_EQ_GAINK2_HF_OV, 31) |
+ LNaRECR0_EQ_GAINK3_MF_OV_EN |
+ FIELD_PREP(LNaRECR0_EQ_GAINK3_MF_OV, 0));
+ lynx_28g_lane_write(lane, LNaRECR1,
+ FIELD_PREP(LNaRECR1_EQ_OFFSET_OV, 31));
+ lynx_28g_lane_write(lane, LNaRECR2, 0);
+ lynx_28g_lane_write(lane, LNaRSCCR0, 0);
}

static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
@@ -353,12 +421,22 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
lynx_28g_lane_rmw(lane, SGMIIaCR1, 0, SGMIIaCR1_SGPCS_EN);

/* Configure the appropriate equalization parameters for the protocol */
- iowrite32(0x10808307, priv->base + LNaTECR0(lane->id));
- iowrite32(0x10000000, priv->base + LNaRGCR1(lane->id));
- iowrite32(0x00000000, priv->base + LNaRECR0(lane->id));
- iowrite32(0x001f0000, priv->base + LNaRECR1(lane->id));
- iowrite32(0x81000020, priv->base + LNaRECR2(lane->id));
- iowrite32(0x00002000, priv->base + LNaRSCCR0(lane->id));
+ lynx_28g_lane_write(lane, LNaTECR0,
+ FIELD_PREP(LNaTECR0_EQ_TYPE, EQ_TYPE_2TAP) |
+ LNaTECR0_EQ_SGN_PREQ |
+ FIELD_PREP(LNaTECR0_EQ_PREQ, 0) |
+ LNaTECR0_EQ_SGN_POST1Q |
+ FIELD_PREP(LNaTECR0_EQ_POST1Q, 3) |
+ FIELD_PREP(LNaTECR0_EQ_AMP_RED, 7));
+ lynx_28g_lane_write(lane, LNaRGCR1, LNaRGCR1_IDLE_CONFIG);
+ lynx_28g_lane_write(lane, LNaRECR0, 0);
+ lynx_28g_lane_write(lane, LNaRECR1, FIELD_PREP(LNaRECR1_EQ_OFFSET_OV, 31));
+ lynx_28g_lane_write(lane, LNaRECR2,
+ LNaRECR2_EQ_OFFSET_RNG_DBL |
+ FIELD_PREP(LNaRECR2_EQ_BLW_SEL, 1) |
+ FIELD_PREP(LNaRECR2_EQ_BIN_DATA_AVG_TC, 2));
+ lynx_28g_lane_write(lane, LNaRSCCR0,
+ FIELD_PREP(LNaRSCCR0_SMP_AUTOZ_D1R, 2));
}

static int lynx_28g_power_off(struct phy *phy)