Merge branch 'net-mdio-ipq4019-add-Clause-45-support'
Robert Marko says: ==================== net: mdio-ipq4019: add Clause 45 support This patch series adds support for Clause 45 to the driver. While at it also change some defines to upper case to match rest of the driver. Changes since v4: * Rebase onto net-next.git Changes since v1: * Drop clock patches, these need further investigation and no user for non default configuration has been found ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
774e9ea665
|
@ -12,6 +12,7 @@
|
|||
#include <linux/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define MDIO_MODE_REG 0x40
|
||||
#define MDIO_ADDR_REG 0x44
|
||||
#define MDIO_DATA_WRITE_REG 0x48
|
||||
#define MDIO_DATA_READ_REG 0x4c
|
||||
|
@ -20,9 +21,15 @@
|
|||
#define MDIO_CMD_ACCESS_START BIT(8)
|
||||
#define MDIO_CMD_ACCESS_CODE_READ 0
|
||||
#define MDIO_CMD_ACCESS_CODE_WRITE 1
|
||||
#define MDIO_CMD_ACCESS_CODE_C45_ADDR 0
|
||||
#define MDIO_CMD_ACCESS_CODE_C45_WRITE 1
|
||||
#define MDIO_CMD_ACCESS_CODE_C45_READ 2
|
||||
|
||||
#define ipq4019_MDIO_TIMEOUT 10000
|
||||
#define ipq4019_MDIO_SLEEP 10
|
||||
/* 0 = Clause 22, 1 = Clause 45 */
|
||||
#define MDIO_MODE_C45 BIT(8)
|
||||
|
||||
#define IPQ4019_MDIO_TIMEOUT 10000
|
||||
#define IPQ4019_MDIO_SLEEP 10
|
||||
|
||||
struct ipq4019_mdio_data {
|
||||
void __iomem *membase;
|
||||
|
@ -35,25 +42,50 @@ static int ipq4019_mdio_wait_busy(struct mii_bus *bus)
|
|||
|
||||
return readl_poll_timeout(priv->membase + MDIO_CMD_REG, busy,
|
||||
(busy & MDIO_CMD_ACCESS_BUSY) == 0,
|
||||
ipq4019_MDIO_SLEEP, ipq4019_MDIO_TIMEOUT);
|
||||
IPQ4019_MDIO_SLEEP, IPQ4019_MDIO_TIMEOUT);
|
||||
}
|
||||
|
||||
static int ipq4019_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
|
||||
{
|
||||
struct ipq4019_mdio_data *priv = bus->priv;
|
||||
unsigned int data;
|
||||
unsigned int cmd;
|
||||
|
||||
/* Reject clause 45 */
|
||||
if (regnum & MII_ADDR_C45)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (ipq4019_mdio_wait_busy(bus))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
/* issue the phy address and reg */
|
||||
writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
|
||||
/* Clause 45 support */
|
||||
if (regnum & MII_ADDR_C45) {
|
||||
unsigned int mmd = (regnum >> 16) & 0x1F;
|
||||
unsigned int reg = regnum & 0xFFFF;
|
||||
|
||||
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_READ;
|
||||
/* Enter Clause 45 mode */
|
||||
data = readl(priv->membase + MDIO_MODE_REG);
|
||||
|
||||
data |= MDIO_MODE_C45;
|
||||
|
||||
writel(data, priv->membase + MDIO_MODE_REG);
|
||||
|
||||
/* issue the phy address and mmd */
|
||||
writel((mii_id << 8) | mmd, priv->membase + MDIO_ADDR_REG);
|
||||
|
||||
/* issue reg */
|
||||
writel(reg, priv->membase + MDIO_DATA_WRITE_REG);
|
||||
|
||||
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_ADDR;
|
||||
} else {
|
||||
/* Enter Clause 22 mode */
|
||||
data = readl(priv->membase + MDIO_MODE_REG);
|
||||
|
||||
data &= ~MDIO_MODE_C45;
|
||||
|
||||
writel(data, priv->membase + MDIO_MODE_REG);
|
||||
|
||||
/* issue the phy address and reg */
|
||||
writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
|
||||
|
||||
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_READ;
|
||||
}
|
||||
|
||||
/* issue read command */
|
||||
writel(cmd, priv->membase + MDIO_CMD_REG);
|
||||
|
@ -62,6 +94,15 @@ static int ipq4019_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
|
|||
if (ipq4019_mdio_wait_busy(bus))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
if (regnum & MII_ADDR_C45) {
|
||||
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_READ;
|
||||
|
||||
writel(cmd, priv->membase + MDIO_CMD_REG);
|
||||
|
||||
if (ipq4019_mdio_wait_busy(bus))
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Read and return data */
|
||||
return readl(priv->membase + MDIO_DATA_READ_REG);
|
||||
}
|
||||
|
@ -70,23 +111,57 @@ static int ipq4019_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
|
|||
u16 value)
|
||||
{
|
||||
struct ipq4019_mdio_data *priv = bus->priv;
|
||||
unsigned int data;
|
||||
unsigned int cmd;
|
||||
|
||||
/* Reject clause 45 */
|
||||
if (regnum & MII_ADDR_C45)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (ipq4019_mdio_wait_busy(bus))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
/* issue the phy address and reg */
|
||||
writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
|
||||
/* Clause 45 support */
|
||||
if (regnum & MII_ADDR_C45) {
|
||||
unsigned int mmd = (regnum >> 16) & 0x1F;
|
||||
unsigned int reg = regnum & 0xFFFF;
|
||||
|
||||
/* Enter Clause 45 mode */
|
||||
data = readl(priv->membase + MDIO_MODE_REG);
|
||||
|
||||
data |= MDIO_MODE_C45;
|
||||
|
||||
writel(data, priv->membase + MDIO_MODE_REG);
|
||||
|
||||
/* issue the phy address and mmd */
|
||||
writel((mii_id << 8) | mmd, priv->membase + MDIO_ADDR_REG);
|
||||
|
||||
/* issue reg */
|
||||
writel(reg, priv->membase + MDIO_DATA_WRITE_REG);
|
||||
|
||||
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_ADDR;
|
||||
|
||||
writel(cmd, priv->membase + MDIO_CMD_REG);
|
||||
|
||||
if (ipq4019_mdio_wait_busy(bus))
|
||||
return -ETIMEDOUT;
|
||||
} else {
|
||||
/* Enter Clause 22 mode */
|
||||
data = readl(priv->membase + MDIO_MODE_REG);
|
||||
|
||||
data &= ~MDIO_MODE_C45;
|
||||
|
||||
writel(data, priv->membase + MDIO_MODE_REG);
|
||||
|
||||
/* issue the phy address and reg */
|
||||
writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
|
||||
}
|
||||
|
||||
/* issue write data */
|
||||
writel(value, priv->membase + MDIO_DATA_WRITE_REG);
|
||||
|
||||
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_WRITE;
|
||||
/* issue write command */
|
||||
if (regnum & MII_ADDR_C45)
|
||||
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_WRITE;
|
||||
else
|
||||
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_WRITE;
|
||||
|
||||
writel(cmd, priv->membase + MDIO_CMD_REG);
|
||||
|
||||
/* Wait write complete */
|
||||
|
|
Loading…
Reference in New Issue