mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-29 08:00:26 +09:00
net: mscc: refactor mscc_miim
Because all MSCC SoC use the same MDIO bus, put the implementation in one common file(mscc_miim) and make all the other MSCC network drivers to use these functions. Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
This commit is contained in:
parent
ec9594a50f
commit
61243678c2
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_xfer.o mscc_mac_table.o
|
obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o
|
||||||
obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_xfer.o mscc_mac_table.o
|
obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o
|
||||||
obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o
|
obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o mscc_miim.o
|
||||||
obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o
|
obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o mscc_miim.o
|
||||||
obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o
|
obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o
|
||||||
|
@ -17,20 +17,7 @@
|
|||||||
|
|
||||||
#include <dt-bindings/mscc/jr2_data.h>
|
#include <dt-bindings/mscc/jr2_data.h>
|
||||||
#include "mscc_xfer.h"
|
#include "mscc_xfer.h"
|
||||||
|
#include "mscc_miim.h"
|
||||||
#define GCB_MIIM_MII_STATUS 0x0
|
|
||||||
#define GCB_MIIM_STAT_BUSY BIT(3)
|
|
||||||
#define GCB_MIIM_MII_CMD 0x8
|
|
||||||
#define GCB_MIIM_MII_CMD_SCAN BIT(0)
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
|
|
||||||
#define GCB_MIIM_MII_CMD_SINGLE_SCAN BIT(3)
|
|
||||||
#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
|
|
||||||
#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
|
|
||||||
#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
|
|
||||||
#define GCB_MIIM_MII_CMD_VLD BIT(31)
|
|
||||||
#define GCB_MIIM_DATA 0xC
|
|
||||||
#define GCB_MIIM_DATA_ERROR (0x3 << 16)
|
|
||||||
|
|
||||||
#define ANA_AC_RAM_CTRL_RAM_INIT 0x94358
|
#define ANA_AC_RAM_CTRL_RAM_INIT 0x94358
|
||||||
#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x94370
|
#define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET 0x94370
|
||||||
@ -279,13 +266,6 @@ struct jr2_private {
|
|||||||
struct jr2_phy_port_t ports[MAX_PORT];
|
struct jr2_phy_port_t ports[MAX_PORT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct jr2_miim_dev {
|
|
||||||
void __iomem *regs;
|
|
||||||
phys_addr_t miim_base;
|
|
||||||
unsigned long miim_size;
|
|
||||||
struct mii_dev *bus;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned long jr2_regs_qs[] = {
|
static const unsigned long jr2_regs_qs[] = {
|
||||||
[MSCC_QS_XTR_RD] = 0x8,
|
[MSCC_QS_XTR_RD] = 0x8,
|
||||||
[MSCC_QS_XTR_FLUSH] = 0x18,
|
[MSCC_QS_XTR_FLUSH] = 0x18,
|
||||||
@ -294,99 +274,9 @@ static const unsigned long jr2_regs_qs[] = {
|
|||||||
[MSCC_QS_INJ_CTRL] = 0x34,
|
[MSCC_QS_INJ_CTRL] = 0x34,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct jr2_miim_dev miim[JR2_MIIM_BUS_COUNT];
|
static struct mscc_miim_dev miim[JR2_MIIM_BUS_COUNT];
|
||||||
static int miim_count = -1;
|
static int miim_count = -1;
|
||||||
|
|
||||||
static int mscc_miim_wait_ready(struct jr2_miim_dev *miim)
|
|
||||||
{
|
|
||||||
unsigned long deadline;
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
deadline = timer_get_us() + 250000;
|
|
||||||
|
|
||||||
do {
|
|
||||||
val = readl(miim->regs + GCB_MIIM_MII_STATUS);
|
|
||||||
} while (timer_get_us() <= deadline && (val & GCB_MIIM_STAT_BUSY));
|
|
||||||
|
|
||||||
if (val & GCB_MIIM_STAT_BUSY)
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
|
|
||||||
{
|
|
||||||
struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
|
|
||||||
u32 val;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
|
|
||||||
miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
val = readl(miim->regs + GCB_MIIM_DATA);
|
|
||||||
if (val & GCB_MIIM_DATA_ERROR) {
|
|
||||||
ret = -EIO;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = val & 0xFFFF;
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
|
|
||||||
GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mii_dev *jr2_mdiobus_init(phys_addr_t miim_base,
|
|
||||||
unsigned long miim_size)
|
|
||||||
{
|
|
||||||
struct mii_dev *bus;
|
|
||||||
|
|
||||||
bus = mdio_alloc();
|
|
||||||
if (!bus)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
++miim_count;
|
|
||||||
sprintf(bus->name, "miim-bus%d", miim_count);
|
|
||||||
|
|
||||||
miim[miim_count].regs = ioremap(miim_base, miim_size);
|
|
||||||
miim[miim_count].miim_base = miim_base;
|
|
||||||
miim[miim_count].miim_size = miim_size;
|
|
||||||
bus->priv = &miim[miim_count];
|
|
||||||
bus->read = mscc_miim_read;
|
|
||||||
bus->write = mscc_miim_write;
|
|
||||||
|
|
||||||
if (mdio_register(bus))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
miim[miim_count].bus = bus;
|
|
||||||
return bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void jr2_cpu_capture_setup(struct jr2_private *priv)
|
static void jr2_cpu_capture_setup(struct jr2_private *priv)
|
||||||
{
|
{
|
||||||
/* ASM: No preamble and IFH prefix on CPU injected frames */
|
/* ASM: No preamble and IFH prefix on CPU injected frames */
|
||||||
@ -973,7 +863,7 @@ static int jr2_probe(struct udevice *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize miim buses */
|
/* Initialize miim buses */
|
||||||
memset(&miim, 0x0, sizeof(struct jr2_miim_dev) * JR2_MIIM_BUS_COUNT);
|
memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * JR2_MIIM_BUS_COUNT);
|
||||||
|
|
||||||
/* iterate all the ports and find out on which bus they are */
|
/* iterate all the ports and find out on which bus they are */
|
||||||
i = 0;
|
i = 0;
|
||||||
@ -1008,7 +898,8 @@ static int jr2_probe(struct udevice *dev)
|
|||||||
/* If the bus is new then create a new bus */
|
/* If the bus is new then create a new bus */
|
||||||
if (!get_mdiobus(addr_base, addr_size))
|
if (!get_mdiobus(addr_base, addr_size))
|
||||||
priv->bus[miim_count] =
|
priv->bus[miim_count] =
|
||||||
jr2_mdiobus_init(addr_base, addr_size);
|
mscc_mdiobus_init(miim, &miim_count, addr_base,
|
||||||
|
addr_size);
|
||||||
|
|
||||||
/* Connect mdio bus with the port */
|
/* Connect mdio bus with the port */
|
||||||
bus = get_mdiobus(addr_base, addr_size);
|
bus = get_mdiobus(addr_base, addr_size);
|
||||||
|
@ -17,18 +17,7 @@
|
|||||||
|
|
||||||
#include "mscc_xfer.h"
|
#include "mscc_xfer.h"
|
||||||
#include "mscc_mac_table.h"
|
#include "mscc_mac_table.h"
|
||||||
|
#include "mscc_miim.h"
|
||||||
#define GCB_MIIM_MII_STATUS 0x0
|
|
||||||
#define GCB_MIIM_STAT_BUSY BIT(3)
|
|
||||||
#define GCB_MIIM_MII_CMD 0x8
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
|
|
||||||
#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
|
|
||||||
#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
|
|
||||||
#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
|
|
||||||
#define GCB_MIIM_MII_CMD_VLD BIT(31)
|
|
||||||
#define GCB_MIIM_DATA 0xC
|
|
||||||
#define GCB_MIIM_DATA_ERROR (0x2 << 16)
|
|
||||||
|
|
||||||
#define ANA_PORT_VLAN_CFG(x) (0x00 + 0x80 * (x))
|
#define ANA_PORT_VLAN_CFG(x) (0x00 + 0x80 * (x))
|
||||||
#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
|
#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
|
||||||
@ -189,13 +178,6 @@ struct luton_private {
|
|||||||
struct luton_phy_port_t ports[MAX_PORT];
|
struct luton_phy_port_t ports[MAX_PORT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mscc_miim_dev {
|
|
||||||
void __iomem *regs;
|
|
||||||
phys_addr_t miim_base;
|
|
||||||
unsigned long miim_size;
|
|
||||||
struct mii_dev *bus;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned long luton_regs_qs[] = {
|
static const unsigned long luton_regs_qs[] = {
|
||||||
[MSCC_QS_XTR_RD] = 0x18,
|
[MSCC_QS_XTR_RD] = 0x18,
|
||||||
[MSCC_QS_XTR_FLUSH] = 0x28,
|
[MSCC_QS_XTR_FLUSH] = 0x28,
|
||||||
@ -213,84 +195,6 @@ static const unsigned long luton_regs_ana_table[] = {
|
|||||||
static struct mscc_miim_dev miim[LUTON_MIIM_BUS_COUNT];
|
static struct mscc_miim_dev miim[LUTON_MIIM_BUS_COUNT];
|
||||||
static int miim_count = -1;
|
static int miim_count = -1;
|
||||||
|
|
||||||
static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
|
|
||||||
{
|
|
||||||
return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
|
|
||||||
GCB_MIIM_STAT_BUSY, false, 250, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
|
|
||||||
{
|
|
||||||
struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
|
|
||||||
u32 val;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
|
|
||||||
miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
val = readl(miim->regs + GCB_MIIM_DATA);
|
|
||||||
if (val & GCB_MIIM_DATA_ERROR) {
|
|
||||||
ret = -EIO;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = val & 0xFFFF;
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
|
|
||||||
GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mii_dev *serval_mdiobus_init(phys_addr_t miim_base,
|
|
||||||
unsigned long miim_size)
|
|
||||||
{
|
|
||||||
struct mii_dev *bus;
|
|
||||||
|
|
||||||
bus = mdio_alloc();
|
|
||||||
if (!bus)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
++miim_count;
|
|
||||||
sprintf(bus->name, "miim-bus%d", miim_count);
|
|
||||||
|
|
||||||
miim[miim_count].regs = ioremap(miim_base, miim_size);
|
|
||||||
miim[miim_count].miim_base = miim_base;
|
|
||||||
miim[miim_count].miim_size = miim_size;
|
|
||||||
bus->priv = &miim[miim_count];
|
|
||||||
bus->read = mscc_miim_read;
|
|
||||||
bus->write = mscc_miim_write;
|
|
||||||
|
|
||||||
if (mdio_register(bus))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
miim[miim_count].bus = bus;
|
|
||||||
return bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void luton_stop(struct udevice *dev)
|
static void luton_stop(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct luton_private *priv = dev_get_priv(dev);
|
struct luton_private *priv = dev_get_priv(dev);
|
||||||
@ -760,7 +664,8 @@ static int luton_probe(struct udevice *dev)
|
|||||||
/* If the bus is new then create a new bus */
|
/* If the bus is new then create a new bus */
|
||||||
if (!get_mdiobus(addr_base, addr_size))
|
if (!get_mdiobus(addr_base, addr_size))
|
||||||
priv->bus[miim_count] =
|
priv->bus[miim_count] =
|
||||||
serval_mdiobus_init(addr_base, addr_size);
|
mscc_mdiobus_init(miim, &miim_count, addr_base,
|
||||||
|
addr_size);
|
||||||
|
|
||||||
/* Connect mdio bus with the port */
|
/* Connect mdio bus with the port */
|
||||||
bus = get_mdiobus(addr_base, addr_size);
|
bus = get_mdiobus(addr_base, addr_size);
|
||||||
|
@ -72,3 +72,31 @@ int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
|
|||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mii_dev *mscc_mdiobus_init(struct mscc_miim_dev *miim, int *miim_count,
|
||||||
|
phys_addr_t miim_base,
|
||||||
|
unsigned long miim_size)
|
||||||
|
{
|
||||||
|
struct mii_dev *bus;
|
||||||
|
|
||||||
|
bus = mdio_alloc();
|
||||||
|
|
||||||
|
if (!bus)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*miim_count += 1;
|
||||||
|
sprintf(bus->name, "miim-bus%d", *miim_count);
|
||||||
|
|
||||||
|
miim[*miim_count].regs = ioremap(miim_base, miim_size);
|
||||||
|
miim[*miim_count].miim_base = miim_base;
|
||||||
|
miim[*miim_count].miim_size = miim_size;
|
||||||
|
bus->priv = &miim[*miim_count];
|
||||||
|
bus->read = mscc_miim_read;
|
||||||
|
bus->write = mscc_miim_write;
|
||||||
|
|
||||||
|
if (mdio_register(bus))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
miim[*miim_count].bus = bus;
|
||||||
|
return bus;
|
||||||
|
}
|
||||||
|
@ -3,10 +3,22 @@
|
|||||||
* Copyright (c) 2018 Microsemi Corporation
|
* Copyright (c) 2018 Microsemi Corporation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _MSCC_MIIM_H_
|
||||||
|
#define _MSCC_MIIM_H_
|
||||||
|
|
||||||
struct mscc_miim_dev {
|
struct mscc_miim_dev {
|
||||||
void __iomem *regs;
|
void __iomem *regs;
|
||||||
void __iomem *phy_regs;
|
phys_addr_t miim_base;
|
||||||
|
unsigned long miim_size;
|
||||||
|
struct mii_dev *bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg);
|
int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg);
|
||||||
int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg, u16 val);
|
int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg, u16 val);
|
||||||
|
|
||||||
|
struct mii_dev *mscc_mdiobus_init(struct mscc_miim_dev *miim, int *miim_count,
|
||||||
|
phys_addr_t miim_base,
|
||||||
|
unsigned long miim_size);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _MSCC_MIIM_H_ */
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "mscc_xfer.h"
|
#include "mscc_xfer.h"
|
||||||
#include "mscc_mac_table.h"
|
#include "mscc_mac_table.h"
|
||||||
|
#include "mscc_miim.h"
|
||||||
|
|
||||||
#define PHY_CFG 0x0
|
#define PHY_CFG 0x0
|
||||||
#define PHY_CFG_ENA 0xF
|
#define PHY_CFG_ENA 0xF
|
||||||
@ -25,20 +26,6 @@
|
|||||||
#define PHY_STAT 0x4
|
#define PHY_STAT 0x4
|
||||||
#define PHY_STAT_SUPERVISOR_COMPLETE BIT(0)
|
#define PHY_STAT_SUPERVISOR_COMPLETE BIT(0)
|
||||||
|
|
||||||
#define GCB_MIIM_MII_STATUS 0x0
|
|
||||||
#define GCB_MIIM_STAT_BUSY BIT(3)
|
|
||||||
#define GCB_MIIM_MII_CMD 0x8
|
|
||||||
#define GCB_MIIM_MII_CMD_SCAN BIT(0)
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
|
|
||||||
#define GCB_MIIM_MII_CMD_SINGLE_SCAN BIT(3)
|
|
||||||
#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
|
|
||||||
#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
|
|
||||||
#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
|
|
||||||
#define GCB_MIIM_MII_CMD_VLD BIT(31)
|
|
||||||
#define GCB_MIIM_DATA 0xC
|
|
||||||
#define GCB_MIIM_DATA_ERROR (0x3 << 16)
|
|
||||||
|
|
||||||
#define ANA_PORT_VLAN_CFG(x) (0x7000 + 0x100 * (x))
|
#define ANA_PORT_VLAN_CFG(x) (0x7000 + 0x100 * (x))
|
||||||
#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
|
#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
|
||||||
#define ANA_PORT_VLAN_CFG_POP_CNT(x) ((x) << 18)
|
#define ANA_PORT_VLAN_CFG_POP_CNT(x) ((x) << 18)
|
||||||
@ -173,13 +160,6 @@ struct ocelot_private {
|
|||||||
struct ocelot_phy_port_t ports[MAX_PORT];
|
struct ocelot_phy_port_t ports[MAX_PORT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mscc_miim_dev {
|
|
||||||
void __iomem *regs;
|
|
||||||
phys_addr_t miim_base;
|
|
||||||
unsigned long miim_size;
|
|
||||||
struct mii_dev *bus;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct mscc_miim_dev miim[OCELOT_MIIM_BUS_COUNT];
|
static struct mscc_miim_dev miim[OCELOT_MIIM_BUS_COUNT];
|
||||||
static int miim_count = -1;
|
static int miim_count = -1;
|
||||||
|
|
||||||
@ -209,85 +189,6 @@ static void mscc_phy_reset(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
|
|
||||||
{
|
|
||||||
return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
|
|
||||||
GCB_MIIM_STAT_BUSY, false, 250, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
|
|
||||||
{
|
|
||||||
struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
|
|
||||||
u32 val;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
|
|
||||||
miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
val = readl(miim->regs + GCB_MIIM_DATA);
|
|
||||||
if (val & GCB_MIIM_DATA_ERROR) {
|
|
||||||
ret = -EIO;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = val & 0xFFFF;
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
|
|
||||||
GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mii_dev *ocelot_mdiobus_init(phys_addr_t miim_base,
|
|
||||||
unsigned long miim_size)
|
|
||||||
{
|
|
||||||
struct mii_dev *bus;
|
|
||||||
|
|
||||||
bus = mdio_alloc();
|
|
||||||
|
|
||||||
if (!bus)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
++miim_count;
|
|
||||||
sprintf(bus->name, "miim-bus%d", miim_count);
|
|
||||||
|
|
||||||
miim[miim_count].regs = ioremap(miim_base, miim_size);
|
|
||||||
miim[miim_count].miim_base = miim_base;
|
|
||||||
miim[miim_count].miim_size = miim_size;
|
|
||||||
bus->priv = &miim[miim_count];
|
|
||||||
bus->read = mscc_miim_read;
|
|
||||||
bus->write = mscc_miim_write;
|
|
||||||
|
|
||||||
if (mdio_register(bus))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
miim[miim_count].bus = bus;
|
|
||||||
return bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
__weak void mscc_switch_reset(void)
|
__weak void mscc_switch_reset(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -682,7 +583,8 @@ static int ocelot_probe(struct udevice *dev)
|
|||||||
/* If the bus is new then create a new bus */
|
/* If the bus is new then create a new bus */
|
||||||
if (!get_mdiobus(addr_base, addr_size))
|
if (!get_mdiobus(addr_base, addr_size))
|
||||||
priv->bus[miim_count] =
|
priv->bus[miim_count] =
|
||||||
ocelot_mdiobus_init(addr_base, addr_size);
|
mscc_mdiobus_init(miim, &miim_count, addr_base,
|
||||||
|
addr_size);
|
||||||
|
|
||||||
/* Connect mdio bus with the port */
|
/* Connect mdio bus with the port */
|
||||||
bus = get_mdiobus(addr_base, addr_size);
|
bus = get_mdiobus(addr_base, addr_size);
|
||||||
|
@ -17,18 +17,7 @@
|
|||||||
|
|
||||||
#include "mscc_xfer.h"
|
#include "mscc_xfer.h"
|
||||||
#include "mscc_mac_table.h"
|
#include "mscc_mac_table.h"
|
||||||
|
#include "mscc_miim.h"
|
||||||
#define GCB_MIIM_MII_STATUS 0x0
|
|
||||||
#define GCB_MIIM_STAT_BUSY BIT(3)
|
|
||||||
#define GCB_MIIM_MII_CMD 0x8
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
|
|
||||||
#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
|
|
||||||
#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
|
|
||||||
#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
|
|
||||||
#define GCB_MIIM_MII_CMD_VLD BIT(31)
|
|
||||||
#define GCB_MIIM_DATA 0xC
|
|
||||||
#define GCB_MIIM_DATA_ERROR (0x2 << 16)
|
|
||||||
|
|
||||||
#define ANA_PORT_VLAN_CFG(x) (0xc000 + 0x100 * (x))
|
#define ANA_PORT_VLAN_CFG(x) (0xc000 + 0x100 * (x))
|
||||||
#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
|
#define ANA_PORT_VLAN_CFG_AWARE_ENA BIT(20)
|
||||||
@ -156,13 +145,6 @@ struct serval_private {
|
|||||||
struct serval_phy_port_t ports[MAX_PORT];
|
struct serval_phy_port_t ports[MAX_PORT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mscc_miim_dev {
|
|
||||||
void __iomem *regs;
|
|
||||||
phys_addr_t miim_base;
|
|
||||||
unsigned long miim_size;
|
|
||||||
struct mii_dev *bus;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned long serval_regs_qs[] = {
|
static const unsigned long serval_regs_qs[] = {
|
||||||
[MSCC_QS_XTR_RD] = 0x8,
|
[MSCC_QS_XTR_RD] = 0x8,
|
||||||
[MSCC_QS_XTR_FLUSH] = 0x18,
|
[MSCC_QS_XTR_FLUSH] = 0x18,
|
||||||
@ -180,84 +162,6 @@ static const unsigned long serval_regs_ana_table[] = {
|
|||||||
static struct mscc_miim_dev miim[SERVAL_MIIM_BUS_COUNT];
|
static struct mscc_miim_dev miim[SERVAL_MIIM_BUS_COUNT];
|
||||||
static int miim_count = -1;
|
static int miim_count = -1;
|
||||||
|
|
||||||
static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
|
|
||||||
{
|
|
||||||
return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
|
|
||||||
GCB_MIIM_STAT_BUSY, false, 250, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
|
|
||||||
{
|
|
||||||
struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
|
|
||||||
u32 val;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
|
|
||||||
miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
val = readl(miim->regs + GCB_MIIM_DATA);
|
|
||||||
if (val & GCB_MIIM_DATA_ERROR) {
|
|
||||||
ret = -EIO;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = val & 0xFFFF;
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
|
|
||||||
GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mii_dev *serval_mdiobus_init(phys_addr_t miim_base,
|
|
||||||
unsigned long miim_size)
|
|
||||||
{
|
|
||||||
struct mii_dev *bus;
|
|
||||||
|
|
||||||
bus = mdio_alloc();
|
|
||||||
if (!bus)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
++miim_count;
|
|
||||||
sprintf(bus->name, "miim-bus%d", miim_count);
|
|
||||||
|
|
||||||
miim[miim_count].regs = ioremap(miim_base, miim_size);
|
|
||||||
miim[miim_count].miim_base = miim_base;
|
|
||||||
miim[miim_count].miim_size = miim_size;
|
|
||||||
bus->priv = &miim[miim_count];
|
|
||||||
bus->read = mscc_miim_read;
|
|
||||||
bus->write = mscc_miim_write;
|
|
||||||
|
|
||||||
if (mdio_register(bus))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
miim[miim_count].bus = bus;
|
|
||||||
return bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void serval_cpu_capture_setup(struct serval_private *priv)
|
static void serval_cpu_capture_setup(struct serval_private *priv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -634,7 +538,8 @@ static int serval_probe(struct udevice *dev)
|
|||||||
/* If the bus is new then create a new bus */
|
/* If the bus is new then create a new bus */
|
||||||
if (!get_mdiobus(addr_base, addr_size))
|
if (!get_mdiobus(addr_base, addr_size))
|
||||||
priv->bus[miim_count] =
|
priv->bus[miim_count] =
|
||||||
serval_mdiobus_init(addr_base, addr_size);
|
mscc_mdiobus_init(miim, &miim_count, addr_base,
|
||||||
|
addr_size);
|
||||||
|
|
||||||
/* Connect mdio bus with the port */
|
/* Connect mdio bus with the port */
|
||||||
bus = get_mdiobus(addr_base, addr_size);
|
bus = get_mdiobus(addr_base, addr_size);
|
||||||
|
@ -16,18 +16,7 @@
|
|||||||
#include <wait_bit.h>
|
#include <wait_bit.h>
|
||||||
|
|
||||||
#include "mscc_xfer.h"
|
#include "mscc_xfer.h"
|
||||||
|
#include "mscc_miim.h"
|
||||||
#define GCB_MIIM_MII_STATUS 0x0
|
|
||||||
#define GCB_MIIM_STAT_BUSY BIT(3)
|
|
||||||
#define GCB_MIIM_MII_CMD 0x8
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_WRITE BIT(1)
|
|
||||||
#define GCB_MIIM_MII_CMD_OPR_READ BIT(2)
|
|
||||||
#define GCB_MIIM_MII_CMD_WRDATA(x) ((x) << 4)
|
|
||||||
#define GCB_MIIM_MII_CMD_REGAD(x) ((x) << 20)
|
|
||||||
#define GCB_MIIM_MII_CMD_PHYAD(x) ((x) << 25)
|
|
||||||
#define GCB_MIIM_MII_CMD_VLD BIT(31)
|
|
||||||
#define GCB_MIIM_DATA 0xC
|
|
||||||
#define GCB_MIIM_DATA_ERROR (0x3 << 16)
|
|
||||||
|
|
||||||
#define PHY_CFG 0x0
|
#define PHY_CFG 0x0
|
||||||
#define PHY_CFG_ENA 0x3
|
#define PHY_CFG_ENA 0x3
|
||||||
@ -134,13 +123,6 @@ struct servalt_private {
|
|||||||
struct servalt_phy_port_t ports[MAX_PORT];
|
struct servalt_phy_port_t ports[MAX_PORT];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mscc_miim_dev {
|
|
||||||
void __iomem *regs;
|
|
||||||
phys_addr_t miim_base;
|
|
||||||
unsigned long miim_size;
|
|
||||||
struct mii_dev *bus;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned long servalt_regs_qs[] = {
|
static const unsigned long servalt_regs_qs[] = {
|
||||||
[MSCC_QS_XTR_RD] = 0x8,
|
[MSCC_QS_XTR_RD] = 0x8,
|
||||||
[MSCC_QS_XTR_FLUSH] = 0x18,
|
[MSCC_QS_XTR_FLUSH] = 0x18,
|
||||||
@ -152,85 +134,6 @@ static const unsigned long servalt_regs_qs[] = {
|
|||||||
static struct mscc_miim_dev miim[SERVALT_MIIM_BUS_COUNT];
|
static struct mscc_miim_dev miim[SERVALT_MIIM_BUS_COUNT];
|
||||||
static int miim_count = -1;
|
static int miim_count = -1;
|
||||||
|
|
||||||
static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
|
|
||||||
{
|
|
||||||
return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
|
|
||||||
GCB_MIIM_STAT_BUSY, false, 250, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
|
|
||||||
{
|
|
||||||
struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
|
|
||||||
u32 val;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
|
|
||||||
miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
val = readl(miim->regs + GCB_MIIM_DATA);
|
|
||||||
if (val & GCB_MIIM_DATA_ERROR) {
|
|
||||||
ret = -EIO;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = val & 0xFFFF;
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
|
|
||||||
u16 val)
|
|
||||||
{
|
|
||||||
struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = mscc_miim_wait_ready(miim);
|
|
||||||
if (ret < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
|
|
||||||
GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
|
|
||||||
GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
|
|
||||||
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mii_dev *servalt_mdiobus_init(phys_addr_t miim_base,
|
|
||||||
unsigned long miim_size)
|
|
||||||
{
|
|
||||||
struct mii_dev *bus;
|
|
||||||
|
|
||||||
bus = mdio_alloc();
|
|
||||||
if (!bus)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
++miim_count;
|
|
||||||
sprintf(bus->name, "miim-bus%d", miim_count);
|
|
||||||
|
|
||||||
miim[miim_count].regs = ioremap(miim_base, miim_size);
|
|
||||||
miim[miim_count].miim_base = miim_base;
|
|
||||||
miim[miim_count].miim_size = miim_size;
|
|
||||||
bus->priv = &miim[miim_count];
|
|
||||||
bus->read = mscc_miim_read;
|
|
||||||
bus->write = mscc_miim_write;
|
|
||||||
|
|
||||||
if (mdio_register(bus))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
miim[miim_count].bus = bus;
|
|
||||||
return bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mscc_phy_reset(void)
|
static void mscc_phy_reset(void)
|
||||||
{
|
{
|
||||||
writel(0, BASE_DEVCPU_GCB + GCB_PHY_CFG + PHY_CFG);
|
writel(0, BASE_DEVCPU_GCB + GCB_PHY_CFG + PHY_CFG);
|
||||||
@ -564,7 +467,8 @@ static int servalt_probe(struct udevice *dev)
|
|||||||
/* If the bus is new then create a new bus */
|
/* If the bus is new then create a new bus */
|
||||||
if (!get_mdiobus(addr_base, addr_size))
|
if (!get_mdiobus(addr_base, addr_size))
|
||||||
priv->bus[miim_count] =
|
priv->bus[miim_count] =
|
||||||
servalt_mdiobus_init(addr_base, addr_size);
|
mscc_mdiobus_init(miim, &miim_count, addr_base,
|
||||||
|
addr_size);
|
||||||
|
|
||||||
/* Connect mdio bus with the port */
|
/* Connect mdio bus with the port */
|
||||||
bus = get_mdiobus(addr_base, addr_size);
|
bus = get_mdiobus(addr_base, addr_size);
|
||||||
|
Loading…
Reference in New Issue
Block a user