mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
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>
This commit is contained in:
committed by
Vinod Koul
parent
719a2da392
commit
c6c1d7dfd5
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user