[PATCH v2 phy-next 08/15] phy: lynx-28g: make lynx_28g_pll_read_configuration() callable per PLL

From: Vladimir Oltean

Date: Fri May 29 2026 - 13:22:43 EST


In a future change, lynx_28g_pll_read_configuration() and
lynx_28g_lane_read_configuration() will be made methods of struct
lynx_info.

There is no functional reason, but lynx_28g_lane_read_configuration() is
called per lane and lynx_28g_pll_read_configuration() iterates over PLLs
internally. So the API exported by the lynx_info structure would not be
uniform. Change lynx_28g_pll_read_configuration() to also permit reading
the PLL configuration individually, and move the for loop at the call
site.

Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
---
v1->v2: fix typo in commit message (spotted by Sashiko)
---
drivers/phy/freescale/phy-fsl-lynx-28g.c | 73 ++++++++++++------------
1 file changed, 35 insertions(+), 38 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 0076de537763..25aeab478d49 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -272,7 +272,6 @@
#define lynx_28g_lane_rmw lynx_lane_rmw
#define lynx_28g_lane_read lynx_lane_read
#define lynx_28g_lane_write lynx_lane_write
-#define lynx_28g_pll_read lynx_pll_read

#define lynx_28g_priv lynx_priv
#define lynx_28g_lane lynx_lane
@@ -1051,49 +1050,41 @@ static const struct phy_ops lynx_28g_ops = {
.owner = THIS_MODULE,
};

-static void lynx_28g_pll_read_configuration(struct lynx_28g_priv *priv)
+static void lynx_28g_pll_read_configuration(struct lynx_pll *pll)
{
- struct lynx_28g_pll *pll;
u32 val;
- int i;

- for (i = 0; i < LYNX_28G_NUM_PLL; i++) {
- pll = &priv->pll[i];
- pll->priv = priv;
- pll->id = i;
+ val = lynx_pll_read(pll, PLLnRSTCTL);
+ pll->enabled = !(val & PLLnRSTCTL_DIS);
+ pll->locked = !!(val & PLLnRSTCTL_LOCK);

- val = lynx_28g_pll_read(pll, PLLnRSTCTL);
- pll->enabled = !(val & PLLnRSTCTL_DIS);
- pll->locked = !!(val & PLLnRSTCTL_LOCK);
+ val = lynx_pll_read(pll, PLLnCR0);
+ pll->refclk_sel = FIELD_GET(PLLnCR0_REFCLK_SEL, val);

- val = lynx_28g_pll_read(pll, PLLnCR0);
- pll->refclk_sel = FIELD_GET(PLLnCR0_REFCLK_SEL, val);
+ val = lynx_pll_read(pll, PLLnCR1);
+ pll->frate_sel = FIELD_GET(PLLnCR1_FRATE_SEL, val);

- val = lynx_28g_pll_read(pll, PLLnCR1);
- pll->frate_sel = FIELD_GET(PLLnCR1_FRATE_SEL, val);
-
- if (!pll->enabled)
- continue;
+ if (!pll->enabled)
+ return;

- switch (pll->frate_sel) {
- case PLLnCR1_FRATE_5G_10GVCO:
- case PLLnCR1_FRATE_5G_25GVCO:
- /* 5GHz clock net */
- __set_bit(LANE_MODE_1000BASEX_SGMII, pll->supported);
- break;
- case PLLnCR1_FRATE_10G_20GVCO:
- /* 10.3125GHz clock net */
- __set_bit(LANE_MODE_10GBASER, pll->supported);
- __set_bit(LANE_MODE_USXGMII, pll->supported);
- break;
- case PLLnCR1_FRATE_12G_25GVCO:
- /* 12.890625GHz clock net */
- __set_bit(LANE_MODE_25GBASER, pll->supported);
- break;
- default:
- /* 6GHz, 8GHz */
- break;
- }
+ switch (pll->frate_sel) {
+ case PLLnCR1_FRATE_5G_10GVCO:
+ case PLLnCR1_FRATE_5G_25GVCO:
+ /* 5GHz clock net */
+ __set_bit(LANE_MODE_1000BASEX_SGMII, pll->supported);
+ break;
+ case PLLnCR1_FRATE_10G_20GVCO:
+ /* 10.3125GHz clock net */
+ __set_bit(LANE_MODE_10GBASER, pll->supported);
+ __set_bit(LANE_MODE_USXGMII, pll->supported);
+ break;
+ case PLLnCR1_FRATE_12G_25GVCO:
+ /* 12.890625GHz clock net */
+ __set_bit(LANE_MODE_25GBASER, pll->supported);
+ break;
+ default:
+ /* 6GHz, 8GHz */
+ break;
}
}

@@ -1291,7 +1282,13 @@ static int lynx_28g_probe(struct platform_device *pdev)
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);

- lynx_28g_pll_read_configuration(priv);
+ for (int i = 0; i < LYNX_28G_NUM_PLL; i++) {
+ struct lynx_28g_pll *pll = &priv->pll[i];
+
+ pll->priv = priv;
+ pll->id = i;
+ lynx_28g_pll_read_configuration(pll);
+ }

if (of_get_child_count(dn)) {
struct device_node *child;
--
2.34.1