Commit a7043f65 authored by David S. Miller's avatar David S. Miller

Merge branch 'systemport-sf2-mdio-endian'

Florian Fainelli says:

====================
Endian fixes for SYSTEMPORT/SF2/MDIO

While trying an ARM BE kernel for kinks, the 3 drivers below started not
working and the reasons why became pretty obvious because the register space
remains LE (hardwired), except for Broadcom MIPS where it follows the CPU's
native endian (let's call that a feature).
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7619de85 cb51a091
...@@ -130,12 +130,12 @@ static inline u32 bcm_sf2_mangle_addr(struct bcm_sf2_priv *priv, u32 off) ...@@ -130,12 +130,12 @@ static inline u32 bcm_sf2_mangle_addr(struct bcm_sf2_priv *priv, u32 off)
#define SF2_IO_MACRO(name) \ #define SF2_IO_MACRO(name) \
static inline u32 name##_readl(struct bcm_sf2_priv *priv, u32 off) \ static inline u32 name##_readl(struct bcm_sf2_priv *priv, u32 off) \
{ \ { \
return __raw_readl(priv->name + off); \ return readl_relaxed(priv->name + off); \
} \ } \
static inline void name##_writel(struct bcm_sf2_priv *priv, \ static inline void name##_writel(struct bcm_sf2_priv *priv, \
u32 val, u32 off) \ u32 val, u32 off) \
{ \ { \
__raw_writel(val, priv->name + off); \ writel_relaxed(val, priv->name + off); \
} \ } \
/* Accesses to 64-bits register requires us to latch the hi/lo pairs /* Accesses to 64-bits register requires us to latch the hi/lo pairs
...@@ -179,23 +179,23 @@ static inline void intrl2_##which##_mask_set(struct bcm_sf2_priv *priv, \ ...@@ -179,23 +179,23 @@ static inline void intrl2_##which##_mask_set(struct bcm_sf2_priv *priv, \
static inline u32 core_readl(struct bcm_sf2_priv *priv, u32 off) static inline u32 core_readl(struct bcm_sf2_priv *priv, u32 off)
{ {
u32 tmp = bcm_sf2_mangle_addr(priv, off); u32 tmp = bcm_sf2_mangle_addr(priv, off);
return __raw_readl(priv->core + tmp); return readl_relaxed(priv->core + tmp);
} }
static inline void core_writel(struct bcm_sf2_priv *priv, u32 val, u32 off) static inline void core_writel(struct bcm_sf2_priv *priv, u32 val, u32 off)
{ {
u32 tmp = bcm_sf2_mangle_addr(priv, off); u32 tmp = bcm_sf2_mangle_addr(priv, off);
__raw_writel(val, priv->core + tmp); writel_relaxed(val, priv->core + tmp);
} }
static inline u32 reg_readl(struct bcm_sf2_priv *priv, u16 off) static inline u32 reg_readl(struct bcm_sf2_priv *priv, u16 off)
{ {
return __raw_readl(priv->reg + priv->reg_offsets[off]); return readl_relaxed(priv->reg + priv->reg_offsets[off]);
} }
static inline void reg_writel(struct bcm_sf2_priv *priv, u32 val, u16 off) static inline void reg_writel(struct bcm_sf2_priv *priv, u32 val, u16 off)
{ {
__raw_writel(val, priv->reg + priv->reg_offsets[off]); writel_relaxed(val, priv->reg + priv->reg_offsets[off]);
} }
SF2_IO64_MACRO(core); SF2_IO64_MACRO(core);
......
...@@ -32,13 +32,13 @@ ...@@ -32,13 +32,13 @@
#define BCM_SYSPORT_IO_MACRO(name, offset) \ #define BCM_SYSPORT_IO_MACRO(name, offset) \
static inline u32 name##_readl(struct bcm_sysport_priv *priv, u32 off) \ static inline u32 name##_readl(struct bcm_sysport_priv *priv, u32 off) \
{ \ { \
u32 reg = __raw_readl(priv->base + offset + off); \ u32 reg = readl_relaxed(priv->base + offset + off); \
return reg; \ return reg; \
} \ } \
static inline void name##_writel(struct bcm_sysport_priv *priv, \ static inline void name##_writel(struct bcm_sysport_priv *priv, \
u32 val, u32 off) \ u32 val, u32 off) \
{ \ { \
__raw_writel(val, priv->base + offset + off); \ writel_relaxed(val, priv->base + offset + off); \
} \ } \
BCM_SYSPORT_IO_MACRO(intrl2_0, SYS_PORT_INTRL2_0_OFFSET); BCM_SYSPORT_IO_MACRO(intrl2_0, SYS_PORT_INTRL2_0_OFFSET);
...@@ -59,14 +59,14 @@ static inline u32 rdma_readl(struct bcm_sysport_priv *priv, u32 off) ...@@ -59,14 +59,14 @@ static inline u32 rdma_readl(struct bcm_sysport_priv *priv, u32 off)
{ {
if (priv->is_lite && off >= RDMA_STATUS) if (priv->is_lite && off >= RDMA_STATUS)
off += 4; off += 4;
return __raw_readl(priv->base + SYS_PORT_RDMA_OFFSET + off); return readl_relaxed(priv->base + SYS_PORT_RDMA_OFFSET + off);
} }
static inline void rdma_writel(struct bcm_sysport_priv *priv, u32 val, u32 off) static inline void rdma_writel(struct bcm_sysport_priv *priv, u32 val, u32 off)
{ {
if (priv->is_lite && off >= RDMA_STATUS) if (priv->is_lite && off >= RDMA_STATUS)
off += 4; off += 4;
__raw_writel(val, priv->base + SYS_PORT_RDMA_OFFSET + off); writel_relaxed(val, priv->base + SYS_PORT_RDMA_OFFSET + off);
} }
static inline u32 tdma_control_bit(struct bcm_sysport_priv *priv, u32 bit) static inline u32 tdma_control_bit(struct bcm_sysport_priv *priv, u32 bit)
...@@ -110,10 +110,10 @@ static inline void dma_desc_set_addr(struct bcm_sysport_priv *priv, ...@@ -110,10 +110,10 @@ static inline void dma_desc_set_addr(struct bcm_sysport_priv *priv,
dma_addr_t addr) dma_addr_t addr)
{ {
#ifdef CONFIG_PHYS_ADDR_T_64BIT #ifdef CONFIG_PHYS_ADDR_T_64BIT
__raw_writel(upper_32_bits(addr) & DESC_ADDR_HI_MASK, writel_relaxed(upper_32_bits(addr) & DESC_ADDR_HI_MASK,
d + DESC_ADDR_HI_STATUS_LEN); d + DESC_ADDR_HI_STATUS_LEN);
#endif #endif
__raw_writel(lower_32_bits(addr), d + DESC_ADDR_LO); writel_relaxed(lower_32_bits(addr), d + DESC_ADDR_LO);
} }
static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv, static inline void tdma_port_write_desc_addr(struct bcm_sysport_priv *priv,
...@@ -1762,10 +1762,14 @@ static void rbuf_init(struct bcm_sysport_priv *priv) ...@@ -1762,10 +1762,14 @@ static void rbuf_init(struct bcm_sysport_priv *priv)
reg = rbuf_readl(priv, RBUF_CONTROL); reg = rbuf_readl(priv, RBUF_CONTROL);
reg |= RBUF_4B_ALGN | RBUF_RSB_EN; reg |= RBUF_4B_ALGN | RBUF_RSB_EN;
/* Set a correct RSB format on SYSTEMPORT Lite */ /* Set a correct RSB format on SYSTEMPORT Lite */
if (priv->is_lite) { if (priv->is_lite)
reg &= ~RBUF_RSB_SWAP1; reg &= ~RBUF_RSB_SWAP1;
/* Set a correct RSB format based on host endian */
if (!IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
reg |= RBUF_RSB_SWAP0; reg |= RBUF_RSB_SWAP0;
} else
reg &= ~RBUF_RSB_SWAP0;
rbuf_writel(priv, reg, RBUF_CONTROL); rbuf_writel(priv, reg, RBUF_CONTROL);
} }
......
...@@ -47,18 +47,38 @@ struct unimac_mdio_priv { ...@@ -47,18 +47,38 @@ struct unimac_mdio_priv {
void *wait_func_data; void *wait_func_data;
}; };
static inline u32 unimac_mdio_readl(struct unimac_mdio_priv *priv, u32 offset)
{
/* MIPS chips strapped for BE will automagically configure the
* peripheral registers for CPU-native byte order.
*/
if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
return __raw_readl(priv->base + offset);
else
return readl_relaxed(priv->base + offset);
}
static inline void unimac_mdio_writel(struct unimac_mdio_priv *priv, u32 val,
u32 offset)
{
if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
__raw_writel(val, priv->base + offset);
else
writel_relaxed(val, priv->base + offset);
}
static inline void unimac_mdio_start(struct unimac_mdio_priv *priv) static inline void unimac_mdio_start(struct unimac_mdio_priv *priv)
{ {
u32 reg; u32 reg;
reg = __raw_readl(priv->base + MDIO_CMD); reg = unimac_mdio_readl(priv, MDIO_CMD);
reg |= MDIO_START_BUSY; reg |= MDIO_START_BUSY;
__raw_writel(reg, priv->base + MDIO_CMD); unimac_mdio_writel(priv, reg, MDIO_CMD);
} }
static inline unsigned int unimac_mdio_busy(struct unimac_mdio_priv *priv) static inline unsigned int unimac_mdio_busy(struct unimac_mdio_priv *priv)
{ {
return __raw_readl(priv->base + MDIO_CMD) & MDIO_START_BUSY; return unimac_mdio_readl(priv, MDIO_CMD) & MDIO_START_BUSY;
} }
static int unimac_mdio_poll(void *wait_func_data) static int unimac_mdio_poll(void *wait_func_data)
...@@ -87,7 +107,7 @@ static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg) ...@@ -87,7 +107,7 @@ static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
/* Prepare the read operation */ /* Prepare the read operation */
cmd = MDIO_RD | (phy_id << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT); cmd = MDIO_RD | (phy_id << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT);
__raw_writel(cmd, priv->base + MDIO_CMD); unimac_mdio_writel(priv, cmd, MDIO_CMD);
/* Start MDIO transaction */ /* Start MDIO transaction */
unimac_mdio_start(priv); unimac_mdio_start(priv);
...@@ -96,7 +116,7 @@ static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg) ...@@ -96,7 +116,7 @@ static int unimac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
if (ret) if (ret)
return ret; return ret;
cmd = __raw_readl(priv->base + MDIO_CMD); cmd = unimac_mdio_readl(priv, MDIO_CMD);
/* Some broken devices are known not to release the line during /* Some broken devices are known not to release the line during
* turn-around, e.g: Broadcom BCM53125 external switches, so check for * turn-around, e.g: Broadcom BCM53125 external switches, so check for
...@@ -118,7 +138,7 @@ static int unimac_mdio_write(struct mii_bus *bus, int phy_id, ...@@ -118,7 +138,7 @@ static int unimac_mdio_write(struct mii_bus *bus, int phy_id,
/* Prepare the write operation */ /* Prepare the write operation */
cmd = MDIO_WR | (phy_id << MDIO_PMD_SHIFT) | cmd = MDIO_WR | (phy_id << MDIO_PMD_SHIFT) |
(reg << MDIO_REG_SHIFT) | (0xffff & val); (reg << MDIO_REG_SHIFT) | (0xffff & val);
__raw_writel(cmd, priv->base + MDIO_CMD); unimac_mdio_writel(priv, cmd, MDIO_CMD);
unimac_mdio_start(priv); unimac_mdio_start(priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment