1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * xhci-plat.c - xHCI host controller driver platform Bus Glue. 4 * 5 * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com 6 * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de> 7 * 8 * A lot of code borrowed from the Linux xHCI driver. 9 */ 10 11 #include <linux/clk.h> 12 #include <linux/dma-mapping.h> 13 #include <linux/module.h> 14 #include <linux/pci.h> 15 #include <linux/of.h> 16 #include <linux/platform_device.h> 17 #include <linux/usb/phy.h> 18 #include <linux/slab.h> 19 #include <linux/acpi.h> 20 #include <linux/usb/of.h> 21 #include <linux/reset.h> 22 23 #include "xhci.h" 24 #include "xhci-plat.h" 25 #include "xhci-mvebu.h" 26 27 static struct hc_driver __read_mostly xhci_plat_hc_driver; 28 29 static int xhci_plat_setup(struct usb_hcd *hcd); 30 static int xhci_plat_start(struct usb_hcd *hcd); 31 32 static const struct xhci_driver_overrides xhci_plat_overrides __initconst = { 33 .extra_priv_size = sizeof(struct xhci_plat_priv), 34 .reset = xhci_plat_setup, 35 .start = xhci_plat_start, 36 }; 37 38 static void xhci_priv_plat_start(struct usb_hcd *hcd) 39 { 40 struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); 41 42 if (priv->plat_start) 43 priv->plat_start(hcd); 44 } 45 46 static int xhci_priv_init_quirk(struct usb_hcd *hcd) 47 { 48 struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); 49 50 if (!priv->init_quirk) 51 return 0; 52 53 return priv->init_quirk(hcd); 54 } 55 56 static int xhci_priv_suspend_quirk(struct usb_hcd *hcd) 57 { 58 struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); 59 60 if (!priv->suspend_quirk) 61 return 0; 62 63 return priv->suspend_quirk(hcd); 64 } 65 66 static int xhci_priv_resume_quirk(struct usb_hcd *hcd) 67 { 68 struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); 69 70 if (!priv->resume_quirk) 71 return 0; 72 73 return priv->resume_quirk(hcd); 74 } 75 76 static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) 77 { 78 struct xhci_plat_priv *priv = xhci_to_priv(xhci); 79 80 xhci->quirks |= priv->quirks; 81 } 82 83 /* called during probe() after chip reset completes */ 84 static int xhci_plat_setup(struct usb_hcd *hcd) 85 { 86 int ret; 87 88 89 ret = xhci_priv_init_quirk(hcd); 90 if (ret) 91 return ret; 92 93 return xhci_gen_setup(hcd, xhci_plat_quirks); 94 } 95 96 static int xhci_plat_start(struct usb_hcd *hcd) 97 { 98 xhci_priv_plat_start(hcd); 99 return xhci_run(hcd); 100 } 101 102 #ifdef CONFIG_OF 103 static const struct xhci_plat_priv xhci_plat_marvell_armada = { 104 .init_quirk = xhci_mvebu_mbus_init_quirk, 105 }; 106 107 static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = { 108 .init_quirk = xhci_mvebu_a3700_init_quirk, 109 }; 110 111 static const struct xhci_plat_priv xhci_plat_brcm = { 112 .quirks = XHCI_RESET_ON_RESUME | XHCI_SUSPEND_RESUME_CLKS, 113 }; 114 115 static const struct of_device_id usb_xhci_of_match[] = { 116 { 117 .compatible = "generic-xhci", 118 }, { 119 .compatible = "xhci-platform", 120 }, { 121 .compatible = "marvell,armada-375-xhci", 122 .data = &xhci_plat_marvell_armada, 123 }, { 124 .compatible = "marvell,armada-380-xhci", 125 .data = &xhci_plat_marvell_armada, 126 }, { 127 .compatible = "marvell,armada3700-xhci", 128 .data = &xhci_plat_marvell_armada3700, 129 }, { 130 .compatible = "brcm,xhci-brcm-v2", 131 .data = &xhci_plat_brcm, 132 }, { 133 .compatible = "brcm,bcm7445-xhci", 134 .data = &xhci_plat_brcm, 135 }, 136 {}, 137 }; 138 MODULE_DEVICE_TABLE(of, usb_xhci_of_match); 139 #endif 140 141 int xhci_plat_probe(struct platform_device *pdev, struct device *sysdev, const struct xhci_plat_priv *priv_match) 142 { 143 const struct hc_driver *driver; 144 struct device *tmpdev; 145 struct xhci_hcd *xhci; 146 struct resource *res; 147 struct usb_hcd *hcd, *usb3_hcd; 148 int ret; 149 int irq; 150 struct xhci_plat_priv *priv = NULL; 151 152 153 if (usb_disabled()) 154 return -ENODEV; 155 156 driver = &xhci_plat_hc_driver; 157 158 irq = platform_get_irq(pdev, 0); 159 if (irq < 0) 160 return irq; 161 162 if (!sysdev) 163 sysdev = &pdev->dev; 164 165 ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64)); 166 if (ret) 167 return ret; 168 169 pm_runtime_set_active(&pdev->dev); 170 pm_runtime_enable(&pdev->dev); 171 pm_runtime_get_noresume(&pdev->dev); 172 173 hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, 174 dev_name(&pdev->dev), NULL); 175 if (!hcd) { 176 ret = -ENOMEM; 177 goto disable_runtime; 178 } 179 180 hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 181 if (IS_ERR(hcd->regs)) { 182 ret = PTR_ERR(hcd->regs); 183 goto put_hcd; 184 } 185 186 hcd->rsrc_start = res->start; 187 hcd->rsrc_len = resource_size(res); 188 189 xhci = hcd_to_xhci(hcd); 190 191 xhci->allow_single_roothub = 1; 192 193 /* 194 * Not all platforms have clks so it is not an error if the 195 * clock do not exist. 196 */ 197 xhci->reg_clk = devm_clk_get_optional(&pdev->dev, "reg"); 198 if (IS_ERR(xhci->reg_clk)) { 199 ret = PTR_ERR(xhci->reg_clk); 200 goto put_hcd; 201 } 202 203 xhci->clk = devm_clk_get_optional(&pdev->dev, NULL); 204 if (IS_ERR(xhci->clk)) { 205 ret = PTR_ERR(xhci->clk); 206 goto put_hcd; 207 } 208 209 xhci->reset = devm_reset_control_array_get_optional_shared(&pdev->dev); 210 if (IS_ERR(xhci->reset)) { 211 ret = PTR_ERR(xhci->reset); 212 goto put_hcd; 213 } 214 215 ret = reset_control_deassert(xhci->reset); 216 if (ret) 217 goto put_hcd; 218 219 ret = clk_prepare_enable(xhci->reg_clk); 220 if (ret) 221 goto err_reset; 222 223 ret = clk_prepare_enable(xhci->clk); 224 if (ret) 225 goto disable_reg_clk; 226 227 if (priv_match) { 228 priv = hcd_to_xhci_priv(hcd); 229 /* Just copy data for now */ 230 *priv = *priv_match; 231 } 232 233 device_set_wakeup_capable(&pdev->dev, true); 234 235 xhci->main_hcd = hcd; 236 237 /* imod_interval is the interrupt moderation value in nanoseconds. */ 238 xhci->imod_interval = 40000; 239 240 /* Iterate over all parent nodes for finding quirks */ 241 for (tmpdev = &pdev->dev; tmpdev; tmpdev = tmpdev->parent) { 242 243 if (device_property_read_bool(tmpdev, "usb2-lpm-disable")) 244 xhci->quirks |= XHCI_HW_LPM_DISABLE; 245 246 if (device_property_read_bool(tmpdev, "usb3-lpm-capable")) 247 xhci->quirks |= XHCI_LPM_SUPPORT; 248 249 if (device_property_read_bool(tmpdev, "quirk-broken-port-ped")) 250 xhci->quirks |= XHCI_BROKEN_PORT_PED; 251 252 device_property_read_u32(tmpdev, "imod-interval-ns", 253 &xhci->imod_interval); 254 } 255 256 hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0); 257 if (IS_ERR(hcd->usb_phy)) { 258 ret = PTR_ERR(hcd->usb_phy); 259 if (ret == -EPROBE_DEFER) 260 goto disable_clk; 261 hcd->usb_phy = NULL; 262 } else { 263 ret = usb_phy_init(hcd->usb_phy); 264 if (ret) 265 goto disable_clk; 266 } 267 268 hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node); 269 270 if (priv && (priv->quirks & XHCI_SKIP_PHY_INIT)) 271 hcd->skip_phy_initialization = 1; 272 273 if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK)) 274 xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK; 275 276 ret = usb_add_hcd(hcd, irq, IRQF_SHARED); 277 if (ret) 278 goto disable_usb_phy; 279 280 if (!xhci_has_one_roothub(xhci)) { 281 xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, 282 dev_name(&pdev->dev), hcd); 283 if (!xhci->shared_hcd) { 284 ret = -ENOMEM; 285 goto dealloc_usb2_hcd; 286 } 287 288 xhci->shared_hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, 289 "usb-phy", 1); 290 if (IS_ERR(xhci->shared_hcd->usb_phy)) { 291 xhci->shared_hcd->usb_phy = NULL; 292 } else { 293 ret = usb_phy_init(xhci->shared_hcd->usb_phy); 294 if (ret) 295 dev_err(sysdev, "%s init usb3phy fail (ret=%d)\n", 296 __func__, ret); 297 } 298 299 xhci->shared_hcd->tpl_support = hcd->tpl_support; 300 } 301 302 usb3_hcd = xhci_get_usb3_hcd(xhci); 303 if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4) 304 usb3_hcd->can_do_streams = 1; 305 306 if (xhci->shared_hcd) { 307 ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); 308 if (ret) 309 goto put_usb3_hcd; 310 } 311 312 device_enable_async_suspend(&pdev->dev); 313 pm_runtime_put_noidle(&pdev->dev); 314 315 /* 316 * Prevent runtime pm from being on as default, users should enable 317 * runtime pm using power/control in sysfs. 318 */ 319 pm_runtime_forbid(&pdev->dev); 320 321 return 0; 322 323 324 put_usb3_hcd: 325 usb_put_hcd(xhci->shared_hcd); 326 327 dealloc_usb2_hcd: 328 usb_remove_hcd(hcd); 329 330 disable_usb_phy: 331 usb_phy_shutdown(hcd->usb_phy); 332 333 disable_clk: 334 clk_disable_unprepare(xhci->clk); 335 336 disable_reg_clk: 337 clk_disable_unprepare(xhci->reg_clk); 338 339 err_reset: 340 reset_control_assert(xhci->reset); 341 342 put_hcd: 343 usb_put_hcd(hcd); 344 345 disable_runtime: 346 pm_runtime_put_noidle(&pdev->dev); 347 pm_runtime_disable(&pdev->dev); 348 349 return ret; 350 } 351 EXPORT_SYMBOL_GPL(xhci_plat_probe); 352 353 static int xhci_generic_plat_probe(struct platform_device *pdev) 354 { 355 const struct xhci_plat_priv *priv_match; 356 struct device *sysdev; 357 int ret; 358 359 /* 360 * sysdev must point to a device that is known to the system firmware 361 * or PCI hardware. We handle these three cases here: 362 * 1. xhci_plat comes from firmware 363 * 2. xhci_plat is child of a device from firmware (dwc3-plat) 364 * 3. xhci_plat is grandchild of a pci device (dwc3-pci) 365 */ 366 for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { 367 if (is_of_node(sysdev->fwnode) || 368 is_acpi_device_node(sysdev->fwnode)) 369 break; 370 else if (dev_is_pci(sysdev)) 371 break; 372 } 373 374 if (!sysdev) 375 sysdev = &pdev->dev; 376 377 if (WARN_ON(!sysdev->dma_mask)) { 378 /* Platform did not initialize dma_mask */ 379 ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64)); 380 if (ret) 381 return ret; 382 } 383 384 if (pdev->dev.of_node) 385 priv_match = of_device_get_match_data(&pdev->dev); 386 else 387 priv_match = dev_get_platdata(&pdev->dev); 388 389 return xhci_plat_probe(pdev, sysdev, priv_match); 390 } 391 392 void xhci_plat_remove(struct platform_device *dev) 393 { 394 struct usb_hcd *hcd = platform_get_drvdata(dev); 395 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 396 struct clk *clk = xhci->clk; 397 struct clk *reg_clk = xhci->reg_clk; 398 struct usb_hcd *shared_hcd = xhci->shared_hcd; 399 400 xhci->xhc_state |= XHCI_STATE_REMOVING; 401 pm_runtime_get_sync(&dev->dev); 402 403 if (shared_hcd) { 404 usb_remove_hcd(shared_hcd); 405 xhci->shared_hcd = NULL; 406 } 407 408 usb_phy_shutdown(hcd->usb_phy); 409 410 usb_remove_hcd(hcd); 411 412 if (shared_hcd) 413 usb_put_hcd(shared_hcd); 414 415 clk_disable_unprepare(clk); 416 clk_disable_unprepare(reg_clk); 417 reset_control_assert(xhci->reset); 418 usb_put_hcd(hcd); 419 420 pm_runtime_disable(&dev->dev); 421 pm_runtime_put_noidle(&dev->dev); 422 pm_runtime_set_suspended(&dev->dev); 423 } 424 EXPORT_SYMBOL_GPL(xhci_plat_remove); 425 426 static int __maybe_unused xhci_plat_suspend(struct device *dev) 427 { 428 struct usb_hcd *hcd = dev_get_drvdata(dev); 429 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 430 int ret; 431 432 if (pm_runtime_suspended(dev)) 433 pm_runtime_resume(dev); 434 435 ret = xhci_priv_suspend_quirk(hcd); 436 if (ret) 437 return ret; 438 /* 439 * xhci_suspend() needs `do_wakeup` to know whether host is allowed 440 * to do wakeup during suspend. 441 */ 442 ret = xhci_suspend(xhci, device_may_wakeup(dev)); 443 if (ret) 444 return ret; 445 446 if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { 447 clk_disable_unprepare(xhci->clk); 448 clk_disable_unprepare(xhci->reg_clk); 449 } 450 451 return 0; 452 } 453 454 static int __maybe_unused xhci_plat_resume(struct device *dev) 455 { 456 struct usb_hcd *hcd = dev_get_drvdata(dev); 457 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 458 int ret; 459 460 if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { 461 ret = clk_prepare_enable(xhci->clk); 462 if (ret) 463 return ret; 464 465 ret = clk_prepare_enable(xhci->reg_clk); 466 if (ret) { 467 clk_disable_unprepare(xhci->clk); 468 return ret; 469 } 470 } 471 472 ret = xhci_priv_resume_quirk(hcd); 473 if (ret) 474 goto disable_clks; 475 476 ret = xhci_resume(xhci, PMSG_RESUME); 477 if (ret) 478 goto disable_clks; 479 480 pm_runtime_disable(dev); 481 pm_runtime_set_active(dev); 482 pm_runtime_enable(dev); 483 484 return 0; 485 486 disable_clks: 487 if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { 488 clk_disable_unprepare(xhci->clk); 489 clk_disable_unprepare(xhci->reg_clk); 490 } 491 492 return ret; 493 } 494 495 static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev) 496 { 497 struct usb_hcd *hcd = dev_get_drvdata(dev); 498 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 499 int ret; 500 501 ret = xhci_priv_suspend_quirk(hcd); 502 if (ret) 503 return ret; 504 505 return xhci_suspend(xhci, true); 506 } 507 508 static int __maybe_unused xhci_plat_runtime_resume(struct device *dev) 509 { 510 struct usb_hcd *hcd = dev_get_drvdata(dev); 511 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 512 513 return xhci_resume(xhci, PMSG_AUTO_RESUME); 514 } 515 516 const struct dev_pm_ops xhci_plat_pm_ops = { 517 SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume) 518 519 SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, 520 xhci_plat_runtime_resume, 521 NULL) 522 }; 523 EXPORT_SYMBOL_GPL(xhci_plat_pm_ops); 524 525 #ifdef CONFIG_ACPI 526 static const struct acpi_device_id usb_xhci_acpi_match[] = { 527 /* XHCI-compliant USB Controller */ 528 { "PNP0D10", }, 529 { } 530 }; 531 MODULE_DEVICE_TABLE(acpi, usb_xhci_acpi_match); 532 #endif 533 534 static struct platform_driver usb_generic_xhci_driver = { 535 .probe = xhci_generic_plat_probe, 536 .remove_new = xhci_plat_remove, 537 .shutdown = usb_hcd_platform_shutdown, 538 .driver = { 539 .name = "xhci-hcd", 540 .pm = &xhci_plat_pm_ops, 541 .of_match_table = of_match_ptr(usb_xhci_of_match), 542 .acpi_match_table = ACPI_PTR(usb_xhci_acpi_match), 543 }, 544 }; 545 MODULE_ALIAS("platform:xhci-hcd"); 546 547 static int __init xhci_plat_init(void) 548 { 549 xhci_init_driver(&xhci_plat_hc_driver, &xhci_plat_overrides); 550 return platform_driver_register(&usb_generic_xhci_driver); 551 } 552 module_init(xhci_plat_init); 553 554 static void __exit xhci_plat_exit(void) 555 { 556 platform_driver_unregister(&usb_generic_xhci_driver); 557 } 558 module_exit(xhci_plat_exit); 559 560 MODULE_DESCRIPTION("xHCI Platform Host Controller Driver"); 561 MODULE_LICENSE("GPL"); 562