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 #define MVMDIO_XSMI_CFG_REG 0xc 57 #define MVMDIO_XSMI_CLKDIV_MASK 0x3 58 #define MVMDIO_XSMI_CLKDIV_256 0x0 59 #define MVMDIO_XSMI_CLKDIV_64 0x1 60 #define MVMDIO_XSMI_CLKDIV_32 0x2 61 #define MVMDIO_XSMI_CLKDIV_8 0x3 62 63 /* 64 * SMI Timeout measurements: 65 * - Kirkwood 88F6281 (Globalscale Dreamplug): 45us to 95us (Interrupt) 66 * - Armada 370 (Globalscale Mirabox): 41us to 43us (Polled) 67 */ 68 #define MVMDIO_SMI_TIMEOUT 1000 /* 1000us = 1ms */ 69 70 struct orion_mdio_dev { 71 void __iomem *regs; 72 struct clk *clk[4]; 73 /* 74 * If we have access to the error interrupt pin (which is 75 * somewhat misnamed as it not only reflects internal errors 76 * but also reflects SMI completion), use that to wait for 77 * SMI access completion instead of polling the SMI busy bit. 78 */ 79 int err_interrupt; 80 wait_queue_head_t smi_busy_wait; 81 }; 82 83 enum orion_mdio_bus_type { 84 BUS_TYPE_SMI, 85 BUS_TYPE_XSMI 86 }; 87 88 struct orion_mdio_ops { 89 int (*is_done)(struct orion_mdio_dev *); 90 }; 91 92 /* Wait for the SMI unit to be ready for another operation 93 */ 94 static int orion_mdio_wait_ready(const struct orion_mdio_ops *ops, 95 struct mii_bus *bus) 96 { 97 struct orion_mdio_dev *dev = bus->priv; 98 unsigned long timeout; 99 int done; 100 101 if (dev->err_interrupt <= 0) { 102 if (!read_poll_timeout_atomic(ops->is_done, done, done, 2, 103 MVMDIO_SMI_TIMEOUT, false, dev)) 104 return 0; 105 } else { 106 /* wait_event_timeout does not guarantee a delay of at 107 * least one whole jiffy, so timeout must be no less 108 * than two. 109 */ 110 timeout = max(usecs_to_jiffies(MVMDIO_SMI_TIMEOUT), 2); 111 112 if (wait_event_timeout(dev->smi_busy_wait, 113 ops->is_done(dev), timeout)) 114 return 0; 115 } 116 117 dev_err(bus->parent, "Timeout: SMI busy for too long\n"); 118 return -ETIMEDOUT; 119 } 120 121 static int orion_mdio_smi_is_done(struct orion_mdio_dev *dev) 122 { 123 return !(readl(dev->regs) & MVMDIO_SMI_BUSY); 124 } 125 126 static const struct orion_mdio_ops orion_mdio_smi_ops = { 127 .is_done = orion_mdio_smi_is_done, 128 }; 129 130 static int orion_mdio_smi_read(struct mii_bus *bus, int mii_id, 131 int regnum) 132 { 133 struct orion_mdio_dev *dev = bus->priv; 134 u32 val; 135 int ret; 136 137 ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus); 138 if (ret < 0) 139 return ret; 140 141 writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) | 142 (regnum << MVMDIO_SMI_PHY_REG_SHIFT) | 143 MVMDIO_SMI_READ_OPERATION), 144 dev->regs); 145 146 ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus); 147 if (ret < 0) 148 return ret; 149 150 val = readl(dev->regs); 151 if (!(val & MVMDIO_SMI_READ_VALID)) { 152 dev_err(bus->parent, "SMI bus read not valid\n"); 153 return -ENODEV; 154 } 155 156 return val & GENMASK(15, 0); 157 } 158 159 static int orion_mdio_smi_write(struct mii_bus *bus, int mii_id, 160 int regnum, u16 value) 161 { 162 struct orion_mdio_dev *dev = bus->priv; 163 int ret; 164 165 ret = orion_mdio_wait_ready(&orion_mdio_smi_ops, bus); 166 if (ret < 0) 167 return ret; 168 169 writel(((mii_id << MVMDIO_SMI_PHY_ADDR_SHIFT) | 170 (regnum << MVMDIO_SMI_PHY_REG_SHIFT) | 171 MVMDIO_SMI_WRITE_OPERATION | 172 (value << MVMDIO_SMI_DATA_SHIFT)), 173 dev->regs); 174 175 return 0; 176 } 177 178 static int orion_mdio_xsmi_is_done(struct orion_mdio_dev *dev) 179 { 180 return !(readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & MVMDIO_XSMI_BUSY); 181 } 182 183 static const struct orion_mdio_ops orion_mdio_xsmi_ops = { 184 .is_done = orion_mdio_xsmi_is_done, 185 }; 186 187 static int orion_mdio_xsmi_read_c45(struct mii_bus *bus, int mii_id, 188 int dev_addr, int regnum) 189 { 190 struct orion_mdio_dev *dev = bus->priv; 191 int ret; 192 193 ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus); 194 if (ret < 0) 195 return ret; 196 197 writel(regnum, dev->regs + MVMDIO_XSMI_ADDR_REG); 198 writel((mii_id << MVMDIO_XSMI_PHYADDR_SHIFT) | 199 (dev_addr << MVMDIO_XSMI_DEVADDR_SHIFT) | 200 MVMDIO_XSMI_READ_OPERATION, 201 dev->regs + MVMDIO_XSMI_MGNT_REG); 202 203 ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus); 204 if (ret < 0) 205 return ret; 206 207 if (!(readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & 208 MVMDIO_XSMI_READ_VALID)) { 209 dev_err(bus->parent, "XSMI bus read not valid\n"); 210 return -ENODEV; 211 } 212 213 return readl(dev->regs + MVMDIO_XSMI_MGNT_REG) & GENMASK(15, 0); 214 } 215 216 static int orion_mdio_xsmi_write_c45(struct mii_bus *bus, int mii_id, 217 int dev_addr, int regnum, u16 value) 218 { 219 struct orion_mdio_dev *dev = bus->priv; 220 int ret; 221 222 ret = orion_mdio_wait_ready(&orion_mdio_xsmi_ops, bus); 223 if (ret < 0) 224 return ret; 225 226 writel(regnum, dev->regs + MVMDIO_XSMI_ADDR_REG); 227 writel((mii_id << MVMDIO_XSMI_PHYADDR_SHIFT) | 228 (dev_addr << MVMDIO_XSMI_DEVADDR_SHIFT) | 229 MVMDIO_XSMI_WRITE_OPERATION | value, 230 dev->regs + MVMDIO_XSMI_MGNT_REG); 231 232 return 0; 233 } 234 235 static void orion_mdio_xsmi_set_mdc_freq(struct mii_bus *bus) 236 { 237 struct orion_mdio_dev *dev = bus->priv; 238 struct clk *mg_core; 239 u32 div, freq, cfg; 240 241 if (device_property_read_u32(bus->parent, "clock-frequency", &freq)) 242 return; 243 244 mg_core = of_clk_get_by_name(bus->parent->of_node, "mg_core_clk"); 245 if (IS_ERR(mg_core)) { 246 dev_err(bus->parent, 247 "MG core clock unknown, not changing MDC frequency"); 248 return; 249 } 250 251 div = clk_get_rate(mg_core) / (freq + 1) + 1; 252 clk_put(mg_core); 253 254 if (div <= 8) 255 div = MVMDIO_XSMI_CLKDIV_8; 256 else if (div <= 32) 257 div = MVMDIO_XSMI_CLKDIV_32; 258 else if (div <= 64) 259 div = MVMDIO_XSMI_CLKDIV_64; 260 else 261 div = MVMDIO_XSMI_CLKDIV_256; 262 263 cfg = readl(dev->regs + MVMDIO_XSMI_CFG_REG); 264 cfg &= ~MVMDIO_XSMI_CLKDIV_MASK; 265 cfg |= div; 266 writel(cfg, dev->regs + MVMDIO_XSMI_CFG_REG); 267 } 268 269 static irqreturn_t orion_mdio_err_irq(int irq, void *dev_id) 270 { 271 struct orion_mdio_dev *dev = dev_id; 272 273 if (readl(dev->regs + MVMDIO_ERR_INT_CAUSE) & 274 MVMDIO_ERR_INT_SMI_DONE) { 275 writel(~MVMDIO_ERR_INT_SMI_DONE, 276 dev->regs + MVMDIO_ERR_INT_CAUSE); 277 wake_up(&dev->smi_busy_wait); 278 return IRQ_HANDLED; 279 } 280 281 return IRQ_NONE; 282 } 283 284 static int orion_mdio_probe(struct platform_device *pdev) 285 { 286 enum orion_mdio_bus_type type; 287 struct resource *r; 288 struct mii_bus *bus; 289 struct orion_mdio_dev *dev; 290 int i, ret; 291 292 type = (uintptr_t)device_get_match_data(&pdev->dev); 293 294 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 295 if (!r) { 296 dev_err(&pdev->dev, "No SMI register address given\n"); 297 return -ENODEV; 298 } 299 300 bus = devm_mdiobus_alloc_size(&pdev->dev, 301 sizeof(struct orion_mdio_dev)); 302 if (!bus) 303 return -ENOMEM; 304 305 switch (type) { 306 case BUS_TYPE_SMI: 307 bus->read = orion_mdio_smi_read; 308 bus->write = orion_mdio_smi_write; 309 break; 310 case BUS_TYPE_XSMI: 311 bus->read_c45 = orion_mdio_xsmi_read_c45; 312 bus->write_c45 = orion_mdio_xsmi_write_c45; 313 break; 314 } 315 316 bus->name = "orion_mdio_bus"; 317 snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", 318 dev_name(&pdev->dev)); 319 bus->parent = &pdev->dev; 320 321 dev = bus->priv; 322 dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); 323 if (!dev->regs) { 324 dev_err(&pdev->dev, "Unable to remap SMI register\n"); 325 return -ENODEV; 326 } 327 328 init_waitqueue_head(&dev->smi_busy_wait); 329 330 if (pdev->dev.of_node) { 331 for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { 332 dev->clk[i] = of_clk_get(pdev->dev.of_node, i); 333 if (PTR_ERR(dev->clk[i]) == -EPROBE_DEFER) { 334 ret = -EPROBE_DEFER; 335 goto out_clk; 336 } 337 if (IS_ERR(dev->clk[i])) 338 break; 339 clk_prepare_enable(dev->clk[i]); 340 } 341 342 if (!IS_ERR(of_clk_get(pdev->dev.of_node, 343 ARRAY_SIZE(dev->clk)))) 344 dev_warn(&pdev->dev, 345 "unsupported number of clocks, limiting to the first " 346 __stringify(ARRAY_SIZE(dev->clk)) "\n"); 347 348 if (type == BUS_TYPE_XSMI) 349 orion_mdio_xsmi_set_mdc_freq(bus); 350 } else { 351 dev->clk[0] = clk_get(&pdev->dev, NULL); 352 if (PTR_ERR(dev->clk[0]) == -EPROBE_DEFER) { 353 ret = -EPROBE_DEFER; 354 goto out_clk; 355 } 356 if (!IS_ERR(dev->clk[0])) 357 clk_prepare_enable(dev->clk[0]); 358 } 359 360 361 dev->err_interrupt = platform_get_irq_optional(pdev, 0); 362 if (dev->err_interrupt > 0 && 363 resource_size(r) < MVMDIO_ERR_INT_MASK + 4) { 364 dev_err(&pdev->dev, 365 "disabling interrupt, resource size is too small\n"); 366 dev->err_interrupt = 0; 367 } 368 if (dev->err_interrupt > 0) { 369 ret = devm_request_irq(&pdev->dev, dev->err_interrupt, 370 orion_mdio_err_irq, 371 IRQF_SHARED, pdev->name, dev); 372 if (ret) 373 goto out_mdio; 374 375 writel(MVMDIO_ERR_INT_SMI_DONE, 376 dev->regs + MVMDIO_ERR_INT_MASK); 377 378 } else if (dev->err_interrupt == -EPROBE_DEFER) { 379 ret = -EPROBE_DEFER; 380 goto out_mdio; 381 } 382 383 /* For the platforms not supporting DT/ACPI fall-back 384 * to mdiobus_register via of_mdiobus_register. 385 */ 386 if (is_acpi_node(pdev->dev.fwnode)) 387 ret = acpi_mdiobus_register(bus, pdev->dev.fwnode); 388 else 389 ret = of_mdiobus_register(bus, pdev->dev.of_node); 390 if (ret < 0) { 391 dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret); 392 goto out_mdio; 393 } 394 395 platform_set_drvdata(pdev, bus); 396 397 return 0; 398 399 out_mdio: 400 if (dev->err_interrupt > 0) 401 writel(0, dev->regs + MVMDIO_ERR_INT_MASK); 402 403 out_clk: 404 for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { 405 if (IS_ERR(dev->clk[i])) 406 break; 407 clk_disable_unprepare(dev->clk[i]); 408 clk_put(dev->clk[i]); 409 } 410 411 return ret; 412 } 413 414 static void orion_mdio_remove(struct platform_device *pdev) 415 { 416 struct mii_bus *bus = platform_get_drvdata(pdev); 417 struct orion_mdio_dev *dev = bus->priv; 418 int i; 419 420 if (dev->err_interrupt > 0) 421 writel(0, dev->regs + MVMDIO_ERR_INT_MASK); 422 mdiobus_unregister(bus); 423 424 for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { 425 if (IS_ERR(dev->clk[i])) 426 break; 427 clk_disable_unprepare(dev->clk[i]); 428 clk_put(dev->clk[i]); 429 } 430 } 431 432 static const struct of_device_id orion_mdio_match[] = { 433 { .compatible = "marvell,orion-mdio", .data = (void *)BUS_TYPE_SMI }, 434 { .compatible = "marvell,xmdio", .data = (void *)BUS_TYPE_XSMI }, 435 { } 436 }; 437 MODULE_DEVICE_TABLE(of, orion_mdio_match); 438 439 #ifdef CONFIG_ACPI 440 static const struct acpi_device_id orion_mdio_acpi_match[] = { 441 { "MRVL0100", BUS_TYPE_SMI }, 442 { "MRVL0101", BUS_TYPE_XSMI }, 443 { }, 444 }; 445 MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match); 446 #endif 447 448 static struct platform_driver orion_mdio_driver = { 449 .probe = orion_mdio_probe, 450 .remove_new = orion_mdio_remove, 451 .driver = { 452 .name = "orion-mdio", 453 .of_match_table = orion_mdio_match, 454 .acpi_match_table = ACPI_PTR(orion_mdio_acpi_match), 455 }, 456 }; 457 458 module_platform_driver(orion_mdio_driver); 459 460 MODULE_DESCRIPTION("Marvell MDIO interface driver"); 461 MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); 462 MODULE_LICENSE("GPL"); 463 MODULE_ALIAS("platform:orion-mdio"); 464