1 /* 2 * B53 register access through Switch Register Access Bridge Registers 3 * 4 * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de> 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <linux/kernel.h> 20 #include <linux/module.h> 21 #include <linux/delay.h> 22 #include <linux/interrupt.h> 23 #include <linux/platform_device.h> 24 #include <linux/platform_data/b53.h> 25 #include <linux/of.h> 26 27 #include "b53_priv.h" 28 #include "b53_serdes.h" 29 30 /* command and status register of the SRAB */ 31 #define B53_SRAB_CMDSTAT 0x2c 32 #define B53_SRAB_CMDSTAT_RST BIT(2) 33 #define B53_SRAB_CMDSTAT_WRITE BIT(1) 34 #define B53_SRAB_CMDSTAT_GORDYN BIT(0) 35 #define B53_SRAB_CMDSTAT_PAGE 24 36 #define B53_SRAB_CMDSTAT_REG 16 37 38 /* high order word of write data to switch registe */ 39 #define B53_SRAB_WD_H 0x30 40 41 /* low order word of write data to switch registe */ 42 #define B53_SRAB_WD_L 0x34 43 44 /* high order word of read data from switch register */ 45 #define B53_SRAB_RD_H 0x38 46 47 /* low order word of read data from switch register */ 48 #define B53_SRAB_RD_L 0x3c 49 50 /* command and status register of the SRAB */ 51 #define B53_SRAB_CTRLS 0x40 52 #define B53_SRAB_CTRLS_HOST_INTR BIT(1) 53 #define B53_SRAB_CTRLS_RCAREQ BIT(3) 54 #define B53_SRAB_CTRLS_RCAGNT BIT(4) 55 #define B53_SRAB_CTRLS_SW_INIT_DONE BIT(6) 56 57 /* the register captures interrupt pulses from the switch */ 58 #define B53_SRAB_INTR 0x44 59 #define B53_SRAB_INTR_P(x) BIT(x) 60 #define B53_SRAB_SWITCH_PHY BIT(8) 61 #define B53_SRAB_1588_SYNC BIT(9) 62 #define B53_SRAB_IMP1_SLEEP_TIMER BIT(10) 63 #define B53_SRAB_P7_SLEEP_TIMER BIT(11) 64 #define B53_SRAB_IMP0_SLEEP_TIMER BIT(12) 65 66 /* Port mux configuration registers */ 67 #define B53_MUX_CONFIG_P5 0x00 68 #define MUX_CONFIG_SGMII 0 69 #define MUX_CONFIG_MII_LITE 1 70 #define MUX_CONFIG_RGMII 2 71 #define MUX_CONFIG_GMII 3 72 #define MUX_CONFIG_GPHY 4 73 #define MUX_CONFIG_INTERNAL 5 74 #define MUX_CONFIG_MASK 0x7 75 #define B53_MUX_CONFIG_P4 0x04 76 77 struct b53_srab_port_priv { 78 int irq; 79 bool irq_enabled; 80 struct b53_device *dev; 81 unsigned int num; 82 phy_interface_t mode; 83 }; 84 85 struct b53_srab_priv { 86 void __iomem *regs; 87 void __iomem *mux_config; 88 struct b53_srab_port_priv port_intrs[B53_N_PORTS]; 89 }; 90 91 static int b53_srab_request_grant(struct b53_device *dev) 92 { 93 struct b53_srab_priv *priv = dev->priv; 94 u8 __iomem *regs = priv->regs; 95 u32 ctrls; 96 int i; 97 98 ctrls = readl(regs + B53_SRAB_CTRLS); 99 ctrls |= B53_SRAB_CTRLS_RCAREQ; 100 writel(ctrls, regs + B53_SRAB_CTRLS); 101 102 for (i = 0; i < 20; i++) { 103 ctrls = readl(regs + B53_SRAB_CTRLS); 104 if (ctrls & B53_SRAB_CTRLS_RCAGNT) 105 break; 106 usleep_range(10, 100); 107 } 108 if (WARN_ON(i == 5)) 109 return -EIO; 110 111 return 0; 112 } 113 114 static void b53_srab_release_grant(struct b53_device *dev) 115 { 116 struct b53_srab_priv *priv = dev->priv; 117 u8 __iomem *regs = priv->regs; 118 u32 ctrls; 119 120 ctrls = readl(regs + B53_SRAB_CTRLS); 121 ctrls &= ~B53_SRAB_CTRLS_RCAREQ; 122 writel(ctrls, regs + B53_SRAB_CTRLS); 123 } 124 125 static int b53_srab_op(struct b53_device *dev, u8 page, u8 reg, u32 op) 126 { 127 struct b53_srab_priv *priv = dev->priv; 128 u8 __iomem *regs = priv->regs; 129 int i; 130 u32 cmdstat; 131 132 /* set register address */ 133 cmdstat = (page << B53_SRAB_CMDSTAT_PAGE) | 134 (reg << B53_SRAB_CMDSTAT_REG) | 135 B53_SRAB_CMDSTAT_GORDYN | 136 op; 137 writel(cmdstat, regs + B53_SRAB_CMDSTAT); 138 139 /* check if operation completed */ 140 for (i = 0; i < 5; ++i) { 141 cmdstat = readl(regs + B53_SRAB_CMDSTAT); 142 if (!(cmdstat & B53_SRAB_CMDSTAT_GORDYN)) 143 break; 144 usleep_range(10, 100); 145 } 146 147 if (WARN_ON(i == 5)) 148 return -EIO; 149 150 return 0; 151 } 152 153 static int b53_srab_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val) 154 { 155 struct b53_srab_priv *priv = dev->priv; 156 u8 __iomem *regs = priv->regs; 157 int ret = 0; 158 159 ret = b53_srab_request_grant(dev); 160 if (ret) 161 goto err; 162 163 ret = b53_srab_op(dev, page, reg, 0); 164 if (ret) 165 goto err; 166 167 *val = readl(regs + B53_SRAB_RD_L) & 0xff; 168 169 err: 170 b53_srab_release_grant(dev); 171 172 return ret; 173 } 174 175 static int b53_srab_read16(struct b53_device *dev, u8 page, u8 reg, u16 *val) 176 { 177 struct b53_srab_priv *priv = dev->priv; 178 u8 __iomem *regs = priv->regs; 179 int ret = 0; 180 181 ret = b53_srab_request_grant(dev); 182 if (ret) 183 goto err; 184 185 ret = b53_srab_op(dev, page, reg, 0); 186 if (ret) 187 goto err; 188 189 *val = readl(regs + B53_SRAB_RD_L) & 0xffff; 190 191 err: 192 b53_srab_release_grant(dev); 193 194 return ret; 195 } 196 197 static int b53_srab_read32(struct b53_device *dev, u8 page, u8 reg, u32 *val) 198 { 199 struct b53_srab_priv *priv = dev->priv; 200 u8 __iomem *regs = priv->regs; 201 int ret = 0; 202 203 ret = b53_srab_request_grant(dev); 204 if (ret) 205 goto err; 206 207 ret = b53_srab_op(dev, page, reg, 0); 208 if (ret) 209 goto err; 210 211 *val = readl(regs + B53_SRAB_RD_L); 212 213 err: 214 b53_srab_release_grant(dev); 215 216 return ret; 217 } 218 219 static int b53_srab_read48(struct b53_device *dev, u8 page, u8 reg, u64 *val) 220 { 221 struct b53_srab_priv *priv = dev->priv; 222 u8 __iomem *regs = priv->regs; 223 int ret = 0; 224 225 ret = b53_srab_request_grant(dev); 226 if (ret) 227 goto err; 228 229 ret = b53_srab_op(dev, page, reg, 0); 230 if (ret) 231 goto err; 232 233 *val = readl(regs + B53_SRAB_RD_L); 234 *val += ((u64)readl(regs + B53_SRAB_RD_H) & 0xffff) << 32; 235 236 err: 237 b53_srab_release_grant(dev); 238 239 return ret; 240 } 241 242 static int b53_srab_read64(struct b53_device *dev, u8 page, u8 reg, u64 *val) 243 { 244 struct b53_srab_priv *priv = dev->priv; 245 u8 __iomem *regs = priv->regs; 246 int ret = 0; 247 248 ret = b53_srab_request_grant(dev); 249 if (ret) 250 goto err; 251 252 ret = b53_srab_op(dev, page, reg, 0); 253 if (ret) 254 goto err; 255 256 *val = readl(regs + B53_SRAB_RD_L); 257 *val += (u64)readl(regs + B53_SRAB_RD_H) << 32; 258 259 err: 260 b53_srab_release_grant(dev); 261 262 return ret; 263 } 264 265 static int b53_srab_write8(struct b53_device *dev, u8 page, u8 reg, u8 value) 266 { 267 struct b53_srab_priv *priv = dev->priv; 268 u8 __iomem *regs = priv->regs; 269 int ret = 0; 270 271 ret = b53_srab_request_grant(dev); 272 if (ret) 273 goto err; 274 275 writel(value, regs + B53_SRAB_WD_L); 276 277 ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); 278 279 err: 280 b53_srab_release_grant(dev); 281 282 return ret; 283 } 284 285 static int b53_srab_write16(struct b53_device *dev, u8 page, u8 reg, 286 u16 value) 287 { 288 struct b53_srab_priv *priv = dev->priv; 289 u8 __iomem *regs = priv->regs; 290 int ret = 0; 291 292 ret = b53_srab_request_grant(dev); 293 if (ret) 294 goto err; 295 296 writel(value, regs + B53_SRAB_WD_L); 297 298 ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); 299 300 err: 301 b53_srab_release_grant(dev); 302 303 return ret; 304 } 305 306 static int b53_srab_write32(struct b53_device *dev, u8 page, u8 reg, 307 u32 value) 308 { 309 struct b53_srab_priv *priv = dev->priv; 310 u8 __iomem *regs = priv->regs; 311 int ret = 0; 312 313 ret = b53_srab_request_grant(dev); 314 if (ret) 315 goto err; 316 317 writel(value, regs + B53_SRAB_WD_L); 318 319 ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); 320 321 err: 322 b53_srab_release_grant(dev); 323 324 return ret; 325 } 326 327 static int b53_srab_write48(struct b53_device *dev, u8 page, u8 reg, 328 u64 value) 329 { 330 struct b53_srab_priv *priv = dev->priv; 331 u8 __iomem *regs = priv->regs; 332 int ret = 0; 333 334 ret = b53_srab_request_grant(dev); 335 if (ret) 336 goto err; 337 338 writel((u32)value, regs + B53_SRAB_WD_L); 339 writel((u16)(value >> 32), regs + B53_SRAB_WD_H); 340 341 ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); 342 343 err: 344 b53_srab_release_grant(dev); 345 346 return ret; 347 } 348 349 static int b53_srab_write64(struct b53_device *dev, u8 page, u8 reg, 350 u64 value) 351 { 352 struct b53_srab_priv *priv = dev->priv; 353 u8 __iomem *regs = priv->regs; 354 int ret = 0; 355 356 ret = b53_srab_request_grant(dev); 357 if (ret) 358 goto err; 359 360 writel((u32)value, regs + B53_SRAB_WD_L); 361 writel((u32)(value >> 32), regs + B53_SRAB_WD_H); 362 363 ret = b53_srab_op(dev, page, reg, B53_SRAB_CMDSTAT_WRITE); 364 365 err: 366 b53_srab_release_grant(dev); 367 368 return ret; 369 } 370 371 static irqreturn_t b53_srab_port_thread(int irq, void *dev_id) 372 { 373 struct b53_srab_port_priv *port = dev_id; 374 struct b53_device *dev = port->dev; 375 376 if (port->mode == PHY_INTERFACE_MODE_SGMII) 377 b53_port_event(dev->ds, port->num); 378 379 return IRQ_HANDLED; 380 } 381 382 static irqreturn_t b53_srab_port_isr(int irq, void *dev_id) 383 { 384 struct b53_srab_port_priv *port = dev_id; 385 struct b53_device *dev = port->dev; 386 struct b53_srab_priv *priv = dev->priv; 387 388 /* Acknowledge the interrupt */ 389 writel(BIT(port->num), priv->regs + B53_SRAB_INTR); 390 391 return IRQ_WAKE_THREAD; 392 } 393 394 #if IS_ENABLED(CONFIG_B53_SERDES) 395 static u8 b53_srab_serdes_map_lane(struct b53_device *dev, int port) 396 { 397 struct b53_srab_priv *priv = dev->priv; 398 struct b53_srab_port_priv *p = &priv->port_intrs[port]; 399 400 if (p->mode != PHY_INTERFACE_MODE_SGMII) 401 return B53_INVALID_LANE; 402 403 switch (port) { 404 case 5: 405 return 0; 406 case 4: 407 return 1; 408 default: 409 return B53_INVALID_LANE; 410 } 411 } 412 #endif 413 414 static int b53_srab_irq_enable(struct b53_device *dev, int port) 415 { 416 struct b53_srab_priv *priv = dev->priv; 417 struct b53_srab_port_priv *p = &priv->port_intrs[port]; 418 int ret = 0; 419 420 /* Interrupt is optional and was not specified, do not make 421 * this fatal 422 */ 423 if (p->irq == -ENXIO) 424 return ret; 425 426 ret = request_threaded_irq(p->irq, b53_srab_port_isr, 427 b53_srab_port_thread, 0, 428 dev_name(dev->dev), p); 429 if (!ret) 430 p->irq_enabled = true; 431 432 return ret; 433 } 434 435 static void b53_srab_irq_disable(struct b53_device *dev, int port) 436 { 437 struct b53_srab_priv *priv = dev->priv; 438 struct b53_srab_port_priv *p = &priv->port_intrs[port]; 439 440 if (p->irq_enabled) { 441 free_irq(p->irq, p); 442 p->irq_enabled = false; 443 } 444 } 445 446 static const struct b53_io_ops b53_srab_ops = { 447 .read8 = b53_srab_read8, 448 .read16 = b53_srab_read16, 449 .read32 = b53_srab_read32, 450 .read48 = b53_srab_read48, 451 .read64 = b53_srab_read64, 452 .write8 = b53_srab_write8, 453 .write16 = b53_srab_write16, 454 .write32 = b53_srab_write32, 455 .write48 = b53_srab_write48, 456 .write64 = b53_srab_write64, 457 .irq_enable = b53_srab_irq_enable, 458 .irq_disable = b53_srab_irq_disable, 459 #if IS_ENABLED(CONFIG_B53_SERDES) 460 .serdes_map_lane = b53_srab_serdes_map_lane, 461 .serdes_link_state = b53_serdes_link_state, 462 .serdes_config = b53_serdes_config, 463 .serdes_an_restart = b53_serdes_an_restart, 464 .serdes_link_set = b53_serdes_link_set, 465 .serdes_phylink_validate = b53_serdes_phylink_validate, 466 #endif 467 }; 468 469 static const struct of_device_id b53_srab_of_match[] = { 470 { .compatible = "brcm,bcm53010-srab" }, 471 { .compatible = "brcm,bcm53011-srab" }, 472 { .compatible = "brcm,bcm53012-srab" }, 473 { .compatible = "brcm,bcm53018-srab" }, 474 { .compatible = "brcm,bcm53019-srab" }, 475 { .compatible = "brcm,bcm5301x-srab" }, 476 { .compatible = "brcm,bcm11360-srab", .data = (void *)BCM583XX_DEVICE_ID }, 477 { .compatible = "brcm,bcm58522-srab", .data = (void *)BCM58XX_DEVICE_ID }, 478 { .compatible = "brcm,bcm58525-srab", .data = (void *)BCM58XX_DEVICE_ID }, 479 { .compatible = "brcm,bcm58535-srab", .data = (void *)BCM58XX_DEVICE_ID }, 480 { .compatible = "brcm,bcm58622-srab", .data = (void *)BCM58XX_DEVICE_ID }, 481 { .compatible = "brcm,bcm58623-srab", .data = (void *)BCM58XX_DEVICE_ID }, 482 { .compatible = "brcm,bcm58625-srab", .data = (void *)BCM58XX_DEVICE_ID }, 483 { .compatible = "brcm,bcm88312-srab", .data = (void *)BCM58XX_DEVICE_ID }, 484 { .compatible = "brcm,cygnus-srab", .data = (void *)BCM583XX_DEVICE_ID }, 485 { .compatible = "brcm,nsp-srab", .data = (void *)BCM58XX_DEVICE_ID }, 486 { .compatible = "brcm,omega-srab", .data = (void *)BCM583XX_DEVICE_ID }, 487 { /* sentinel */ }, 488 }; 489 MODULE_DEVICE_TABLE(of, b53_srab_of_match); 490 491 static void b53_srab_intr_set(struct b53_srab_priv *priv, bool set) 492 { 493 u32 reg; 494 495 reg = readl(priv->regs + B53_SRAB_CTRLS); 496 if (set) 497 reg |= B53_SRAB_CTRLS_HOST_INTR; 498 else 499 reg &= ~B53_SRAB_CTRLS_HOST_INTR; 500 writel(reg, priv->regs + B53_SRAB_CTRLS); 501 } 502 503 static void b53_srab_prepare_irq(struct platform_device *pdev) 504 { 505 struct b53_device *dev = platform_get_drvdata(pdev); 506 struct b53_srab_priv *priv = dev->priv; 507 struct b53_srab_port_priv *port; 508 unsigned int i; 509 char *name; 510 511 /* Clear all pending interrupts */ 512 writel(0xffffffff, priv->regs + B53_SRAB_INTR); 513 514 for (i = 0; i < B53_N_PORTS; i++) { 515 port = &priv->port_intrs[i]; 516 517 /* There is no port 6 */ 518 if (i == 6) 519 continue; 520 521 name = kasprintf(GFP_KERNEL, "link_state_p%d", i); 522 if (!name) 523 return; 524 525 port->num = i; 526 port->dev = dev; 527 port->irq = platform_get_irq_byname(pdev, name); 528 kfree(name); 529 } 530 531 b53_srab_intr_set(priv, true); 532 } 533 534 static void b53_srab_mux_init(struct platform_device *pdev) 535 { 536 struct b53_device *dev = platform_get_drvdata(pdev); 537 struct b53_srab_priv *priv = dev->priv; 538 struct b53_srab_port_priv *p; 539 unsigned int port; 540 u32 reg, off = 0; 541 int ret; 542 543 if (dev->pdata && dev->pdata->chip_id != BCM58XX_DEVICE_ID) 544 return; 545 546 priv->mux_config = devm_platform_ioremap_resource(pdev, 1); 547 if (IS_ERR(priv->mux_config)) 548 return; 549 550 /* Obtain the port mux configuration so we know which lanes 551 * actually map to SerDes lanes 552 */ 553 for (port = 5; port > 3; port--, off += 4) { 554 p = &priv->port_intrs[port]; 555 556 reg = readl(priv->mux_config + B53_MUX_CONFIG_P5 + off); 557 switch (reg & MUX_CONFIG_MASK) { 558 case MUX_CONFIG_SGMII: 559 p->mode = PHY_INTERFACE_MODE_SGMII; 560 ret = b53_serdes_init(dev, port); 561 if (ret) 562 continue; 563 break; 564 case MUX_CONFIG_MII_LITE: 565 p->mode = PHY_INTERFACE_MODE_MII; 566 break; 567 case MUX_CONFIG_GMII: 568 p->mode = PHY_INTERFACE_MODE_GMII; 569 break; 570 case MUX_CONFIG_RGMII: 571 p->mode = PHY_INTERFACE_MODE_RGMII; 572 break; 573 case MUX_CONFIG_INTERNAL: 574 p->mode = PHY_INTERFACE_MODE_INTERNAL; 575 break; 576 default: 577 p->mode = PHY_INTERFACE_MODE_NA; 578 break; 579 } 580 581 if (p->mode != PHY_INTERFACE_MODE_NA) 582 dev_info(&pdev->dev, "Port %d mode: %s\n", 583 port, phy_modes(p->mode)); 584 } 585 } 586 587 static int b53_srab_probe(struct platform_device *pdev) 588 { 589 struct b53_platform_data *pdata = pdev->dev.platform_data; 590 struct device_node *dn = pdev->dev.of_node; 591 const struct of_device_id *of_id = NULL; 592 struct b53_srab_priv *priv; 593 struct b53_device *dev; 594 595 if (dn) 596 of_id = of_match_node(b53_srab_of_match, dn); 597 598 if (of_id) { 599 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 600 if (!pdata) 601 return -ENOMEM; 602 603 pdata->chip_id = (u32)(unsigned long)of_id->data; 604 } 605 606 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 607 if (!priv) 608 return -ENOMEM; 609 610 priv->regs = devm_platform_ioremap_resource(pdev, 0); 611 if (IS_ERR(priv->regs)) 612 return -ENOMEM; 613 614 dev = b53_switch_alloc(&pdev->dev, &b53_srab_ops, priv); 615 if (!dev) 616 return -ENOMEM; 617 618 if (pdata) 619 dev->pdata = pdata; 620 621 platform_set_drvdata(pdev, dev); 622 623 b53_srab_prepare_irq(pdev); 624 b53_srab_mux_init(pdev); 625 626 return b53_switch_register(dev); 627 } 628 629 static int b53_srab_remove(struct platform_device *pdev) 630 { 631 struct b53_device *dev = platform_get_drvdata(pdev); 632 struct b53_srab_priv *priv = dev->priv; 633 634 b53_srab_intr_set(priv, false); 635 if (dev) 636 b53_switch_remove(dev); 637 638 return 0; 639 } 640 641 static struct platform_driver b53_srab_driver = { 642 .probe = b53_srab_probe, 643 .remove = b53_srab_remove, 644 .driver = { 645 .name = "b53-srab-switch", 646 .of_match_table = b53_srab_of_match, 647 }, 648 }; 649 650 module_platform_driver(b53_srab_driver); 651 MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>"); 652 MODULE_DESCRIPTION("B53 Switch Register Access Bridge Registers (SRAB) access driver"); 653 MODULE_LICENSE("Dual BSD/GPL"); 654