diff options
| author | Vladimir Oltean <vladimir.oltean@nxp.com> | 2026-06-10 18:19:47 +0300 |
|---|---|---|
| committer | Vinod Koul <vkoul@kernel.org> | 2026-06-11 10:09:47 +0300 |
| commit | c6c1d7dfd59b181b96b0909b63e140b0aa61ac59 (patch) | |
| tree | c456f89962a80a3b293fbee24af0180cbd42b696 | |
| parent | 719a2da392349db052532db89637622a71d14d49 (diff) | |
| download | linux-c6c1d7dfd59b181b96b0909b63e140b0aa61ac59.tar.xz | |
phy: lynx-28g: add support for big endian register maps
Some 10G Lynx SerDes blocks are big endian and require byte swapping
because the CPUs are little endian armv8 (LS1046A). Parse the
"big-endian" device tree property, and modify the base lynx_read() and
lynx_write() accessors to test this property before issuing either the
ioread32() or ioread32be() variants (as per
Documentation/driver-api/device-io.rst).
All other accessors - lynx_rmw(), lynx_lane_read(), lynx_lane_write(),
lynx_lane_rmw(), lynx_pll_read() - need to go through these endian-aware
helpers.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-12-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
| -rw-r--r-- | drivers/phy/freescale/phy-fsl-lynx-core.c | 1 | ||||
| -rw-r--r-- | drivers/phy/freescale/phy-fsl-lynx-core.h | 36 |
2 files changed, 27 insertions, 10 deletions
diff --git a/drivers/phy/freescale/phy-fsl-lynx-core.c b/drivers/phy/freescale/phy-fsl-lynx-core.c index 3fb89bb4b0d6..226b2af2b599 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-core.c +++ b/drivers/phy/freescale/phy-fsl-lynx-core.c @@ -295,6 +295,7 @@ int lynx_probe(struct platform_device *pdev, const struct lynx_info *info, priv->dev = dev; priv->info = info; + priv->big_endian = device_property_read_bool(dev, "big-endian"); dev_set_drvdata(dev, priv); spin_lock_init(&priv->pcc_lock); INIT_DELAYED_WORK(&priv->cdr_check, lynx_cdr_lock_check); diff --git a/drivers/phy/freescale/phy-fsl-lynx-core.h b/drivers/phy/freescale/phy-fsl-lynx-core.h index e8b280cc9b38..d82e529fa65a 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-core.h +++ b/drivers/phy/freescale/phy-fsl-lynx-core.h @@ -58,36 +58,52 @@ struct lynx_priv { * like PCCn */ spinlock_t pcc_lock; + bool big_endian; struct lynx_pll pll[LYNX_NUM_PLL]; struct lynx_lane *lane; struct delayed_work cdr_check; }; +static inline u32 lynx_read(struct lynx_priv *priv, unsigned long off) +{ + void __iomem *reg = priv->base + off; + + if (priv->big_endian) + return ioread32be(reg); + + return ioread32(reg); +} + +static inline void lynx_write(struct lynx_priv *priv, unsigned long off, u32 val) +{ + void __iomem *reg = priv->base + off; + + if (priv->big_endian) + return iowrite32be(val, reg); + + return iowrite32(val, reg); +} + static inline void lynx_rmw(struct lynx_priv *priv, unsigned long off, u32 val, u32 mask) { - void __iomem *reg = priv->base + off; u32 orig, tmp; - orig = ioread32(reg); + orig = lynx_read(priv, off); tmp = orig & ~mask; tmp |= val; - iowrite32(tmp, reg); + lynx_write(priv, off, tmp); } -#define lynx_read(priv, off) \ - ioread32((priv)->base + (off)) -#define lynx_write(priv, off, val) \ - iowrite32(val, (priv)->base + (off)) #define lynx_lane_rmw(lane, reg, val, mask) \ lynx_rmw((lane)->priv, reg(lane->id), val, mask) #define lynx_lane_read(lane, reg) \ - ioread32((lane)->priv->base + reg((lane)->id)) + lynx_read((lane)->priv, reg((lane)->id)) #define lynx_lane_write(lane, reg, val) \ - iowrite32(val, (lane)->priv->base + reg((lane)->id)) + lynx_write((lane)->priv, reg((lane)->id), val) #define lynx_pll_read(pll, reg) \ - ioread32((pll)->priv->base + reg((pll)->id)) + lynx_read((pll)->priv, reg((pll)->id)) int lynx_probe(struct platform_device *pdev, const struct lynx_info *info, const struct phy_ops *phy_ops); |
