diff options
author | Horatiu Vultur <horatiu.vultur@microchip.com> | 2019-01-31 17:30:34 +0300 |
---|---|---|
committer | Daniel Schwierzeck <daniel.schwierzeck@gmail.com> | 2019-02-01 16:13:36 +0300 |
commit | 2fff4a9b59855b97f498c2846c5485a65663189b (patch) | |
tree | 9682539fb4199c082b83f11c938c13ad764455a9 /drivers/net/mscc_eswitch/mscc_miim.c | |
parent | 4c66157f427ad87d683b76d6819a00138e9f71dd (diff) | |
download | u-boot-2fff4a9b59855b97f498c2846c5485a65663189b.tar.xz |
net: mscc: Move miim commands into separate file.
Move miim functions that can be shared in a different file inside
mscc_eswitch.
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Diffstat (limited to 'drivers/net/mscc_eswitch/mscc_miim.c')
-rw-r--r-- | drivers/net/mscc_eswitch/mscc_miim.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/drivers/net/mscc_eswitch/mscc_miim.c b/drivers/net/mscc_eswitch/mscc_miim.c new file mode 100644 index 0000000000..419dcc1dd6 --- /dev/null +++ b/drivers/net/mscc_eswitch/mscc_miim.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Microsemi Corporation + */ + +#include <miiphy.h> +#include <wait_bit.h> +#include "mscc_miim.h" + +#define MIIM_STATUS 0x0 +#define MIIM_STAT_BUSY BIT(3) +#define MIIM_CMD 0x8 +#define MIIM_CMD_SCAN BIT(0) +#define MIIM_CMD_OPR_WRITE BIT(1) +#define MIIM_CMD_OPR_READ BIT(2) +#define MIIM_CMD_SINGLE_SCAN BIT(3) +#define MIIM_CMD_WRDATA(x) ((x) << 4) +#define MIIM_CMD_REGAD(x) ((x) << 20) +#define MIIM_CMD_PHYAD(x) ((x) << 25) +#define MIIM_CMD_VLD BIT(31) +#define MIIM_DATA 0xC +#define MIIM_DATA_ERROR (0x2 << 16) + +static int mscc_miim_wait_ready(struct mscc_miim_dev *miim) +{ + return wait_for_bit_le32(miim->regs + MIIM_STATUS, MIIM_STAT_BUSY, + false, 250, false); +} + +int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg) +{ + struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv; + u32 val; + int ret; + + ret = mscc_miim_wait_ready(miim); + if (ret) + goto out; + + writel(MIIM_CMD_VLD | MIIM_CMD_PHYAD(addr) | + MIIM_CMD_REGAD(reg) | MIIM_CMD_OPR_READ, + miim->regs + MIIM_CMD); + + ret = mscc_miim_wait_ready(miim); + if (ret) + goto out; + + val = readl(miim->regs + MIIM_DATA); + if (val & MIIM_DATA_ERROR) { + ret = -EIO; + goto out; + } + + ret = val & 0xFFFF; + out: + return ret; +} + +int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 val) +{ + struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv; + int ret; + + ret = mscc_miim_wait_ready(miim); + if (ret < 0) + goto out; + + writel(MIIM_CMD_VLD | MIIM_CMD_PHYAD(addr) | + MIIM_CMD_REGAD(reg) | MIIM_CMD_WRDATA(val) | + MIIM_CMD_OPR_WRITE, miim->regs + MIIM_CMD); + out: + return ret; +} |