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, 166 "Error while reading PHY%d reg at %d.%d\n", 167 phy_id, dev_addr, regnum); 168 return 0xffff; 169 } 170 171 value = in_be32(®s->mdio_data) & 0xffff; 172 dev_dbg(&bus->dev, "read %04x\n", value); 173 174 return value; 175 } 176 177 /* Reset the MIIM registers, and wait for the bus to free */ 178 static int xgmac_mdio_reset(struct mii_bus *bus) 179 { 180 struct tgec_mdio_controller __iomem *regs = bus->priv; 181 int ret; 182 183 mutex_lock(&bus->mdio_lock); 184 185 /* Setup the MII Mgmt clock speed */ 186 out_be32(®s->mdio_stat, MDIO_STAT_CLKDIV(100)); 187 188 ret = xgmac_wait_until_free(&bus->dev, regs); 189 190 mutex_unlock(&bus->mdio_lock); 191 192 return ret; 193 } 194 195 static int xgmac_mdio_probe(struct platform_device *pdev) 196 { 197 struct device_node *np = pdev->dev.of_node; 198 struct mii_bus *bus; 199 struct resource res; 200 int ret; 201 202 ret = of_address_to_resource(np, 0, &res); 203 if (ret) { 204 dev_err(&pdev->dev, "could not obtain address\n"); 205 return ret; 206 } 207 208 bus = mdiobus_alloc_size(PHY_MAX_ADDR * sizeof(int)); 209 if (!bus) 210 return -ENOMEM; 211 212 bus->name = "Freescale XGMAC MDIO Bus"; 213 bus->read = xgmac_mdio_read; 214 bus->write = xgmac_mdio_write; 215 bus->reset = xgmac_mdio_reset; 216 bus->irq = bus->priv; 217 bus->parent = &pdev->dev; 218 snprintf(bus->id, MII_BUS_ID_SIZE, "%llx", (unsigned long long)res.start); 219 220 /* Set the PHY base address */ 221 bus->priv = of_iomap(np, 0); 222 if (!bus->priv) { 223 ret = -ENOMEM; 224 goto err_ioremap; 225 } 226 227 ret = of_mdiobus_register(bus, np); 228 if (ret) { 229 dev_err(&pdev->dev, "cannot register MDIO bus\n"); 230 goto err_registration; 231 } 232 233 platform_set_drvdata(pdev, bus); 234 235 return 0; 236 237 err_registration: 238 iounmap(bus->priv); 239 240 err_ioremap: 241 mdiobus_free(bus); 242 243 return ret; 244 } 245 246 static int xgmac_mdio_remove(struct platform_device *pdev) 247 { 248 struct mii_bus *bus = platform_get_drvdata(pdev); 249 250 mdiobus_unregister(bus); 251 iounmap(bus->priv); 252 mdiobus_free(bus); 253 254 return 0; 255 } 256 257 static struct of_device_id xgmac_mdio_match[] = { 258 { 259 .compatible = "fsl,fman-xmdio", 260 }, 261 {}, 262 }; 263 MODULE_DEVICE_TABLE(of, xgmac_mdio_match); 264 265 static struct platform_driver xgmac_mdio_driver = { 266 .driver = { 267 .name = "fsl-fman_xmdio", 268 .of_match_table = xgmac_mdio_match, 269 }, 270 .probe = xgmac_mdio_probe, 271 .remove = xgmac_mdio_remove, 272 }; 273 274 module_platform_driver(xgmac_mdio_driver); 275 276 MODULE_DESCRIPTION("Freescale QorIQ 10G MDIO Controller"); 277 MODULE_LICENSE("GPL v2"); 278