Message ID | 20190806155144.19301-3-nhed+uboot@starry.com |
---|---|
State | New, archived |
Delegated to: | Joe Hershberger |
Headers | show |
Series | Switch MVPP2 to use new MVMDIO | expand |
On Tue, Aug 6, 2019 at 6:52 PM <nhed+uboot@starry.com> wrote: > > From: Ken Ma <make@marvell.com> > > The availability of the marvell MDIO driver enables us to eliminate > the SMI function implementation within the mvpp2 driver. > This replacement also fixes 2 old issues: > 1. Each pp2 port device now has its own mdio bus field member since > some pp2 ports may use SMI mdio bus while some other pp2 ports may > use XSMI mdio bus, but the old mvpp2_base device has a shared bus > for all its pp2 ports; this patch moves mdio bus field member from > struct mvpp2 to struct mvpp2_port; > 2. Old code uses mvpp2_base device name as mdio bus name; but for > Armada80x0, cp0 ethernet device and cp1 ethernet device have the > same device name - "ethernet@0"; and because mdio_register() checks > unique name, then the second probed mvpp2_base device fails to > register mdio bus; since new marvell MDIO driver has resolved the > unique name issue - different mdio names can be set in fdt and if a > mdio name is not set, the default mdio name is generated from the > mdio bus base address, so this issue is fixed by this replacement. > > Signed-off-by: Ken Ma <make@marvell.com> > Reviewed-by: Igal Liberman <igall@marvell.com> > Tested-by: Igal Liberman <igall@marvell.com> > Signed-off-by: Nevo Hed <nhed+github@starry.com> > --- > drivers/net/mvpp2.c | 158 ++++---------------------------------------- > 1 file changed, 12 insertions(+), 146 deletions(-) > > diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c > index f36c8236b1..b6dfed5c54 100644 > --- a/drivers/net/mvpp2.c > +++ b/drivers/net/mvpp2.c > @@ -32,6 +32,7 @@ > #include <linux/mbus.h> > #include <asm-generic/gpio.h> > #include <fdt_support.h> > +#include <mdio.h> > > DECLARE_GLOBAL_DATA_PTR; > > @@ -62,8 +63,6 @@ do { \ > #define MTU 1500 > #define RX_BUFFER_SIZE (ALIGN(MTU + WRAP, ARCH_DMA_MINALIGN)) > > -#define MVPP2_SMI_TIMEOUT 10000 > - > /* RX Fifo Registers */ > #define MVPP2_RX_DATA_FIFO_SIZE_REG(port) (0x00 + 4 * (port)) > #define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port)) > @@ -490,23 +489,8 @@ do { \ > #define MVPP2_QUEUE_NEXT_DESC(q, index) \ > (((index) < (q)->last_desc) ? ((index) + 1) : 0) > > -/* SMI: 0xc0054 -> offset 0x54 to lms_base */ > -#define MVPP21_SMI 0x0054 > /* PP2.2: SMI: 0x12a200 -> offset 0x1200 to iface_base */ > #define MVPP22_SMI 0x1200 > -#define MVPP2_PHY_REG_MASK 0x1f > -/* SMI register fields */ > -#define MVPP2_SMI_DATA_OFFS 0 /* Data */ > -#define MVPP2_SMI_DATA_MASK (0xffff << MVPP2_SMI_DATA_OFFS) > -#define MVPP2_SMI_DEV_ADDR_OFFS 16 /* PHY device address */ > -#define MVPP2_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr*/ > -#define MVPP2_SMI_OPCODE_OFFS 26 /* Write/Read opcode */ > -#define MVPP2_SMI_OPCODE_READ (1 << MVPP2_SMI_OPCODE_OFFS) > -#define MVPP2_SMI_READ_VALID (1 << 27) /* Read Valid */ > -#define MVPP2_SMI_BUSY (1 << 28) /* Busy */ > - > -#define MVPP2_PHY_ADDR_MASK 0x1f > -#define MVPP2_PHY_REG_MASK 0x1f > > /* Additional PPv2.2 offsets */ > #define MVPP22_MPCS 0x007000 > @@ -973,7 +957,6 @@ struct mvpp2_port { > > struct phy_device *phy_dev; > phy_interface_t phy_interface; > - int phy_node; > int phyaddr; > struct mii_dev *bus; > #ifdef CONFIG_DM_GPIO > @@ -4562,7 +4545,7 @@ static int mvpp2_open(struct udevice *dev, struct mvpp2_port *port) > return err; > } > > - if (port->phy_node) { > + if (port->phyaddr < PHY_MAX_ADDR) { > mvpp2_phy_connect(dev, port); > mvpp2_link_event(port); > } else { > @@ -4701,6 +4684,7 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) > u32 id; > u32 phyaddr = 0; > int phy_mode = -1; > + int ret; > > /* Default mdio_base from the same eth base */ > if (port->priv->hw_version == MVPP21) > @@ -4719,17 +4703,12 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) > dev_err(&pdev->dev, "could not find phy address\n"); > return -1; > } > - > - phy_ofnode = ofnode_get_parent(offset_to_ofnode(phy_node)); > - phy_base = ofnode_get_addr(phy_ofnode); > - port->mdio_base = (void *)phy_base; > - > - if (port->mdio_base < 0) { > - dev_err(&pdev->dev, "could not find mdio base address\n"); > - return -1; > - } > + ret = mdio_mii_bus_get_from_phy(phy_node, &port->bus); > + if (ret) > + return ret; > } else { > - phy_node = 0; > + /* phy_addr is set to invalid value */ > + phyaddr = PHY_MAX_ADDR; > } > > phy_mode_str = fdt_getprop(gd->fdt_blob, port_node, "phy-mode", NULL); > @@ -4767,7 +4746,6 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) > port->first_rxq = port->id * rxq_number; > else > port->first_rxq = port->id * port->priv->max_port_rxqs; > - port->phy_node = phy_node; > port->phy_interface = phy_mode; > port->phyaddr = phyaddr; > > @@ -5044,119 +5022,7 @@ static int mvpp2_init(struct udevice *dev, struct mvpp2 *priv) > return 0; > } > > -/* SMI / MDIO functions */ > - > -static int smi_wait_ready(struct mvpp2_port *priv) > -{ > - u32 timeout = MVPP2_SMI_TIMEOUT; > - u32 smi_reg; > - > - /* wait till the SMI is not busy */ > - do { > - /* read smi register */ > - smi_reg = readl(priv->mdio_base); > - if (timeout-- == 0) { > - printf("Error: SMI busy timeout\n"); > - return -EFAULT; > - } > - } while (smi_reg & MVPP2_SMI_BUSY); > - > - return 0; > -} > - > -/* > - * mpp2_mdio_read - miiphy_read callback function. > - * > - * Returns 16bit phy register value, or 0xffff on error > - */ > -static int mpp2_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) > -{ > - struct mvpp2_port *priv = bus->priv; > - u32 smi_reg; > - u32 timeout; > - > - /* check parameters */ > - if (addr > MVPP2_PHY_ADDR_MASK) { > - printf("Error: Invalid PHY address %d\n", addr); > - return -EFAULT; > - } > - > - if (reg > MVPP2_PHY_REG_MASK) { > - printf("Err: Invalid register offset %d\n", reg); > - return -EFAULT; > - } > - > - /* wait till the SMI is not busy */ > - if (smi_wait_ready(priv) < 0) > - return -EFAULT; > - > - /* fill the phy address and regiser offset and read opcode */ > - smi_reg = (addr << MVPP2_SMI_DEV_ADDR_OFFS) > - | (reg << MVPP2_SMI_REG_ADDR_OFFS) > - | MVPP2_SMI_OPCODE_READ; > - > - /* write the smi register */ > - writel(smi_reg, priv->mdio_base); > - > - /* wait till read value is ready */ > - timeout = MVPP2_SMI_TIMEOUT; > - > - do { > - /* read smi register */ > - smi_reg = readl(priv->mdio_base); > - if (timeout-- == 0) { > - printf("Err: SMI read ready timeout\n"); > - return -EFAULT; > - } > - } while (!(smi_reg & MVPP2_SMI_READ_VALID)); > - > - /* Wait for the data to update in the SMI register */ > - for (timeout = 0; timeout < MVPP2_SMI_TIMEOUT; timeout++) > - ; > - > - return readl(priv->mdio_base) & MVPP2_SMI_DATA_MASK; > -} > - > -/* > - * mpp2_mdio_write - miiphy_write callback function. > - * > - * Returns 0 if write succeed, -EINVAL on bad parameters > - * -ETIME on timeout > - */ > -static int mpp2_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, > - u16 value) > -{ > - struct mvpp2_port *priv = bus->priv; > - u32 smi_reg; > - > - /* check parameters */ > - if (addr > MVPP2_PHY_ADDR_MASK) { > - printf("Error: Invalid PHY address %d\n", addr); > - return -EFAULT; > - } > - > - if (reg > MVPP2_PHY_REG_MASK) { > - printf("Err: Invalid register offset %d\n", reg); > - return -EFAULT; > - } > - > - /* wait till the SMI is not busy */ > - if (smi_wait_ready(priv) < 0) > - return -EFAULT; > - > - /* fill the phy addr and reg offset and write opcode and data */ > - smi_reg = value << MVPP2_SMI_DATA_OFFS; > - smi_reg |= (addr << MVPP2_SMI_DEV_ADDR_OFFS) > - | (reg << MVPP2_SMI_REG_ADDR_OFFS); > - smi_reg &= ~MVPP2_SMI_OPCODE_READ; > - > - /* write the smi register */ > - writel(smi_reg, priv->mdio_base); > - > - return 0; > -} > - > -static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) > +int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) > { > struct mvpp2_port *port = dev_get_priv(dev); > struct mvpp2_rx_desc *rx_desc; > @@ -5168,7 +5034,7 @@ static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) > struct mvpp2_rx_queue *rxq; > u8 *data; > > - if (port->phy_node) > + if (port->phyaddr < PHY_MAX_ADDR) > if (!port->phy_dev->link) > return 0; > > @@ -5237,7 +5103,7 @@ static int mvpp2_send(struct udevice *dev, void *packet, int length) > int tx_done; > int timeout; > > - if (port->phy_node) > + if (port->phyaddr < PHY_MAX_ADDR) > if (!port->phy_dev->link) > return 0; > > @@ -5474,7 +5340,7 @@ static int mvpp2_probe(struct udevice *dev) > port->gop_id * MVPP22_PORT_OFFSET; > > /* Set phy address of the port */ > - if(port->phy_node) > + if (port->phyaddr < PHY_MAX_ADDR) > mvpp22_smi_phy_addr_cfg(port); > > /* GoP Init */ > -- > 2.21.0 > Reviewed-By: Ramon Fried <rfried.dev@gmail.com>
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index f36c8236b1..b6dfed5c54 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -32,6 +32,7 @@ #include <linux/mbus.h> #include <asm-generic/gpio.h> #include <fdt_support.h> +#include <mdio.h> DECLARE_GLOBAL_DATA_PTR; @@ -62,8 +63,6 @@ do { \ #define MTU 1500 #define RX_BUFFER_SIZE (ALIGN(MTU + WRAP, ARCH_DMA_MINALIGN)) -#define MVPP2_SMI_TIMEOUT 10000 - /* RX Fifo Registers */ #define MVPP2_RX_DATA_FIFO_SIZE_REG(port) (0x00 + 4 * (port)) #define MVPP2_RX_ATTR_FIFO_SIZE_REG(port) (0x20 + 4 * (port)) @@ -490,23 +489,8 @@ do { \ #define MVPP2_QUEUE_NEXT_DESC(q, index) \ (((index) < (q)->last_desc) ? ((index) + 1) : 0) -/* SMI: 0xc0054 -> offset 0x54 to lms_base */ -#define MVPP21_SMI 0x0054 /* PP2.2: SMI: 0x12a200 -> offset 0x1200 to iface_base */ #define MVPP22_SMI 0x1200 -#define MVPP2_PHY_REG_MASK 0x1f -/* SMI register fields */ -#define MVPP2_SMI_DATA_OFFS 0 /* Data */ -#define MVPP2_SMI_DATA_MASK (0xffff << MVPP2_SMI_DATA_OFFS) -#define MVPP2_SMI_DEV_ADDR_OFFS 16 /* PHY device address */ -#define MVPP2_SMI_REG_ADDR_OFFS 21 /* PHY device reg addr*/ -#define MVPP2_SMI_OPCODE_OFFS 26 /* Write/Read opcode */ -#define MVPP2_SMI_OPCODE_READ (1 << MVPP2_SMI_OPCODE_OFFS) -#define MVPP2_SMI_READ_VALID (1 << 27) /* Read Valid */ -#define MVPP2_SMI_BUSY (1 << 28) /* Busy */ - -#define MVPP2_PHY_ADDR_MASK 0x1f -#define MVPP2_PHY_REG_MASK 0x1f /* Additional PPv2.2 offsets */ #define MVPP22_MPCS 0x007000 @@ -973,7 +957,6 @@ struct mvpp2_port { struct phy_device *phy_dev; phy_interface_t phy_interface; - int phy_node; int phyaddr; struct mii_dev *bus; #ifdef CONFIG_DM_GPIO @@ -4562,7 +4545,7 @@ static int mvpp2_open(struct udevice *dev, struct mvpp2_port *port) return err; } - if (port->phy_node) { + if (port->phyaddr < PHY_MAX_ADDR) { mvpp2_phy_connect(dev, port); mvpp2_link_event(port); } else { @@ -4701,6 +4684,7 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) u32 id; u32 phyaddr = 0; int phy_mode = -1; + int ret; /* Default mdio_base from the same eth base */ if (port->priv->hw_version == MVPP21) @@ -4719,17 +4703,12 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) dev_err(&pdev->dev, "could not find phy address\n"); return -1; } - - phy_ofnode = ofnode_get_parent(offset_to_ofnode(phy_node)); - phy_base = ofnode_get_addr(phy_ofnode); - port->mdio_base = (void *)phy_base; - - if (port->mdio_base < 0) { - dev_err(&pdev->dev, "could not find mdio base address\n"); - return -1; - } + ret = mdio_mii_bus_get_from_phy(phy_node, &port->bus); + if (ret) + return ret; } else { - phy_node = 0; + /* phy_addr is set to invalid value */ + phyaddr = PHY_MAX_ADDR; } phy_mode_str = fdt_getprop(gd->fdt_blob, port_node, "phy-mode", NULL); @@ -4767,7 +4746,6 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) port->first_rxq = port->id * rxq_number; else port->first_rxq = port->id * port->priv->max_port_rxqs; - port->phy_node = phy_node; port->phy_interface = phy_mode; port->phyaddr = phyaddr; @@ -5044,119 +5022,7 @@ static int mvpp2_init(struct udevice *dev, struct mvpp2 *priv) return 0; } -/* SMI / MDIO functions */ - -static int smi_wait_ready(struct mvpp2_port *priv) -{ - u32 timeout = MVPP2_SMI_TIMEOUT; - u32 smi_reg; - - /* wait till the SMI is not busy */ - do { - /* read smi register */ - smi_reg = readl(priv->mdio_base); - if (timeout-- == 0) { - printf("Error: SMI busy timeout\n"); - return -EFAULT; - } - } while (smi_reg & MVPP2_SMI_BUSY); - - return 0; -} - -/* - * mpp2_mdio_read - miiphy_read callback function. - * - * Returns 16bit phy register value, or 0xffff on error - */ -static int mpp2_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) -{ - struct mvpp2_port *priv = bus->priv; - u32 smi_reg; - u32 timeout; - - /* check parameters */ - if (addr > MVPP2_PHY_ADDR_MASK) { - printf("Error: Invalid PHY address %d\n", addr); - return -EFAULT; - } - - if (reg > MVPP2_PHY_REG_MASK) { - printf("Err: Invalid register offset %d\n", reg); - return -EFAULT; - } - - /* wait till the SMI is not busy */ - if (smi_wait_ready(priv) < 0) - return -EFAULT; - - /* fill the phy address and regiser offset and read opcode */ - smi_reg = (addr << MVPP2_SMI_DEV_ADDR_OFFS) - | (reg << MVPP2_SMI_REG_ADDR_OFFS) - | MVPP2_SMI_OPCODE_READ; - - /* write the smi register */ - writel(smi_reg, priv->mdio_base); - - /* wait till read value is ready */ - timeout = MVPP2_SMI_TIMEOUT; - - do { - /* read smi register */ - smi_reg = readl(priv->mdio_base); - if (timeout-- == 0) { - printf("Err: SMI read ready timeout\n"); - return -EFAULT; - } - } while (!(smi_reg & MVPP2_SMI_READ_VALID)); - - /* Wait for the data to update in the SMI register */ - for (timeout = 0; timeout < MVPP2_SMI_TIMEOUT; timeout++) - ; - - return readl(priv->mdio_base) & MVPP2_SMI_DATA_MASK; -} - -/* - * mpp2_mdio_write - miiphy_write callback function. - * - * Returns 0 if write succeed, -EINVAL on bad parameters - * -ETIME on timeout - */ -static int mpp2_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, - u16 value) -{ - struct mvpp2_port *priv = bus->priv; - u32 smi_reg; - - /* check parameters */ - if (addr > MVPP2_PHY_ADDR_MASK) { - printf("Error: Invalid PHY address %d\n", addr); - return -EFAULT; - } - - if (reg > MVPP2_PHY_REG_MASK) { - printf("Err: Invalid register offset %d\n", reg); - return -EFAULT; - } - - /* wait till the SMI is not busy */ - if (smi_wait_ready(priv) < 0) - return -EFAULT; - - /* fill the phy addr and reg offset and write opcode and data */ - smi_reg = value << MVPP2_SMI_DATA_OFFS; - smi_reg |= (addr << MVPP2_SMI_DEV_ADDR_OFFS) - | (reg << MVPP2_SMI_REG_ADDR_OFFS); - smi_reg &= ~MVPP2_SMI_OPCODE_READ; - - /* write the smi register */ - writel(smi_reg, priv->mdio_base); - - return 0; -} - -static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) +int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) { struct mvpp2_port *port = dev_get_priv(dev); struct mvpp2_rx_desc *rx_desc; @@ -5168,7 +5034,7 @@ static int mvpp2_recv(struct udevice *dev, int flags, uchar **packetp) struct mvpp2_rx_queue *rxq; u8 *data; - if (port->phy_node) + if (port->phyaddr < PHY_MAX_ADDR) if (!port->phy_dev->link) return 0; @@ -5237,7 +5103,7 @@ static int mvpp2_send(struct udevice *dev, void *packet, int length) int tx_done; int timeout; - if (port->phy_node) + if (port->phyaddr < PHY_MAX_ADDR) if (!port->phy_dev->link) return 0; @@ -5474,7 +5340,7 @@ static int mvpp2_probe(struct udevice *dev) port->gop_id * MVPP22_PORT_OFFSET; /* Set phy address of the port */ - if(port->phy_node) + if (port->phyaddr < PHY_MAX_ADDR) mvpp22_smi_phy_addr_cfg(port); /* GoP Init */