1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Cadence USBSS DRD Driver. 4 * 5 * Copyright (C) 2018-2019 Cadence. 6 * Copyright (C) 2017-2018 NXP 7 * Copyright (C) 2019 Texas Instruments 8 * 9 * Author: Peter Chen <peter.chen@nxp.com> 10 * Pawel Laszczak <pawell@cadence.com> 11 * Roger Quadros <rogerq@ti.com> 12 */ 13 14 #include <linux/dma-mapping.h> 15 #include <linux/module.h> 16 #include <linux/kernel.h> 17 #include <linux/platform_device.h> 18 #include <linux/interrupt.h> 19 #include <linux/io.h> 20 #include <linux/pm_runtime.h> 21 22 #include "gadget.h" 23 #include "core.h" 24 #include "host-export.h" 25 #include "gadget-export.h" 26 #include "drd.h" 27 28 static int cdns3_idle_init(struct cdns3 *cdns); 29 30 static inline 31 struct cdns3_role_driver *cdns3_get_current_role_driver(struct cdns3 *cdns) 32 { 33 WARN_ON(!cdns->roles[cdns->role]); 34 return cdns->roles[cdns->role]; 35 } 36 37 static int cdns3_role_start(struct cdns3 *cdns, enum usb_role role) 38 { 39 int ret; 40 41 if (WARN_ON(role > USB_ROLE_DEVICE)) 42 return 0; 43 44 mutex_lock(&cdns->mutex); 45 cdns->role = role; 46 mutex_unlock(&cdns->mutex); 47 48 if (!cdns->roles[role]) 49 return -ENXIO; 50 51 if (cdns->roles[role]->state == CDNS3_ROLE_STATE_ACTIVE) 52 return 0; 53 54 mutex_lock(&cdns->mutex); 55 ret = cdns->roles[role]->start(cdns); 56 if (!ret) 57 cdns->roles[role]->state = CDNS3_ROLE_STATE_ACTIVE; 58 mutex_unlock(&cdns->mutex); 59 60 return ret; 61 } 62 63 static void cdns3_role_stop(struct cdns3 *cdns) 64 { 65 enum usb_role role = cdns->role; 66 67 if (WARN_ON(role > USB_ROLE_DEVICE)) 68 return; 69 70 if (cdns->roles[role]->state == CDNS3_ROLE_STATE_INACTIVE) 71 return; 72 73 mutex_lock(&cdns->mutex); 74 cdns->roles[role]->stop(cdns); 75 cdns->roles[role]->state = CDNS3_ROLE_STATE_INACTIVE; 76 mutex_unlock(&cdns->mutex); 77 } 78 79 static void cdns3_exit_roles(struct cdns3 *cdns) 80 { 81 cdns3_role_stop(cdns); 82 cdns3_drd_exit(cdns); 83 } 84 85 static enum usb_role cdsn3_hw_role_state_machine(struct cdns3 *cdns); 86 87 /** 88 * cdns3_core_init_role - initialize role of operation 89 * @cdns: Pointer to cdns3 structure 90 * 91 * Returns 0 on success otherwise negative errno 92 */ 93 static int cdns3_core_init_role(struct cdns3 *cdns) 94 { 95 struct device *dev = cdns->dev; 96 enum usb_dr_mode best_dr_mode; 97 enum usb_dr_mode dr_mode; 98 int ret = 0; 99 100 dr_mode = usb_get_dr_mode(dev); 101 cdns->role = USB_ROLE_NONE; 102 103 /* 104 * If driver can't read mode by means of usb_get_dr_mode function then 105 * chooses mode according with Kernel configuration. This setting 106 * can be restricted later depending on strap pin configuration. 107 */ 108 if (dr_mode == USB_DR_MODE_UNKNOWN) { 109 if (IS_ENABLED(CONFIG_USB_CDNS3_HOST) && 110 IS_ENABLED(CONFIG_USB_CDNS3_GADGET)) 111 dr_mode = USB_DR_MODE_OTG; 112 else if (IS_ENABLED(CONFIG_USB_CDNS3_HOST)) 113 dr_mode = USB_DR_MODE_HOST; 114 else if (IS_ENABLED(CONFIG_USB_CDNS3_GADGET)) 115 dr_mode = USB_DR_MODE_PERIPHERAL; 116 } 117 118 /* 119 * At this point cdns->dr_mode contains strap configuration. 120 * Driver try update this setting considering kernel configuration 121 */ 122 best_dr_mode = cdns->dr_mode; 123 124 ret = cdns3_idle_init(cdns); 125 if (ret) 126 return ret; 127 128 if (dr_mode == USB_DR_MODE_OTG) { 129 best_dr_mode = cdns->dr_mode; 130 } else if (cdns->dr_mode == USB_DR_MODE_OTG) { 131 best_dr_mode = dr_mode; 132 } else if (cdns->dr_mode != dr_mode) { 133 dev_err(dev, "Incorrect DRD configuration\n"); 134 return -EINVAL; 135 } 136 137 dr_mode = best_dr_mode; 138 139 if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_HOST) { 140 ret = cdns3_host_init(cdns); 141 if (ret) { 142 dev_err(dev, "Host initialization failed with %d\n", 143 ret); 144 goto err; 145 } 146 } 147 148 if (dr_mode == USB_DR_MODE_OTG || dr_mode == USB_DR_MODE_PERIPHERAL) { 149 ret = cdns3_gadget_init(cdns); 150 if (ret) { 151 dev_err(dev, "Device initialization failed with %d\n", 152 ret); 153 goto err; 154 } 155 } 156 157 cdns->dr_mode = dr_mode; 158 159 ret = cdns3_drd_update_mode(cdns); 160 if (ret) 161 goto err; 162 163 if (cdns->dr_mode != USB_DR_MODE_OTG) { 164 ret = cdns3_hw_role_switch(cdns); 165 if (ret) 166 goto err; 167 } 168 169 return ret; 170 err: 171 cdns3_exit_roles(cdns); 172 return ret; 173 } 174 175 /** 176 * cdsn3_hw_role_state_machine - role switch state machine based on hw events. 177 * @cdns: Pointer to controller structure. 178 * 179 * Returns next role to be entered based on hw events. 180 */ 181 static enum usb_role cdsn3_hw_role_state_machine(struct cdns3 *cdns) 182 { 183 enum usb_role role; 184 int id, vbus; 185 186 if (cdns->dr_mode != USB_DR_MODE_OTG) 187 goto not_otg; 188 189 id = cdns3_get_id(cdns); 190 vbus = cdns3_get_vbus(cdns); 191 192 /* 193 * Role change state machine 194 * Inputs: ID, VBUS 195 * Previous state: cdns->role 196 * Next state: role 197 */ 198 role = cdns->role; 199 200 switch (role) { 201 case USB_ROLE_NONE: 202 /* 203 * Driver treats USB_ROLE_NONE synonymous to IDLE state from 204 * controller specification. 205 */ 206 if (!id) 207 role = USB_ROLE_HOST; 208 else if (vbus) 209 role = USB_ROLE_DEVICE; 210 break; 211 case USB_ROLE_HOST: /* from HOST, we can only change to NONE */ 212 if (id) 213 role = USB_ROLE_NONE; 214 break; 215 case USB_ROLE_DEVICE: /* from GADGET, we can only change to NONE*/ 216 if (!vbus) 217 role = USB_ROLE_NONE; 218 break; 219 } 220 221 dev_dbg(cdns->dev, "role %d -> %d\n", cdns->role, role); 222 223 return role; 224 225 not_otg: 226 if (cdns3_is_host(cdns)) 227 role = USB_ROLE_HOST; 228 if (cdns3_is_device(cdns)) 229 role = USB_ROLE_DEVICE; 230 231 return role; 232 } 233 234 static int cdns3_idle_role_start(struct cdns3 *cdns) 235 { 236 return 0; 237 } 238 239 static void cdns3_idle_role_stop(struct cdns3 *cdns) 240 { 241 /* Program Lane swap and bring PHY out of RESET */ 242 phy_reset(cdns->usb3_phy); 243 } 244 245 static int cdns3_idle_init(struct cdns3 *cdns) 246 { 247 struct cdns3_role_driver *rdrv; 248 249 rdrv = devm_kzalloc(cdns->dev, sizeof(*rdrv), GFP_KERNEL); 250 if (!rdrv) 251 return -ENOMEM; 252 253 rdrv->start = cdns3_idle_role_start; 254 rdrv->stop = cdns3_idle_role_stop; 255 rdrv->state = CDNS3_ROLE_STATE_INACTIVE; 256 rdrv->suspend = NULL; 257 rdrv->resume = NULL; 258 rdrv->name = "idle"; 259 260 cdns->roles[USB_ROLE_NONE] = rdrv; 261 262 return 0; 263 } 264 265 /** 266 * cdns3_hw_role_switch - switch roles based on HW state 267 * @cdns3: controller 268 */ 269 int cdns3_hw_role_switch(struct cdns3 *cdns) 270 { 271 enum usb_role real_role, current_role; 272 int ret = 0; 273 274 /* Do nothing if role based on syfs. */ 275 if (cdns->role_override) 276 return 0; 277 278 pm_runtime_get_sync(cdns->dev); 279 280 current_role = cdns->role; 281 real_role = cdsn3_hw_role_state_machine(cdns); 282 283 /* Do nothing if nothing changed */ 284 if (current_role == real_role) 285 goto exit; 286 287 cdns3_role_stop(cdns); 288 289 dev_dbg(cdns->dev, "Switching role %d -> %d", current_role, real_role); 290 291 ret = cdns3_role_start(cdns, real_role); 292 if (ret) { 293 /* Back to current role */ 294 dev_err(cdns->dev, "set %d has failed, back to %d\n", 295 real_role, current_role); 296 ret = cdns3_role_start(cdns, current_role); 297 if (ret) 298 dev_err(cdns->dev, "back to %d failed too\n", 299 current_role); 300 } 301 exit: 302 pm_runtime_put_sync(cdns->dev); 303 return ret; 304 } 305 306 /** 307 * cdsn3_role_get - get current role of controller. 308 * 309 * @dev: Pointer to device structure 310 * 311 * Returns role 312 */ 313 static enum usb_role cdns3_role_get(struct device *dev) 314 { 315 struct cdns3 *cdns = dev_get_drvdata(dev); 316 317 return cdns->role; 318 } 319 320 /** 321 * cdns3_role_set - set current role of controller. 322 * 323 * @dev: pointer to device object 324 * @role - the previous role 325 * Handles below events: 326 * - Role switch for dual-role devices 327 * - USB_ROLE_GADGET <--> USB_ROLE_NONE for peripheral-only devices 328 */ 329 static int cdns3_role_set(struct device *dev, enum usb_role role) 330 { 331 struct cdns3 *cdns = dev_get_drvdata(dev); 332 int ret = 0; 333 334 pm_runtime_get_sync(cdns->dev); 335 336 /* 337 * FIXME: switch role framework should be extended to meet 338 * requirements. Driver assumes that role can be controlled 339 * by SW or HW. Temporary workaround is to use USB_ROLE_NONE to 340 * switch from SW to HW control. 341 * 342 * For dr_mode == USB_DR_MODE_OTG: 343 * if user sets USB_ROLE_HOST or USB_ROLE_DEVICE then driver 344 * sets role_override flag and forces that role. 345 * if user sets USB_ROLE_NONE, driver clears role_override and lets 346 * HW state machine take over. 347 * 348 * For dr_mode != USB_DR_MODE_OTG: 349 * Assumptions: 350 * 1. Restricted user control between NONE and dr_mode. 351 * 2. Driver doesn't need to rely on role_override flag. 352 * 3. Driver needs to ensure that HW state machine is never called 353 * if dr_mode != USB_DR_MODE_OTG. 354 */ 355 if (role == USB_ROLE_NONE) 356 cdns->role_override = 0; 357 else 358 cdns->role_override = 1; 359 360 /* 361 * HW state might have changed so driver need to trigger 362 * HW state machine if dr_mode == USB_DR_MODE_OTG. 363 */ 364 if (!cdns->role_override && cdns->dr_mode == USB_DR_MODE_OTG) { 365 cdns3_hw_role_switch(cdns); 366 goto pm_put; 367 } 368 369 if (cdns->role == role) 370 goto pm_put; 371 372 if (cdns->dr_mode == USB_DR_MODE_HOST) { 373 switch (role) { 374 case USB_ROLE_NONE: 375 case USB_ROLE_HOST: 376 break; 377 default: 378 ret = -EPERM; 379 goto pm_put; 380 } 381 } 382 383 if (cdns->dr_mode == USB_DR_MODE_PERIPHERAL) { 384 switch (role) { 385 case USB_ROLE_NONE: 386 case USB_ROLE_DEVICE: 387 break; 388 default: 389 ret = -EPERM; 390 goto pm_put; 391 } 392 } 393 394 cdns3_role_stop(cdns); 395 ret = cdns3_role_start(cdns, role); 396 if (ret) { 397 dev_err(cdns->dev, "set role %d has failed\n", role); 398 ret = -EPERM; 399 } 400 401 pm_put: 402 pm_runtime_put_sync(cdns->dev); 403 return ret; 404 } 405 406 static const struct usb_role_switch_desc cdns3_switch_desc = { 407 .set = cdns3_role_set, 408 .get = cdns3_role_get, 409 .allow_userspace_control = true, 410 }; 411 412 /** 413 * cdns3_probe - probe for cdns3 core device 414 * @pdev: Pointer to cdns3 core platform device 415 * 416 * Returns 0 on success otherwise negative errno 417 */ 418 static int cdns3_probe(struct platform_device *pdev) 419 { 420 struct device *dev = &pdev->dev; 421 struct resource *res; 422 struct cdns3 *cdns; 423 void __iomem *regs; 424 int ret; 425 426 ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 427 if (ret) { 428 dev_err(dev, "error setting dma mask: %d\n", ret); 429 return -ENODEV; 430 } 431 432 cdns = devm_kzalloc(dev, sizeof(*cdns), GFP_KERNEL); 433 if (!cdns) 434 return -ENOMEM; 435 436 cdns->dev = dev; 437 438 platform_set_drvdata(pdev, cdns); 439 440 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "host"); 441 if (!res) { 442 dev_err(dev, "missing host IRQ\n"); 443 return -ENODEV; 444 } 445 446 cdns->xhci_res[0] = *res; 447 448 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "xhci"); 449 if (!res) { 450 dev_err(dev, "couldn't get xhci resource\n"); 451 return -ENXIO; 452 } 453 454 cdns->xhci_res[1] = *res; 455 456 cdns->dev_irq = platform_get_irq_byname(pdev, "peripheral"); 457 if (cdns->dev_irq == -EPROBE_DEFER) 458 return cdns->dev_irq; 459 460 if (cdns->dev_irq < 0) 461 dev_err(dev, "couldn't get peripheral irq\n"); 462 463 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dev"); 464 regs = devm_ioremap_resource(dev, res); 465 if (IS_ERR(regs)) 466 return PTR_ERR(regs); 467 cdns->dev_regs = regs; 468 469 cdns->otg_irq = platform_get_irq_byname(pdev, "otg"); 470 if (cdns->otg_irq == -EPROBE_DEFER) 471 return cdns->otg_irq; 472 473 if (cdns->otg_irq < 0) { 474 dev_err(dev, "couldn't get otg irq\n"); 475 return cdns->otg_irq; 476 } 477 478 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otg"); 479 if (!res) { 480 dev_err(dev, "couldn't get otg resource\n"); 481 return -ENXIO; 482 } 483 484 cdns->otg_res = *res; 485 486 mutex_init(&cdns->mutex); 487 488 cdns->usb2_phy = devm_phy_optional_get(dev, "cdns3,usb2-phy"); 489 if (IS_ERR(cdns->usb2_phy)) 490 return PTR_ERR(cdns->usb2_phy); 491 492 ret = phy_init(cdns->usb2_phy); 493 if (ret) 494 return ret; 495 496 cdns->usb3_phy = devm_phy_optional_get(dev, "cdns3,usb3-phy"); 497 if (IS_ERR(cdns->usb3_phy)) 498 return PTR_ERR(cdns->usb3_phy); 499 500 ret = phy_init(cdns->usb3_phy); 501 if (ret) 502 goto err1; 503 504 ret = phy_power_on(cdns->usb2_phy); 505 if (ret) 506 goto err2; 507 508 ret = phy_power_on(cdns->usb3_phy); 509 if (ret) 510 goto err3; 511 512 cdns->role_sw = usb_role_switch_register(dev, &cdns3_switch_desc); 513 if (IS_ERR(cdns->role_sw)) { 514 ret = PTR_ERR(cdns->role_sw); 515 dev_warn(dev, "Unable to register Role Switch\n"); 516 goto err4; 517 } 518 519 ret = cdns3_drd_init(cdns); 520 if (ret) 521 goto err5; 522 523 ret = cdns3_core_init_role(cdns); 524 if (ret) 525 goto err5; 526 527 device_set_wakeup_capable(dev, true); 528 pm_runtime_set_active(dev); 529 pm_runtime_enable(dev); 530 531 /* 532 * The controller needs less time between bus and controller suspend, 533 * and we also needs a small delay to avoid frequently entering low 534 * power mode. 535 */ 536 pm_runtime_set_autosuspend_delay(dev, 20); 537 pm_runtime_mark_last_busy(dev); 538 pm_runtime_use_autosuspend(dev); 539 dev_dbg(dev, "Cadence USB3 core: probe succeed\n"); 540 541 return 0; 542 err5: 543 cdns3_drd_exit(cdns); 544 usb_role_switch_unregister(cdns->role_sw); 545 err4: 546 phy_power_off(cdns->usb3_phy); 547 548 err3: 549 phy_power_off(cdns->usb2_phy); 550 err2: 551 phy_exit(cdns->usb3_phy); 552 err1: 553 phy_exit(cdns->usb2_phy); 554 555 return ret; 556 } 557 558 /** 559 * cdns3_remove - unbind drd driver and clean up 560 * @pdev: Pointer to Linux platform device 561 * 562 * Returns 0 on success otherwise negative errno 563 */ 564 static int cdns3_remove(struct platform_device *pdev) 565 { 566 struct cdns3 *cdns = platform_get_drvdata(pdev); 567 568 pm_runtime_get_sync(&pdev->dev); 569 pm_runtime_disable(&pdev->dev); 570 pm_runtime_put_noidle(&pdev->dev); 571 cdns3_exit_roles(cdns); 572 usb_role_switch_unregister(cdns->role_sw); 573 phy_power_off(cdns->usb2_phy); 574 phy_power_off(cdns->usb3_phy); 575 phy_exit(cdns->usb2_phy); 576 phy_exit(cdns->usb3_phy); 577 return 0; 578 } 579 580 #ifdef CONFIG_PM_SLEEP 581 582 static int cdns3_suspend(struct device *dev) 583 { 584 struct cdns3 *cdns = dev_get_drvdata(dev); 585 unsigned long flags; 586 587 if (cdns->role == USB_ROLE_HOST) 588 return 0; 589 590 if (pm_runtime_status_suspended(dev)) 591 pm_runtime_resume(dev); 592 593 if (cdns->roles[cdns->role]->suspend) { 594 spin_lock_irqsave(&cdns->gadget_dev->lock, flags); 595 cdns->roles[cdns->role]->suspend(cdns, false); 596 spin_unlock_irqrestore(&cdns->gadget_dev->lock, flags); 597 } 598 599 return 0; 600 } 601 602 static int cdns3_resume(struct device *dev) 603 { 604 struct cdns3 *cdns = dev_get_drvdata(dev); 605 unsigned long flags; 606 607 if (cdns->role == USB_ROLE_HOST) 608 return 0; 609 610 if (cdns->roles[cdns->role]->resume) { 611 spin_lock_irqsave(&cdns->gadget_dev->lock, flags); 612 cdns->roles[cdns->role]->resume(cdns, false); 613 spin_unlock_irqrestore(&cdns->gadget_dev->lock, flags); 614 } 615 616 pm_runtime_disable(dev); 617 pm_runtime_set_active(dev); 618 pm_runtime_enable(dev); 619 620 return 0; 621 } 622 #endif 623 624 static const struct dev_pm_ops cdns3_pm_ops = { 625 SET_SYSTEM_SLEEP_PM_OPS(cdns3_suspend, cdns3_resume) 626 }; 627 628 #ifdef CONFIG_OF 629 static const struct of_device_id of_cdns3_match[] = { 630 { .compatible = "cdns,usb3" }, 631 { }, 632 }; 633 MODULE_DEVICE_TABLE(of, of_cdns3_match); 634 #endif 635 636 static struct platform_driver cdns3_driver = { 637 .probe = cdns3_probe, 638 .remove = cdns3_remove, 639 .driver = { 640 .name = "cdns-usb3", 641 .of_match_table = of_match_ptr(of_cdns3_match), 642 .pm = &cdns3_pm_ops, 643 }, 644 }; 645 646 module_platform_driver(cdns3_driver); 647 648 MODULE_ALIAS("platform:cdns3"); 649 MODULE_AUTHOR("Pawel Laszczak <pawell@cadence.com>"); 650 MODULE_LICENSE("GPL v2"); 651 MODULE_DESCRIPTION("Cadence USB3 DRD Controller Driver"); 652