diff options
| author | Nevo Hed <nhed+github@starry.com> | 2019-08-15 18:08:44 -0400 | 
|---|---|---|
| committer | Joe Hershberger <joe.hershberger@ni.com> | 2019-12-09 09:47:42 -0600 | 
| commit | 2a42870778b78c11d2f4fb1cbc515b5176aaad88 (patch) | |
| tree | 1ae082329f16d9a1412adf644622bf32100ccdb9 /drivers/net/mvpp2.c | |
| parent | 06f555274e9f8a695243bdd791186adb4ffc68e0 (diff) | |
net: mvpp2: use new MVMDIO driver
This commit ports mvpp2 to use the recently introduced Marvell MDIO
(MVMDIO) driver.  It removes direct interaction with the SMI & XSMI
busses.  This commit is based in part on earlier work by
Ken Ma <make@marvell.com> in Marvell's own downstream repo:
https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/c81dc39.
The above refrenced work was based on an MVMDIO implementation that
never made it into U-Boot.  With this patch the mvpp2 driver switches
to use the new MVMDIO driver that is based on a more universal
mdio-uclass implementation.
Signed-off-by: Nevo Hed <nhed+github@starry.com>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'drivers/net/mvpp2.c')
| -rw-r--r-- | drivers/net/mvpp2.c | 195 | 
1 files changed, 18 insertions, 177 deletions
| diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index 64b03bff92f..c5d1f9cf9fb 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -33,6 +33,7 @@  #include <linux/mbus.h>  #include <asm-generic/gpio.h>  #include <fdt_support.h> +#include <linux/mdio.h>  DECLARE_GLOBAL_DATA_PTR; @@ -63,8 +64,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)) @@ -491,23 +490,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 @@ -953,7 +937,6 @@ struct mvpp2_port {  	/* Per-port registers' base address */  	void __iomem *base; -	void __iomem *mdio_base;  	struct mvpp2_rx_queue **rxqs;  	struct mvpp2_tx_queue **txqs; @@ -974,9 +957,8 @@ struct mvpp2_port {  	struct phy_device *phy_dev;  	phy_interface_t phy_interface; -	int phy_node;  	int phyaddr; -	struct mii_dev *bus; +	struct udevice *mdio_dev;  #ifdef CONFIG_DM_GPIO  	struct gpio_desc phy_reset_gpio;  	struct gpio_desc phy_tx_disable_gpio; @@ -4500,8 +4482,8 @@ static void mvpp2_phy_connect(struct udevice *dev, struct mvpp2_port *port)  	struct phy_device *phy_dev;  	if (!port->init || port->link == 0) { -		phy_dev = phy_connect(port->bus, port->phyaddr, dev, -				      port->phy_interface); +		phy_dev = dm_mdio_phy_connect(port->mdio_dev, port->phyaddr, +					      dev, port->phy_interface);  		/*  		 * If the phy doesn't match with any existing u-boot drivers the @@ -4586,7 +4568,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 { @@ -4725,35 +4707,25 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)  	u32 id;  	u32 phyaddr = 0;  	int phy_mode = -1; - -	/* Default mdio_base from the same eth base */ -	if (port->priv->hw_version == MVPP21) -		port->mdio_base = port->priv->lms_base + MVPP21_SMI; -	else -		port->mdio_base = port->priv->iface_base + MVPP22_SMI; +	int ret;  	phy_node = fdtdec_lookup_phandle(gd->fdt_blob, port_node, "phy");  	if (phy_node > 0) { -		ofnode phy_ofnode; -		fdt_addr_t phy_base; - +		int parent;  		phyaddr = fdtdec_get_int(gd->fdt_blob, phy_node, "reg", 0);  		if (phyaddr < 0) {  			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; -		} +		parent = fdt_parent_offset(gd->fdt_blob, phy_node); +		ret = uclass_get_device_by_of_offset(UCLASS_MDIO, parent, +						     &port->mdio_dev); +		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); @@ -4791,7 +4763,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; @@ -5068,118 +5039,6 @@ 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)  {  	struct mvpp2_port *port = dev_get_priv(dev); @@ -5192,7 +5051,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; @@ -5261,7 +5120,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; @@ -5445,31 +5304,13 @@ static int mvpp2_probe(struct udevice *dev)  {  	struct mvpp2_port *port = dev_get_priv(dev);  	struct mvpp2 *priv = dev_get_priv(dev->parent); -	struct mii_dev *bus;  	int err;  	/* Only call the probe function for the parent once */  	if (!priv->probe_done)  		err = mvpp2_base_probe(dev->parent); -	port->priv = dev_get_priv(dev->parent); - -	/* Create and register the MDIO bus driver */ -	bus = mdio_alloc(); -	if (!bus) { -		printf("Failed to allocate MDIO bus\n"); -		return -ENOMEM; -	} - -	bus->read = mpp2_mdio_read; -	bus->write = mpp2_mdio_write; -	snprintf(bus->name, sizeof(bus->name), dev->name); -	bus->priv = (void *)port; -	port->bus = bus; - -	err = mdio_register(bus); -	if (err) -		return err; +	port->priv = priv;  	err = phy_info_parse(dev, port);  	if (err) @@ -5498,7 +5339,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 */ | 
