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