1 /* 2 * Driver for the MDIO interface of Marvell network interfaces. 3 * 4 * Since the MDIO interface of Marvell network interfaces is shared 5 * between all network interfaces, having a single driver allows to 6 * handle concurrent accesses properly (you may have four Ethernet 7 * ports, but they in fact share the same SMI interface to access 8 * the MDIO bus). This driver is currently used by the mvneta and 9 * mv643xx_eth drivers. 10 * 11 * Copyright (C) 2012 Marvell 12 * 13 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 14 * 15 * This file is licensed under the terms of the GNU General Public 16 * License version 2. This program is licensed "as is" without any 17 * warranty of any kind, whether express or implied. 18 */ 19 20 #include <linux/acpi.h> 21 #include <linux/acpi_mdio.h> 22 #include <linux/clk.h> 23 #include <linux/delay.h> 24 #include <linux/interrupt.h> 25 #include <linux/io.h> 26 #include <linux/iopoll.h> 27 #include <linux/kernel.h> 28 #include <linux/mod_devicetable.h> 29 #include <linux/module.h> 30 #include <linux/of_mdio.h> 31 #include <linux/phy.h> 32 #include <linux/platform_device.h> 33 #include <linux/sched.h> 34 #include <linux/wait.h> 35 36 #define MVMDIO_SMI_DATA_SHIFT 0 37 #define MVMDIO_SMI_PHY_ADDR_SHIFT 16 38 #define MVMDIO_SMI_PHY_REG_SHIFT 21 39 #define MVMDIO_SMI_READ_OPERATION BIT(26) 40 #define MVMDIO_SMI_WRITE_OPERATION 0 41 #define MVMDIO_SMI_READ_VALID BIT(27) 42 #define MVMDIO_SMI_BUSY BIT(28) 43 #define MVMDIO_ERR_INT_CAUSE 0x007C 44 #define MVMDIO_ERR_INT_SMI_DONE 0x00000010 45 #define MVMDIO_ERR_INT_MASK 0x0080 46 47 #define MVMDIO_XSMI_MGNT_REG 0x0 48 #define MVMDIO_XSMI_PHYADDR_SHIFT 16 49 #define MVMDIO_XSMI_DEVADDR_SHIFT 21 50 #define MVMDIO_XSMI_WRITE_OPERATION (0x5 << 26) 51 #define MVMDIO_XSMI_READ_OPERATION (0x7 << 26) 52 #define MVMDIO_XSMI_READ_VALID BIT(29) 53 #define MVMDIO_XSMI_BUSY BIT(30) 54 #define MVMDIO_XSMI_ADDR_REG 0x8 55 56 /* 57 * SMI Timeout measurements: 58 * - Kirkwood 88F6281 (Globalscale Dreamplug): 45us to 95us (Interrupt) 59 * - Armada 370 (Globalscale Mirabox): 41us to 43us (Polled) 60 */ 61 #define MVMDIO_SMI_TIMEOUT 1000 /* 1000us = 1ms */ 62 63 struct orion_mdio_dev { 64 void __iomem *regs; 65 struct clk *clk[4]; 66 /* 67 * If we have access to the error interrupt pin (which is 68 * somewhat misnamed as it not only reflects internal errors 69 * but also reflects SMI completion), use that to wait for 70 * SMI access completion instead of polling the SMI busy bit. 71 */ 72 int err_interrupt; 73 wait_queue_head_t smi_busy_wait; 74 }; 75 76 enum orion_mdio_bus_type { 77 BUS_TYPE_SMI, 78 BUS_TYPE_XSMI 79 }; 80 81 struct orion_mdio_ops { 82 int (*is_done)(struct orion_mdio_dev *); 83 }; 84 85 /* Wait for the SMI unit to be ready for another operation 86 */ 87 static int orion_mdio_wait_ready(const struct orion_mdio_ops *ops, 88 struct mii_bus *bus) 89 { 90 struct orion_mdio_dev *dev = bus->priv; 91 unsigned long timeout; 92 int done; 93 94 if (dev->err_interrupt <= 0) { 95 if (!read_poll_timeout_atomic(ops->is_done, done, done, 2, 96 MVMDIO_SMI_TIMEOUT, false, dev)) 97 return 0; 98 } else { 99 /* wait_event_timeout does not guarantee a delay of at 100 * least one whole jiffie, so timeout must be no less 101 * than two. 102 */ 103 timeout = max(usecs_to_jiffies(MVMDIO_SMI_TIMEOUT), 2); 104 105 if (wait_event_timeout(dev->smi_busy_wait, 106 ops->is_done(dev), timeout)) 107 return 0; 108 } 109 110 dev_err(bus->parent, "Timeout: SMI busy for too long\n"); 111 return -ETIMEDOUT; 112 } 113 114 static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev) 115 { 116 return !(readl(dev->regs) & MVMDIO_SMI_BUSY); 117 } 118 119 static const struct orion_mdio_ops orion_mdio_smi_ops = { 120 .is_done = orion_mdio_smi_is_done, 121 }; 122 123 static int orion_mdio_smi_read(struct mii_bus *bus, int mii_id, 124 int regnum) 125 { 126 struct orion_mdio_dev *dev = bus->priv; 127 u32 val; 128 int ret; 129 130 ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus); 131 if (ret < 0) 132 return ret; 133 134 writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) | 135 (regnum << MVMDIO_SMI_PHY_REG_SHIFT) | 136 MVMDIO_SMI_READ_OPERATION), 137 dev->regs); 138 139 ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus); 140 if (ret < 0) 141 return ret; 142 143 val = readl(dev->regs); 144 if (!(val & MVMDIO_SMI_READ_VALID)) { 145 dev_err(bus->parent, "SMI bus read not valid\n"); 146 return -ENODEV; 147 } 148 149 return val & GENMASK(15, 0); 150 } 151 152 static int orion_mdio_smi_write(struct mii_bus *bus, int mii_id, 153 int regnum, u16 value) 154 { 155 struct orion_mdio_dev *dev = bus->priv; 156 int ret; 157 158 ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus); 159 if (ret < 0) 160 return ret; 161 162 writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) | 163 (regnum << MVMDIO_SMI_PHY_REG_SHIFT) | 164 MVMDIO_SMI_WRITE_OPERATION | 165 (value << MVMDIO_SMI_DATA_SHIFT)), 166 dev->regs); 167 168 return 0; 169 } 170 171 static int orion_mdio_xsmi_is_done(struct orion_mdio_dev *dev) 172 { 173 return !(readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & MVMDIO_XSMI_BUSY); 174 } 175 176 static const struct orion_mdio_ops orion_mdio_xsmi_ops = { 177 .is_done = orion_mdio_xsmi_is_done, 178 }; 179 180 static int orion_mdio_xsmi_read_c45(struct mii_bus *bus, int mii_id, 181 int dev_addr, int regnum) 182 { 183 struct orion_mdio_dev *dev = bus->priv; 184 int ret; 185 186 ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus); 187 if (ret < 0) 188 return ret; 189 190 writel(regnum, dev->regs + MVMDIO_XSMI_ADDR_REG); 191 writel((mii_id << MVMDIO_XSMI_PHYADDR_SHIFT) | 192 (dev_addr << MVMDIO_XSMI_DEVADDR_SHIFT) | 193 MVMDIO_XSMI_READ_OPERATION, 194 dev->regs + MVMDIO_XSMI_MGNT_REG); 195 196 ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus); 197 if (ret < 0) 198 return ret; 199 200 if (!(readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & 201 MVMDIO_XSMI_READ_VALID)) { 202 dev_err(bus->parent, "XSMI bus read not valid\n"); 203 return -ENODEV; 204 } 205 206 return readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & GENMASK(15, 0); 207 } 208 209 static int orion_mdio_xsmi_write_c45(struct mii_bus *bus, int mii_id, 210 int dev_addr, int regnum, u16 value) 211 { 212 struct orion_mdio_dev *dev = bus->priv; 213 int ret; 214 215 ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus); 216 if (ret < 0) 217 return ret; 218 219 writel(regnum, dev->regs + MVMDIO_XSMI_ADDR_REG); 220 writel((mii_id << MVMDIO_XSMI_PHYADDR_SHIFT) | 221 (dev_addr << MVMDIO_XSMI_DEVADDR_SHIFT) | 222 MVMDIO_XSMI_WRITE_OPERATION | value, 223 dev->regs + MVMDIO_XSMI_MGNT_REG); 224 225 return 0; 226 } 227 228 static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id) 229 { 230 struct orion_mdio_dev *dev = dev_id; 231 232 if (readl(dev->regs + MVMDIO_ERR_INT_CAUSE) & 233 MVMDIO_ERR_INT_SMI_DONE) { 234 writel(~MVMDIO_ERR_INT_SMI_DONE, 235 dev->regs + MVMDIO_ERR_INT_CAUSE); 236 wake_up(&dev->smi_busy_wait); 237 return IRQ_HANDLED; 238 } 239 240 return IRQ_NONE; 241 } 242 243 static int orion_mdio_probe(struct platform_device *pdev) 244 { 245 enum orion_mdio_bus_type type; 246 struct resource *r; 247 struct mii_bus *bus; 248 struct orion_mdio_dev *dev; 249 int i, ret; 250 251 type = (uintptr_t)device_get_match_data(&pdev->dev); 252 253 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 254 if (!r) { 255 dev_err(&pdev->dev, "No SMI register address given\n"); 256 return -ENODEV; 257 } 258 259 bus = devm_mdiobus_alloc_size(&pdev->dev, 260 sizeof(struct orion_mdio_dev)); 261 if (!bus) 262 return -ENOMEM; 263 264 switch (type) { 265 case BUS_TYPE_SMI: 266 bus->read = orion_mdio_smi_read; 267 bus->write = orion_mdio_smi_write; 268 break; 269 case BUS_TYPE_XSMI: 270 bus->read_c45 = orion_mdio_xsmi_read_c45; 271 bus->write_c45 = orion_mdio_xsmi_write_c45; 272 break; 273 } 274 275 bus->name = "orion_mdio_bus"; 276 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", 277 dev_name(&pdev->dev)); 278 bus->parent = &pdev->dev; 279 280 dev = bus->priv; 281 dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); 282 if (!dev->regs) { 283 dev_err(&pdev->dev, "Unable to remap SMI register\n"); 284 return -ENODEV; 285 } 286 287 init_waitqueue_head(&dev->smi_busy_wait); 288 289 if (pdev->dev.of_node) { 290 for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { 291 dev->clk[i] = of_clk_get(pdev->dev.of_node, i); 292 if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) { 293 ret = -EPROBE_DEFER; 294 goto out_clk; 295 } 296 if (IS_ERR(dev->clk[i])) 297 break; 298 clk_prepare_enable(dev->clk[i]); 299 } 300 301 if (!IS_ERR(of_clk_get(pdev->dev.of_node, 302 ARRAY_SIZE(dev->clk)))) 303 dev_warn(&pdev->dev, 304 "unsupported number of clocks, limiting to the first " 305 __stringify(ARRAY_SIZE(dev->clk)) "\n"); 306 } else { 307 dev->clk[0] = clk_get(&pdev->dev, NULL); 308 if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) { 309 ret = -EPROBE_DEFER; 310 goto out_clk; 311 } 312 if (!IS_ERR(dev->clk[0])) 313 clk_prepare_enable(dev->clk[0]); 314 } 315 316 317 dev->err_interrupt = platform_get_irq_optional(pdev, 0); 318 if (dev->err_interrupt > 0 && 319 resource_size(r) < MVMDIO_ERR_INT_MASK + 4) { 320 dev_err(&pdev->dev, 321 "disabling interrupt, resource size is too small\n"); 322 dev->err_interrupt = 0; 323 } 324 if (dev->err_interrupt > 0) { 325 ret = devm_request_irq(&pdev->dev, dev->err_interrupt, 326 orion_mdio_err_irq, 327 IRQF_SHARED, pdev->name, dev); 328 if (ret) 329 goto out_mdio; 330 331 writel(MVMDIO_ERR_INT_SMI_DONE, 332 dev->regs + MVMDIO_ERR_INT_MASK); 333 334 } else if (dev->err_interrupt == -EPROBE_DEFER) { 335 ret = -EPROBE_DEFER; 336 goto out_mdio; 337 } 338 339 /* For the platforms not supporting DT/ACPI fall-back 340 * to mdiobus_register via of_mdiobus_register. 341 */ 342 if (is_acpi_node(pdev->dev.fwnode)) 343 ret = acpi_mdiobus_register(bus, pdev->dev.fwnode); 344 else 345 ret = of_mdiobus_register(bus, pdev->dev.of_node); 346 if (ret < 0) { 347 dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret); 348 goto out_mdio; 349 } 350 351 platform_set_drvdata(pdev, bus); 352 353 return 0; 354 355 out_mdio: 356 if (dev->err_interrupt > 0) 357 writel(0, dev->regs + MVMDIO_ERR_INT_MASK); 358 359 out_clk: 360 for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { 361 if (IS_ERR(dev->clk[i])) 362 break; 363 clk_disable_unprepare(dev->clk[i]); 364 clk_put(dev->clk[i]); 365 } 366 367 return ret; 368 } 369 370 static int orion_mdio_remove(struct platform_device *pdev) 371 { 372 struct mii_bus *bus = platform_get_drvdata(pdev); 373 struct orion_mdio_dev *dev = bus->priv; 374 int i; 375 376 if (dev->err_interrupt > 0) 377 writel(0, dev->regs + MVMDIO_ERR_INT_MASK); 378 mdiobus_unregister(bus); 379 380 for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { 381 if (IS_ERR(dev->clk[i])) 382 break; 383 clk_disable_unprepare(dev->clk[i]); 384 clk_put(dev->clk[i]); 385 } 386 387 return 0; 388 } 389 390 static const struct of_device_id orion_mdio_match[] = { 391 { .compatible = "marvell,orion-mdio", .data = (void *)BUS_TYPE_SMI }, 392 { .compatible = "marvell,xmdio", .data = (void *)BUS_TYPE_XSMI }, 393 { } 394 }; 395 MODULE_DEVICE_TABLE(of, orion_mdio_match); 396 397 #ifdef CONFIG_ACPI 398 static const struct acpi_device_id orion_mdio_acpi_match[] = { 399 { "MRVL0100", BUS_TYPE_SMI }, 400 { "MRVL0101", BUS_TYPE_XSMI }, 401 { }, 402 }; 403 MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match); 404 #endif 405 406 static struct platform_driver orion_mdio_driver = { 407 .probe = orion_mdio_probe, 408 .remove = orion_mdio_remove, 409 .driver = { 410 .name = "orion-mdio", 411 .of_match_table = orion_mdio_match, 412 .acpi_match_table = ACPI_PTR(orion_mdio_acpi_match), 413 }, 414 }; 415 416 module_platform_driver(orion_mdio_driver); 417 418 MODULE_DESCRIPTION("Marvell MDIO interface driver"); 419 MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); 420 MODULE_LICENSE("GPL"); 421 MODULE_ALIAS("platform:orion-mdio"); 422