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_optional(&pdev->dev, NULL); 352 if (IS_ERR(dev->clk[0])) { 353 ret = PTR_ERR(dev->clk[0]); 354 goto out_clk; 355 } 356 clk_prepare_enable(dev->clk[0]); 357 } 358 359 360 dev->err_interrupt = platform_get_irq_optional(pdev, 0); 361 if (dev->err_interrupt > 0 && 362 resource_size(r) < MVMDIO_ERR_INT_MASK + 4) { 363 dev_err(&pdev->dev, 364 "disabling interrupt, resource size is too small\n"); 365 dev->err_interrupt = 0; 366 } 367 if (dev->err_interrupt > 0) { 368 ret = devm_request_irq(&pdev->dev, dev->err_interrupt, 369 orion_mdio_err_irq, 370 IRQF_SHARED, pdev->name, dev); 371 if (ret) 372 goto out_mdio; 373 374 writel(MVMDIO_ERR_INT_SMI_DONE, 375 dev->regs + MVMDIO_ERR_INT_MASK); 376 377 } else if (dev->err_interrupt == -EPROBE_DEFER) { 378 ret = -EPROBE_DEFER; 379 goto out_mdio; 380 } 381 382 /* For the platforms not supporting DT/ACPI fall-back 383 * to mdiobus_register via of_mdiobus_register. 384 */ 385 if (is_acpi_node(pdev->dev.fwnode)) 386 ret = acpi_mdiobus_register(bus, pdev->dev.fwnode); 387 else 388 ret = of_mdiobus_register(bus, pdev->dev.of_node); 389 if (ret < 0) { 390 dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret); 391 goto out_mdio; 392 } 393 394 platform_set_drvdata(pdev, bus); 395 396 return 0; 397 398 out_mdio: 399 if (dev->err_interrupt > 0) 400 writel(0, dev->regs + MVMDIO_ERR_INT_MASK); 401 402 out_clk: 403 for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { 404 if (IS_ERR(dev->clk[i])) 405 break; 406 clk_disable_unprepare(dev->clk[i]); 407 clk_put(dev->clk[i]); 408 } 409 410 return ret; 411 } 412 413 static void orion_mdio_remove(struct platform_device *pdev) 414 { 415 struct mii_bus *bus = platform_get_drvdata(pdev); 416 struct orion_mdio_dev *dev = bus->priv; 417 int i; 418 419 if (dev->err_interrupt > 0) 420 writel(0, dev->regs + MVMDIO_ERR_INT_MASK); 421 mdiobus_unregister(bus); 422 423 for (i = 0; i < ARRAY_SIZE(dev->clk); i++) { 424 clk_disable_unprepare(dev->clk[i]); 425 clk_put(dev->clk[i]); 426 } 427 } 428 429 static const struct of_device_id orion_mdio_match[] = { 430 { .compatible = "marvell,orion-mdio", .data = (void *)BUS_TYPE_SMI }, 431 { .compatible = "marvell,xmdio", .data = (void *)BUS_TYPE_XSMI }, 432 { } 433 }; 434 MODULE_DEVICE_TABLE(of, orion_mdio_match); 435 436 #ifdef CONFIG_ACPI 437 static const struct acpi_device_id orion_mdio_acpi_match[] = { 438 { "MRVL0100", BUS_TYPE_SMI }, 439 { "MRVL0101", BUS_TYPE_XSMI }, 440 { }, 441 }; 442 MODULE_DEVICE_TABLE(acpi, orion_mdio_acpi_match); 443 #endif 444 445 static struct platform_driver orion_mdio_driver = { 446 .probe = orion_mdio_probe, 447 .remove = orion_mdio_remove, 448 .driver = { 449 .name = "orion-mdio", 450 .of_match_table = orion_mdio_match, 451 .acpi_match_table = ACPI_PTR(orion_mdio_acpi_match), 452 }, 453 }; 454 455 module_platform_driver(orion_mdio_driver); 456 457 MODULE_DESCRIPTION("Marvell MDIO interface driver"); 458 MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); 459 MODULE_LICENSE("GPL"); 460 MODULE_ALIAS("platform:orion-mdio"); 461