Skip to content

Commit

Permalink
mvpp2: Replace SMI implementation with marvell MDIO API
Browse files Browse the repository at this point in the history
Since marvell MDIO driver is added, SMI function implementation in
mvpp2 driver can be removed and NETA driver can use marvell MDIO API
directly.
This replacement also fixes 2 old issues:
1. Each pp2 port device should have 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 its all 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 will be generated from
   the mdio bus base address, so this issue is fixed by this
   replacement.

Change-Id: I382d4be042d0a4fec5d4fc83646897a11144b7b5
Signed-off-by: Ken Ma <make@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/55404
Reviewed-by: Igal Liberman <igall@marvell.com>
Tested-by: Igal Liberman <igall@marvell.com>
  • Loading branch information
makemarvell authored and igalil86 committed May 28, 2018
1 parent c6e30c7 commit c81dc39
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 183 deletions.
1 change: 1 addition & 0 deletions drivers/net/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ config MVPP2
bool "Marvell Armada 375/7K/8K network interface support"
depends on ARMADA_375 || ARMADA_8K
select PHYLIB
select MVMDIO
help
This driver supports the network interface units in the
Marvell ARMADA 375, 7K and 8K SoCs.
Expand Down
198 changes: 15 additions & 183 deletions drivers/net/mvpp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <linux/mbus.h>
#include <asm-generic/gpio.h>
#include <fdt_support.h>
#include <mdio.h>

DECLARE_GLOBAL_DATA_PTR;

Expand Down Expand Up @@ -75,8 +76,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))
Expand Down Expand Up @@ -503,23 +502,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
Expand Down Expand Up @@ -910,7 +894,6 @@ struct mvpp2 {
void __iomem *base;
void __iomem *lms_base;
void __iomem *iface_base;
void __iomem *mdio_base;

void __iomem *mpcs_base;
void __iomem *xpcs_base;
Expand Down Expand Up @@ -941,8 +924,6 @@ struct mvpp2 {
/* Maximum number of RXQs per port */
unsigned int max_port_rxqs;

struct mii_dev *bus;

int probe_done;
u8 num_ports;
};
Expand Down Expand Up @@ -988,8 +969,8 @@ 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
struct gpio_desc phy_reset_gpio;
struct gpio_desc phy_tx_disable_gpio;
Expand Down Expand Up @@ -4512,7 +4493,7 @@ 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->priv->bus, port->phyaddr, dev,
phy_dev = phy_connect(port->bus, port->phyaddr, dev,
port->phy_interface);
port->phy_dev = phy_dev;
if (!phy_dev) {
Expand Down Expand Up @@ -4575,7 +4556,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 {
Expand Down Expand Up @@ -4710,11 +4691,11 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
{
int port_node = dev_of_offset(dev);
const char *phy_mode_str;
int phy_node, mdio_off, cp_node;
int phy_node;
u32 id;
u32 phyaddr = 0;
int phy_mode = -1;
phys_addr_t mdio_addr;
int ret;

phy_node = fdtdec_lookup_phandle(gd->fdt_blob, port_node, "phy");

Expand All @@ -4724,30 +4705,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;
}
mdio_off = fdt_parent_offset(gd->fdt_blob, phy_node);

/* TODO: This WA for mdio issue. U-boot 2017 don't have
* mdio driver and on MACHIATOBin board ports from CP1
* connected to mdio on CP0.
* WA is to get mdio address from phy handler parent
* base address. WA should be removed after
* mdio driver implementation.
*/
mdio_addr = fdtdec_get_uint(gd->fdt_blob,
mdio_off, "reg", 0);

cp_node = fdt_parent_offset(gd->fdt_blob, mdio_off);
mdio_addr |= fdt_get_base_address((void *)gd->fdt_blob,
cp_node);

port->priv->mdio_base = (void *)mdio_addr;

if (port->priv->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);
Expand Down Expand Up @@ -4785,7 +4748,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;

Expand Down Expand Up @@ -5064,118 +5026,6 @@ static int mvpp2_init(struct udevice *dev, struct mvpp2 *priv)
return 0;
}

/* SMI / MDIO functions */

static int smi_wait_ready(struct mvpp2 *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 *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 *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);
Expand All @@ -5188,7 +5038,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;

Expand Down Expand Up @@ -5257,7 +5107,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;

Expand Down Expand Up @@ -5353,7 +5203,6 @@ static int mvpp22_smi_phy_addr_cfg(struct mvpp2_port *port)
static int mvpp2_base_probe(struct udevice *dev)
{
struct mvpp2 *priv = dev_get_priv(dev);
struct mii_dev *bus;
void *bd_space;
u32 size = 0;
int i;
Expand Down Expand Up @@ -5412,15 +5261,11 @@ static int mvpp2_base_probe(struct udevice *dev)
priv->lms_base = (void *)devfdt_get_addr_index(dev, 1);
if (IS_ERR(priv->lms_base))
return PTR_ERR(priv->lms_base);

priv->mdio_base = priv->lms_base + MVPP21_SMI;
} else {
priv->iface_base = (void *)devfdt_get_addr_index(dev, 1);
if (IS_ERR(priv->iface_base))
return PTR_ERR(priv->iface_base);

priv->mdio_base = priv->iface_base + MVPP22_SMI;

/* Store common base addresses for all ports */
priv->mpcs_base = priv->iface_base + MVPP22_MPCS;
priv->xpcs_base = priv->iface_base + MVPP22_XPCS;
Expand All @@ -5432,20 +5277,7 @@ static int mvpp2_base_probe(struct udevice *dev)
else
priv->max_port_rxqs = 32;

/* Finally 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 *)priv;
priv->bus = bus;

return mdio_register(bus);
return 0;
}

static int mvpp2_probe(struct udevice *dev)
Expand Down Expand Up @@ -5487,7 +5319,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 */
Expand Down

0 comments on commit c81dc39

Please sign in to comment.