1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 /* Copyright 2019 NXP */ 3 4 #include <linux/mdio.h> 5 #include <linux/of_mdio.h> 6 #include <linux/iopoll.h> 7 #include <linux/of.h> 8 9 #include "enetc_mdio.h" 10 11 #define ENETC_MDIO_REG_OFFSET 0x1c00 12 #define ENETC_MDIO_CFG 0x0 /* MDIO configuration and status */ 13 #define ENETC_MDIO_CTL 0x4 /* MDIO control */ 14 #define ENETC_MDIO_DATA 0x8 /* MDIO data */ 15 #define ENETC_MDIO_ADDR 0xc /* MDIO address */ 16 17 #define enetc_mdio_rd(hw, off) \ 18 enetc_port_rd(hw, ENETC_##off + ENETC_MDIO_REG_OFFSET) 19 #define enetc_mdio_wr(hw, off, val) \ 20 enetc_port_wr(hw, ENETC_##off + ENETC_MDIO_REG_OFFSET, val) 21 #define enetc_mdio_rd_reg(off) enetc_mdio_rd(hw, off) 22 23 #define ENETC_MDC_DIV 258 24 25 #define MDIO_CFG_CLKDIV(x) ((((x) >> 1) & 0xff) << 8) 26 #define MDIO_CFG_BSY BIT(0) 27 #define MDIO_CFG_RD_ER BIT(1) 28 #define MDIO_CFG_ENC45 BIT(6) 29 /* external MDIO only - driven on neg MDC edge */ 30 #define MDIO_CFG_NEG BIT(23) 31 32 #define MDIO_CTL_DEV_ADDR(x) ((x) & 0x1f) 33 #define MDIO_CTL_PORT_ADDR(x) (((x) & 0x1f) << 5) 34 #define MDIO_CTL_READ BIT(15) 35 #define MDIO_DATA(x) ((x) & 0xffff) 36 37 #define TIMEOUT 1000 38 static int enetc_mdio_wait_complete(struct enetc_hw *hw) 39 { 40 u32 val; 41 42 return readx_poll_timeout(enetc_mdio_rd_reg, MDIO_CFG, val, 43 !(val & MDIO_CFG_BSY), 10, 10 * TIMEOUT); 44 } 45 46 int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value) 47 { 48 struct enetc_mdio_priv *mdio_priv = bus->priv; 49 struct enetc_hw *hw = mdio_priv->hw; 50 u32 mdio_ctl, mdio_cfg; 51 u16 dev_addr; 52 int ret; 53 54 mdio_cfg = MDIO_CFG_CLKDIV(ENETC_MDC_DIV) | MDIO_CFG_NEG; 55 if (regnum & MII_ADDR_C45) { 56 dev_addr = (regnum >> 16) & 0x1f; 57 mdio_cfg |= MDIO_CFG_ENC45; 58 } else { 59 /* clause 22 (ie 1G) */ 60 dev_addr = regnum & 0x1f; 61 mdio_cfg &= ~MDIO_CFG_ENC45; 62 } 63 64 enetc_mdio_wr(hw, MDIO_CFG, mdio_cfg); 65 66 ret = enetc_mdio_wait_complete(hw); 67 if (ret) 68 return ret; 69 70 /* set port and dev addr */ 71 mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr); 72 enetc_mdio_wr(hw, MDIO_CTL, mdio_ctl); 73 74 /* set the register address */ 75 if (regnum & MII_ADDR_C45) { 76 enetc_mdio_wr(hw, MDIO_ADDR, regnum & 0xffff); 77 78 ret = enetc_mdio_wait_complete(hw); 79 if (ret) 80 return ret; 81 } 82 83 /* write the value */ 84 enetc_mdio_wr(hw, MDIO_DATA, MDIO_DATA(value)); 85 86 ret = enetc_mdio_wait_complete(hw); 87 if (ret) 88 return ret; 89 90 return 0; 91 } 92 93 int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum) 94 { 95 struct enetc_mdio_priv *mdio_priv = bus->priv; 96 struct enetc_hw *hw = mdio_priv->hw; 97 u32 mdio_ctl, mdio_cfg; 98 u16 dev_addr, value; 99 int ret; 100 101 mdio_cfg = MDIO_CFG_CLKDIV(ENETC_MDC_DIV) | MDIO_CFG_NEG; 102 if (regnum & MII_ADDR_C45) { 103 dev_addr = (regnum >> 16) & 0x1f; 104 mdio_cfg |= MDIO_CFG_ENC45; 105 } else { 106 dev_addr = regnum & 0x1f; 107 mdio_cfg &= ~MDIO_CFG_ENC45; 108 } 109 110 enetc_mdio_wr(hw, MDIO_CFG, mdio_cfg); 111 112 ret = enetc_mdio_wait_complete(hw); 113 if (ret) 114 return ret; 115 116 /* set port and device addr */ 117 mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr); 118 enetc_mdio_wr(hw, MDIO_CTL, mdio_ctl); 119 120 /* set the register address */ 121 if (regnum & MII_ADDR_C45) { 122 enetc_mdio_wr(hw, MDIO_ADDR, regnum & 0xffff); 123 124 ret = enetc_mdio_wait_complete(hw); 125 if (ret) 126 return ret; 127 } 128 129 /* initiate the read */ 130 enetc_mdio_wr(hw, MDIO_CTL, mdio_ctl | MDIO_CTL_READ); 131 132 ret = enetc_mdio_wait_complete(hw); 133 if (ret) 134 return ret; 135 136 /* return all Fs if nothing was there */ 137 if (enetc_mdio_rd(hw, MDIO_CFG) & MDIO_CFG_RD_ER) { 138 dev_dbg(&bus->dev, 139 "Error while reading PHY%d reg at %d.%hhu\n", 140 phy_id, dev_addr, regnum); 141 return 0xffff; 142 } 143 144 value = enetc_mdio_rd(hw, MDIO_DATA) & 0xffff; 145 146 return value; 147 } 148 149 int enetc_mdio_probe(struct enetc_pf *pf) 150 { 151 struct device *dev = &pf->si->pdev->dev; 152 struct enetc_mdio_priv *mdio_priv; 153 struct device_node *np; 154 struct mii_bus *bus; 155 int err; 156 157 bus = devm_mdiobus_alloc_size(dev, sizeof(*mdio_priv)); 158 if (!bus) 159 return -ENOMEM; 160 161 bus->name = "Freescale ENETC MDIO Bus"; 162 bus->read = enetc_mdio_read; 163 bus->write = enetc_mdio_write; 164 bus->parent = dev; 165 mdio_priv = bus->priv; 166 mdio_priv->hw = &pf->si->hw; 167 snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev)); 168 169 np = of_get_child_by_name(dev->of_node, "mdio"); 170 if (!np) { 171 dev_err(dev, "MDIO node missing\n"); 172 return -EINVAL; 173 } 174 175 err = of_mdiobus_register(bus, np); 176 if (err) { 177 of_node_put(np); 178 dev_err(dev, "cannot register MDIO bus\n"); 179 return err; 180 } 181 182 of_node_put(np); 183 pf->mdio = bus; 184 185 return 0; 186 } 187 188 void enetc_mdio_remove(struct enetc_pf *pf) 189 { 190 if (pf->mdio) 191 mdiobus_unregister(pf->mdio); 192 } 193