1 /* 2 * QorIQ 10G MDIO Controller 3 * 4 * Copyright 2012 Freescale Semiconductor, Inc. 5 * 6 * Authors: Andy Fleming <afleming@freescale.com> 7 * Timur Tabi <timur@freescale.com> 8 * 9 * This file is licensed under the terms of the GNU General Public License 10 * version 2. This program is licensed "as is" without any warranty of any 11 * kind, whether express or implied. 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/slab.h> 16 #include <linux/interrupt.h> 17 #include <linux/module.h> 18 #include <linux/phy.h> 19 #include <linux/mdio.h> 20 #include <linux/of_address.h> 21 #include <linux/of_platform.h> 22 #include <linux/of_mdio.h> 23 24 /* Number of microseconds to wait for a register to respond */ 25 #define TIMEOUT 1000 26 27 struct tgec_mdio_controller { 28 __be32 reserved[12]; 29 __be32 mdio_stat; /* MDIO configuration and status */ 30 __be32 mdio_ctl; /* MDIO control */ 31 __be32 mdio_data; /* MDIO data */ 32 __be32 mdio_addr; /* MDIO address */ 33 } __packed; 34 35 #define MDIO_STAT_CLKDIV(x) (((x>>1) & 0xff) << 8) 36 #define MDIO_STAT_BSY (1 << 0) 37 #define MDIO_STAT_RD_ER (1 << 1) 38 #define MDIO_CTL_DEV_ADDR(x) (x & 0x1f) 39 #define MDIO_CTL_PORT_ADDR(x) ((x & 0x1f) << 5) 40 #define MDIO_CTL_PRE_DIS (1 << 10) 41 #define MDIO_CTL_SCAN_EN (1 << 11) 42 #define MDIO_CTL_POST_INC (1 << 14) 43 #define MDIO_CTL_READ (1 << 15) 44 45 #define MDIO_DATA(x) (x & 0xffff) 46 #define MDIO_DATA_BSY (1 << 31) 47 48 /* 49 * Wait untill the MDIO bus is free 50 */ 51 static int xgmac_wait_until_free(struct device *dev, 52 struct tgec_mdio_controller __iomem *regs) 53 { 54 uint32_t status; 55 56 /* Wait till the bus is free */ 57 status = spin_event_timeout( 58 !((in_be32(®s->mdio_stat)) & MDIO_STAT_BSY), TIMEOUT, 0); 59 if (!status) { 60 dev_err(dev, "timeout waiting for bus to be free\n"); 61 return -ETIMEDOUT; 62 } 63 64 return 0; 65 } 66 67 /* 68 * Wait till the MDIO read or write operation is complete 69 */ 70 static int xgmac_wait_until_done(struct device *dev, 71 struct tgec_mdio_controller __iomem *regs) 72 { 73 uint32_t status; 74 75 /* Wait till the MDIO write is complete */ 76 status = spin_event_timeout( 77 !((in_be32(®s->mdio_data)) & MDIO_DATA_BSY), TIMEOUT, 0); 78 if (!status) { 79 dev_err(dev, "timeout waiting for operation to complete\n"); 80 return -ETIMEDOUT; 81 } 82 83 return 0; 84 } 85 86 /* 87 * Write value to the PHY for this device to the register at regnum,waiting 88 * until the write is done before it returns. All PHY configuration has to be 89 * done through the TSEC1 MIIM regs. 90 */ 91 static int xgmac_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value) 92 { 93 struct tgec_mdio_controller __iomem *regs = bus->priv; 94 uint16_t dev_addr = regnum >> 16; 95 int ret; 96 97 /* Setup the MII Mgmt clock speed */ 98 out_be32(®s->mdio_stat, MDIO_STAT_CLKDIV(100)); 99 100 ret = xgmac_wait_until_free(&bus->dev, regs); 101 if (ret) 102 return ret; 103 104 /* Set the port and dev addr */ 105 out_be32(®s->mdio_ctl, 106 MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr)); 107 108 /* Set the register address */ 109 out_be32(®s->mdio_addr, regnum & 0xffff); 110 111 ret = xgmac_wait_until_free(&bus->dev, regs); 112 if (ret) 113 return ret; 114 115 /* Write the value to the register */ 116 out_be32(®s->mdio_data, MDIO_DATA(value)); 117 118 ret = xgmac_wait_until_done(&bus->dev, regs); 119 if (ret) 120 return ret; 121 122 return 0; 123 } 124 125 /* 126 * Reads from register regnum in the PHY for device dev, returning the value. 127 * Clears miimcom first. All PHY configuration has to be done through the 128 * TSEC1 MIIM regs. 129 */ 130 static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum) 131 { 132 struct tgec_mdio_controller __iomem *regs = bus->priv; 133 uint16_t dev_addr = regnum >> 16; 134 uint32_t mdio_ctl; 135 uint16_t value; 136 int ret; 137 138 /* Setup the MII Mgmt clock speed */ 139 out_be32(®s->mdio_stat, MDIO_STAT_CLKDIV(100)); 140 141 ret = xgmac_wait_until_free(&bus->dev, regs); 142 if (ret) 143 return ret; 144 145 /* Set the Port and Device Addrs */ 146 mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr); 147 out_be32(®s->mdio_ctl, mdio_ctl); 148 149 /* Set the register address */ 150 out_be32(®s->mdio_addr, regnum & 0xffff); 151 152 ret = xgmac_wait_until_free(&bus->dev, regs); 153 if (ret) 154 return ret; 155 156 /* Initiate the read */ 157 out_be32(®s->mdio_ctl, mdio_ctl | MDIO_CTL_READ); 158 159 ret = xgmac_wait_until_done(&bus->dev, regs); 160 if (ret) 161 return ret; 162 163 /* Return all Fs if nothing was there */ 164 if (in_be32(®s->mdio_stat) & MDIO_STAT_RD_ER) { 165 dev_err(&bus->dev, "MDIO read error\n"); 166 return 0xffff; 167 } 168 169 value = in_be32(®s->mdio_data) & 0xffff; 170 dev_dbg(&bus->dev, "read %04x\n", value); 171 172 return value; 173 } 174 175 /* Reset the MIIM registers, and wait for the bus to free */ 176 static int xgmac_mdio_reset(struct mii_bus *bus) 177 { 178 struct tgec_mdio_controller __iomem *regs = bus->priv; 179 int ret; 180 181 mutex_lock(&bus->mdio_lock); 182 183 /* Setup the MII Mgmt clock speed */ 184 out_be32(®s->mdio_stat, MDIO_STAT_CLKDIV(100)); 185 186 ret = xgmac_wait_until_free(&bus->dev, regs); 187 188 mutex_unlock(&bus->mdio_lock); 189 190 return ret; 191 } 192 193 static int xgmac_mdio_probe(struct platform_device *pdev) 194 { 195 struct device_node *np = pdev->dev.of_node; 196 struct mii_bus *bus; 197 struct resource res; 198 int ret; 199 200 ret = of_address_to_resource(np, 0, &res); 201 if (ret) { 202 dev_err(&pdev->dev, "could not obtain address\n"); 203 return ret; 204 } 205 206 bus = mdiobus_alloc_size(PHY_MAX_ADDR * sizeof(int)); 207 if (!bus) 208 return -ENOMEM; 209 210 bus->name = "Freescale XGMAC MDIO Bus"; 211 bus->read = xgmac_mdio_read; 212 bus->write = xgmac_mdio_write; 213 bus->reset = xgmac_mdio_reset; 214 bus->irq = bus->priv; 215 bus->parent = &pdev->dev; 216 snprintf(bus->id, MII_BUS_ID_SIZE, "%llx", (unsigned long long)res.start); 217 218 /* Set the PHY base address */ 219 bus->priv = of_iomap(np, 0); 220 if (!bus->priv) { 221 ret = -ENOMEM; 222 goto err_ioremap; 223 } 224 225 ret = of_mdiobus_register(bus, np); 226 if (ret) { 227 dev_err(&pdev->dev, "cannot register MDIO bus\n"); 228 goto err_registration; 229 } 230 231 platform_set_drvdata(pdev, bus); 232 233 return 0; 234 235 err_registration: 236 iounmap(bus->priv); 237 238 err_ioremap: 239 mdiobus_free(bus); 240 241 return ret; 242 } 243 244 static int xgmac_mdio_remove(struct platform_device *pdev) 245 { 246 struct mii_bus *bus = platform_get_drvdata(pdev); 247 248 mdiobus_unregister(bus); 249 iounmap(bus->priv); 250 mdiobus_free(bus); 251 252 return 0; 253 } 254 255 static struct of_device_id xgmac_mdio_match[] = { 256 { 257 .compatible = "fsl,fman-xmdio", 258 }, 259 {}, 260 }; 261 MODULE_DEVICE_TABLE(of, xgmac_mdio_match); 262 263 static struct platform_driver xgmac_mdio_driver = { 264 .driver = { 265 .name = "fsl-fman_xmdio", 266 .of_match_table = xgmac_mdio_match, 267 }, 268 .probe = xgmac_mdio_probe, 269 .remove = xgmac_mdio_remove, 270 }; 271 272 module_platform_driver(xgmac_mdio_driver); 273 274 MODULE_DESCRIPTION("Freescale QorIQ 10G MDIO Controller"); 275 MODULE_LICENSE("GPL v2"); 276