Lines Matching +full:rcar +full:- +full:gen3 +full:- +full:xhci

1 // SPDX-License-Identifier: GPL-2.0
3 * xhci-plat.c - xHCI host controller driver platform Bus Glue.
5 * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com
8 * A lot of code borrowed from the Linux xHCI driver.
12 #include <linux/dma-mapping.h>
23 #include "xhci.h"
24 #include "xhci-plat.h"
25 #include "xhci-mvebu.h"
26 #include "xhci-rcar.h"
43 if (priv->plat_start) in xhci_priv_plat_start()
44 priv->plat_start(hcd); in xhci_priv_plat_start()
51 if (!priv->plat_setup) in xhci_priv_plat_setup()
54 return priv->plat_setup(hcd); in xhci_priv_plat_setup()
61 if (!priv->init_quirk) in xhci_priv_init_quirk()
64 return priv->init_quirk(hcd); in xhci_priv_init_quirk()
71 if (!priv->suspend_quirk) in xhci_priv_suspend_quirk()
74 return priv->suspend_quirk(hcd); in xhci_priv_suspend_quirk()
81 if (!priv->resume_quirk) in xhci_priv_resume_quirk()
84 return priv->resume_quirk(hcd); in xhci_priv_resume_quirk()
87 static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) in xhci_plat_quirks() argument
89 struct xhci_plat_priv *priv = xhci_to_priv(xhci); in xhci_plat_quirks()
96 xhci->quirks |= XHCI_PLAT | priv->quirks; in xhci_plat_quirks()
142 .compatible = "generic-xhci",
144 .compatible = "xhci-platform",
147 .compatible = "marvell,armada-375-xhci",
150 .compatible = "marvell,armada-380-xhci",
153 .compatible = "marvell,armada3700-xhci",
156 .compatible = "renesas,xhci-r8a7790",
159 .compatible = "renesas,xhci-r8a7791",
162 .compatible = "renesas,xhci-r8a7793",
165 .compatible = "renesas,xhci-r8a7795",
168 .compatible = "renesas,xhci-r8a7796",
171 .compatible = "renesas,rcar-gen2-xhci",
174 .compatible = "renesas,rcar-gen3-xhci",
177 .compatible = "brcm,xhci-brcm-v2",
180 .compatible = "brcm,bcm7445-xhci",
194 return -EINVAL; in xhci_plat_register_vendor_ops()
202 static int xhci_vendor_init(struct xhci_hcd *xhci) in xhci_vendor_init() argument
207 ops = xhci->vendor_ops = xhci_plat_vendor_overwrite.vendor_ops; in xhci_vendor_init()
209 if (ops && ops->vendor_init) in xhci_vendor_init()
210 return ops->vendor_init(xhci); in xhci_vendor_init()
214 static void xhci_vendor_cleanup(struct xhci_hcd *xhci) in xhci_vendor_cleanup() argument
216 struct xhci_vendor_ops *ops = xhci_vendor_get_ops(xhci); in xhci_vendor_cleanup()
218 if (ops && ops->vendor_cleanup) in xhci_vendor_cleanup()
219 ops->vendor_cleanup(xhci); in xhci_vendor_cleanup()
221 xhci->vendor_ops = NULL; in xhci_vendor_cleanup()
229 struct xhci_hcd *xhci; in xhci_plat_probe() local
238 return -ENODEV; in xhci_plat_probe()
250 * 2. xhci_plat is child of a device from firmware (dwc3-plat) in xhci_plat_probe()
251 * 3. xhci_plat is grandchild of a pci device (dwc3-pci) in xhci_plat_probe()
253 for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { in xhci_plat_probe()
254 if (is_of_node(sysdev->fwnode) || in xhci_plat_probe()
255 is_acpi_device_node(sysdev->fwnode)) in xhci_plat_probe()
258 else if (sysdev->bus == &pci_bus_type) in xhci_plat_probe()
264 sysdev = &pdev->dev; in xhci_plat_probe()
266 /* Try to set 64-bit DMA first */ in xhci_plat_probe()
267 if (WARN_ON(!sysdev->dma_mask)) in xhci_plat_probe()
274 /* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */ in xhci_plat_probe()
281 pm_runtime_set_active(&pdev->dev); in xhci_plat_probe()
282 pm_runtime_enable(&pdev->dev); in xhci_plat_probe()
283 pm_runtime_get_noresume(&pdev->dev); in xhci_plat_probe()
285 hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, in xhci_plat_probe()
286 dev_name(&pdev->dev), NULL); in xhci_plat_probe()
288 ret = -ENOMEM; in xhci_plat_probe()
292 hcd->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in xhci_plat_probe()
293 if (IS_ERR(hcd->regs)) { in xhci_plat_probe()
294 ret = PTR_ERR(hcd->regs); in xhci_plat_probe()
298 hcd->rsrc_start = res->start; in xhci_plat_probe()
299 hcd->rsrc_len = resource_size(res); in xhci_plat_probe()
301 xhci = hcd_to_xhci(hcd); in xhci_plat_probe()
307 xhci->reg_clk = devm_clk_get_optional(&pdev->dev, "reg"); in xhci_plat_probe()
308 if (IS_ERR(xhci->reg_clk)) { in xhci_plat_probe()
309 ret = PTR_ERR(xhci->reg_clk); in xhci_plat_probe()
313 ret = clk_prepare_enable(xhci->reg_clk); in xhci_plat_probe()
317 xhci->clk = devm_clk_get_optional(&pdev->dev, NULL); in xhci_plat_probe()
318 if (IS_ERR(xhci->clk)) { in xhci_plat_probe()
319 ret = PTR_ERR(xhci->clk); in xhci_plat_probe()
323 ret = clk_prepare_enable(xhci->clk); in xhci_plat_probe()
327 if (pdev->dev.of_node) in xhci_plat_probe()
328 priv_match = of_device_get_match_data(&pdev->dev); in xhci_plat_probe()
330 priv_match = dev_get_platdata(&pdev->dev); in xhci_plat_probe()
338 device_set_wakeup_capable(&pdev->dev, true); in xhci_plat_probe()
340 xhci->main_hcd = hcd; in xhci_plat_probe()
341 xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, in xhci_plat_probe()
342 dev_name(&pdev->dev), hcd); in xhci_plat_probe()
343 if (!xhci->shared_hcd) { in xhci_plat_probe()
344 ret = -ENOMEM; in xhci_plat_probe()
349 xhci->imod_interval = 40000; in xhci_plat_probe()
352 for (tmpdev = &pdev->dev; tmpdev; tmpdev = tmpdev->parent) { in xhci_plat_probe()
354 if (device_property_read_bool(tmpdev, "usb2-lpm-disable")) in xhci_plat_probe()
355 xhci->quirks |= XHCI_HW_LPM_DISABLE; in xhci_plat_probe()
357 if (device_property_read_bool(tmpdev, "usb3-lpm-capable")) in xhci_plat_probe()
358 xhci->quirks |= XHCI_LPM_SUPPORT; in xhci_plat_probe()
360 if (device_property_read_bool(tmpdev, "quirk-broken-port-ped")) in xhci_plat_probe()
361 xhci->quirks |= XHCI_BROKEN_PORT_PED; in xhci_plat_probe()
363 if (device_property_read_bool(tmpdev, "quirk-skip-phy-init")) in xhci_plat_probe()
364 xhci->quirks |= XHCI_SKIP_PHY_INIT; in xhci_plat_probe()
367 "xhci-u2-broken-suspend")) in xhci_plat_probe()
368 xhci->quirks |= XHCI_U2_BROKEN_SUSPEND; in xhci_plat_probe()
370 device_property_read_u32(tmpdev, "imod-interval-ns", in xhci_plat_probe()
371 &xhci->imod_interval); in xhci_plat_probe()
374 hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0); in xhci_plat_probe()
375 if (IS_ERR(hcd->usb_phy)) { in xhci_plat_probe()
376 ret = PTR_ERR(hcd->usb_phy); in xhci_plat_probe()
377 if (ret == -EPROBE_DEFER) in xhci_plat_probe()
379 hcd->usb_phy = NULL; in xhci_plat_probe()
381 ret = usb_phy_init(hcd->usb_phy); in xhci_plat_probe()
386 ret = xhci_vendor_init(xhci); in xhci_plat_probe()
390 hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node); in xhci_plat_probe()
391 xhci->shared_hcd->tpl_support = hcd->tpl_support; in xhci_plat_probe()
399 if ((xhci->quirks & XHCI_SKIP_PHY_INIT) || (priv && (priv->quirks & XHCI_SKIP_PHY_INIT))) in xhci_plat_probe()
400 hcd->skip_phy_initialization = 1; in xhci_plat_probe()
402 if (priv && (priv->quirks & XHCI_SG_TRB_CACHE_SIZE_QUIRK)) in xhci_plat_probe()
403 xhci->quirks |= XHCI_SG_TRB_CACHE_SIZE_QUIRK; in xhci_plat_probe()
409 if (HCC_MAX_PSA(xhci->hcc_params) >= 4) in xhci_plat_probe()
410 xhci->shared_hcd->can_do_streams = 1; in xhci_plat_probe()
412 ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); in xhci_plat_probe()
416 device_enable_async_suspend(&pdev->dev); in xhci_plat_probe()
417 pm_runtime_put_noidle(&pdev->dev); in xhci_plat_probe()
423 pm_runtime_forbid(&pdev->dev); in xhci_plat_probe()
432 usb_phy_shutdown(hcd->usb_phy); in xhci_plat_probe()
435 usb_put_hcd(xhci->shared_hcd); in xhci_plat_probe()
438 clk_disable_unprepare(xhci->clk); in xhci_plat_probe()
441 clk_disable_unprepare(xhci->reg_clk); in xhci_plat_probe()
447 pm_runtime_put_noidle(&pdev->dev); in xhci_plat_probe()
448 pm_runtime_disable(&pdev->dev); in xhci_plat_probe()
456 struct xhci_hcd *xhci = hcd_to_xhci(hcd); in xhci_plat_remove() local
457 struct clk *clk = xhci->clk; in xhci_plat_remove()
458 struct clk *reg_clk = xhci->reg_clk; in xhci_plat_remove()
459 struct usb_hcd *shared_hcd = xhci->shared_hcd; in xhci_plat_remove()
461 pm_runtime_get_sync(&dev->dev); in xhci_plat_remove()
462 xhci->xhc_state |= XHCI_STATE_REMOVING; in xhci_plat_remove()
465 xhci->shared_hcd = NULL; in xhci_plat_remove()
466 usb_phy_shutdown(hcd->usb_phy); in xhci_plat_remove()
470 xhci_vendor_cleanup(xhci); in xhci_plat_remove()
477 pm_runtime_disable(&dev->dev); in xhci_plat_remove()
478 pm_runtime_put_noidle(&dev->dev); in xhci_plat_remove()
479 pm_runtime_set_suspended(&dev->dev); in xhci_plat_remove()
487 struct xhci_hcd *xhci = hcd_to_xhci(hcd); in xhci_plat_suspend() local
500 ret = xhci_suspend(xhci, device_may_wakeup(dev)); in xhci_plat_suspend()
504 if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { in xhci_plat_suspend()
505 clk_disable_unprepare(xhci->clk); in xhci_plat_suspend()
506 clk_disable_unprepare(xhci->reg_clk); in xhci_plat_suspend()
515 struct xhci_hcd *xhci = hcd_to_xhci(hcd); in xhci_plat_resume() local
518 if (!device_may_wakeup(dev) && (xhci->quirks & XHCI_SUSPEND_RESUME_CLKS)) { in xhci_plat_resume()
519 clk_prepare_enable(xhci->clk); in xhci_plat_resume()
520 clk_prepare_enable(xhci->reg_clk); in xhci_plat_resume()
527 ret = xhci_resume(xhci, 0); in xhci_plat_resume()
541 struct xhci_hcd *xhci = hcd_to_xhci(hcd); in xhci_plat_runtime_suspend() local
548 return xhci_suspend(xhci, true); in xhci_plat_runtime_suspend()
554 struct xhci_hcd *xhci = hcd_to_xhci(hcd); in xhci_plat_runtime_resume() local
556 return xhci_resume(xhci, 0); in xhci_plat_runtime_resume()
569 /* XHCI-compliant USB Controller */
581 .name = "xhci-hcd",
587 MODULE_ALIAS("platform:xhci-hcd");
602 MODULE_DESCRIPTION("xHCI Platform Host Controller Driver");