[PATCH v4 phy 05/16] phy: lynx-28g: don't concatenate lynx_28g_lane_rmw() argument "reg" with "val" and "mask"

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

The last step in having lynx_28g_lane_rmw() arguments that fully point
to their definitions is the removal of the current concatenation logic,
by which e.g. "LNaTGCR0, N_RATE_QUARTER, N_RATE_MSK" is expanded to
"LNaTGCR0, LNaTGCR0_N_RATE_QUARTER, LNaTGCR0_N_RATE_MSK".

There are pros and cons to the above. An advantage is the impossibility
to mix up fields of one register with fields of another. For example
both LNaTGCR0 and LNaRGCR0 contain an N_RATE_QUARTER field (one for the
lane RX direction, one for the lane TX).

But the two notable disadvantages are:

1. the impossibility to write expressions such as logical OR between
multiple fields. Practically, this forces us to perform more accesses
to hardware registers than would otherwise be needed. See the LNaGCR0
access for example.

2. the necessity to invent fields that don't exist, like SGMIIaCR1_SGPCS_DIS,
in order to clear SGMIIaCR1_SGPCS_EN (the real field name). This is
confusing, because sometimes, fields that end with _DIS really exist,
and it's best to not invent new field names.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v4: none

drivers/phy/freescale/phy-fsl-lynx-28g.c | 60 +++++++++++++++---------
1 file changed, 38 insertions(+), 22 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index c9bdd11cc48a..a5a76e0dff89 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -103,7 +103,6 @@

#define SGMIIaCR1(lane) (0x1804 + (lane) * 0x10)
#define SGMIIaCR1_SGPCS_EN BIT(11)
-#define SGMIIaCR1_SGPCS_DIS 0x0
#define SGMIIaCR1_SGPCS_MSK BIT(11)

struct lynx_28g_priv;
@@ -150,8 +149,7 @@ static void lynx_28g_rmw(struct lynx_28g_priv *priv, unsigned long off,
}

#define lynx_28g_lane_rmw(lane, reg, val, mask) \
- lynx_28g_rmw((lane)->priv, reg(lane->id), \
- reg##_##val, reg##_##mask)
+ 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_pll_read(pll, reg) \
@@ -205,8 +203,12 @@ static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane,
switch (intf) {
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
- lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_QUARTER, N_RATE_MSK);
- lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_QUARTER, N_RATE_MSK);
+ lynx_28g_lane_rmw(lane, LNaTGCR0,
+ LNaTGCR0_N_RATE_QUARTER,
+ LNaTGCR0_N_RATE_MSK);
+ lynx_28g_lane_rmw(lane, LNaRGCR0,
+ LNaRGCR0_N_RATE_QUARTER,
+ LNaRGCR0_N_RATE_MSK);
break;
default:
break;
@@ -216,8 +218,10 @@ static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane,
switch (intf) {
case PHY_INTERFACE_MODE_10GBASER:
case PHY_INTERFACE_MODE_USXGMII:
- lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_FULL, N_RATE_MSK);
- lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_FULL, N_RATE_MSK);
+ lynx_28g_lane_rmw(lane, LNaTGCR0, LNaTGCR0_N_RATE_FULL,
+ LNaTGCR0_N_RATE_MSK);
+ lynx_28g_lane_rmw(lane, LNaRGCR0, LNaRGCR0_N_RATE_FULL,
+ LNaRGCR0_N_RATE_MSK);
break;
default:
break;
@@ -232,11 +236,15 @@ static void lynx_28g_lane_set_pll(struct lynx_28g_lane *lane,
struct lynx_28g_pll *pll)
{
if (pll->id == 0) {
- lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLF, USE_PLL_MSK);
- lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLF, USE_PLL_MSK);
+ lynx_28g_lane_rmw(lane, LNaTGCR0, LNaTGCR0_USE_PLLF,
+ LNaTGCR0_USE_PLL_MSK);
+ lynx_28g_lane_rmw(lane, LNaRGCR0, LNaRGCR0_USE_PLLF,
+ LNaRGCR0_USE_PLL_MSK);
} else {
- lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLS, USE_PLL_MSK);
- lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLS, USE_PLL_MSK);
+ lynx_28g_lane_rmw(lane, LNaTGCR0, LNaTGCR0_USE_PLLS,
+ LNaTGCR0_USE_PLL_MSK);
+ lynx_28g_lane_rmw(lane, LNaRGCR0, LNaRGCR0_USE_PLLS,
+ LNaRGCR0_USE_PLL_MSK);
}
}

@@ -277,8 +285,9 @@ static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane)
GENMASK(3, 0) << lane_offset);

/* Setup the protocol select and SerDes parallel interface width */
- lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK);
- lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK);
+ lynx_28g_lane_rmw(lane, LNaGCR0,
+ LNaGCR0_PROTO_SEL_SGMII | LNaGCR0_IF_WIDTH_10_BIT,
+ LNaGCR0_PROTO_SEL_MSK | LNaGCR0_IF_WIDTH_MSK);

/* Find the PLL that works with this interface type */
pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII);
@@ -292,7 +301,8 @@ static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane)
lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_SGMII);

/* Enable the SGMII PCS */
- lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_EN, SGPCS_MSK);
+ lynx_28g_lane_rmw(lane, SGMIIaCR1, SGMIIaCR1_SGPCS_EN,
+ SGMIIaCR1_SGPCS_MSK);

/* Configure the appropriate equalization parameters for the protocol */
iowrite32(0x00808006, priv->base + LNaTECR0(lane->id));
@@ -317,8 +327,9 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
GENMASK(3, 0) << lane_offset);

/* Setup the protocol select and SerDes parallel interface width */
- lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK);
- lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK);
+ lynx_28g_lane_rmw(lane, LNaGCR0,
+ LNaGCR0_PROTO_SEL_XFI | LNaGCR0_IF_WIDTH_20_BIT,
+ LNaGCR0_PROTO_SEL_MSK | LNaGCR0_IF_WIDTH_MSK);

/* Find the PLL that works with this interface type */
pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER);
@@ -332,7 +343,7 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_10GBASER);

/* Disable the SGMII PCS */
- lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_DIS, SGPCS_MSK);
+ lynx_28g_lane_rmw(lane, SGMIIaCR1, 0, SGMIIaCR1_SGPCS_MSK);

/* Configure the appropriate equalization parameters for the protocol */
iowrite32(0x10808307, priv->base + LNaTECR0(lane->id));
@@ -352,8 +363,10 @@ static int lynx_28g_power_off(struct phy *phy)
return 0;

/* Issue a halt request */
- lynx_28g_lane_rmw(lane, LNaTRSTCTL, HLT_REQ, HLT_REQ);
- lynx_28g_lane_rmw(lane, LNaRRSTCTL, HLT_REQ, HLT_REQ);
+ lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_HLT_REQ,
+ LNaTRSTCTL_HLT_REQ);
+ lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_HLT_REQ,
+ LNaRRSTCTL_HLT_REQ);

/* Wait until the halting process is complete */
do {
@@ -376,8 +389,10 @@ static int lynx_28g_power_on(struct phy *phy)
return 0;

/* Issue a reset request on the lane */
- lynx_28g_lane_rmw(lane, LNaTRSTCTL, RST_REQ, RST_REQ);
- lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ);
+ lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_RST_REQ,
+ LNaTRSTCTL_RST_REQ);
+ lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ,
+ LNaRRSTCTL_RST_REQ);

/* Wait until the reset sequence is completed */
do {
@@ -537,7 +552,8 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work)

rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
if (!(rrstctl & LNaRRSTCTL_CDR_LOCK)) {
- lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ);
+ lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ,
+ LNaRRSTCTL_RST_REQ);
do {
rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL);
} while (!(rrstctl & LNaRRSTCTL_RST_DONE));