diff mbox series

[U-Boot,v3,2/7] net: mvpp2: Replace SMI implementation with marvell MDIO API

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

Commit Message

Nevo Hed Aug. 6, 2019, 3:51 p.m. UTC
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(-)

Comments

Ramon Fried Aug. 7, 2019, 5:52 p.m. UTC | #1
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 mbox series

Patch

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 */