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