Lines Matching +full:brcmstb +full:- +full:reset
1 // SPDX-License-Identifier: GPL-2.0-only
3 * phy-brcm-usb.c - Broadcom USB Phy Driver
5 * Copyright (C) 2015-2017 Broadcom
17 #include <linux/soc/brcmstb/brcmstb.h>
18 #include <dt-bindings/phy/phy.h>
22 #include "phy-brcm-usb-init.h"
47 { USB_CTLR_MODE_TYPEC_PD, "typec-pd" }
91 priv->pm_active = true; in brcm_pm_notifier()
96 priv->pm_active = false; in brcm_pm_notifier()
115 container_of(phy, struct brcm_usb_phy_data, phys[phy->id]); in brcm_usb_phy_init()
117 if (priv->pm_active) in brcm_usb_phy_init()
124 mutex_lock(&priv->mutex); in brcm_usb_phy_init()
125 if (priv->init_count++ == 0) { in brcm_usb_phy_init()
126 clk_prepare_enable(priv->usb_20_clk); in brcm_usb_phy_init()
127 clk_prepare_enable(priv->usb_30_clk); in brcm_usb_phy_init()
128 clk_prepare_enable(priv->suspend_clk); in brcm_usb_phy_init()
129 brcm_usb_init_common(&priv->ini); in brcm_usb_phy_init()
131 mutex_unlock(&priv->mutex); in brcm_usb_phy_init()
132 if (phy->id == BRCM_USB_PHY_2_0) in brcm_usb_phy_init()
133 brcm_usb_init_eohci(&priv->ini); in brcm_usb_phy_init()
134 else if (phy->id == BRCM_USB_PHY_3_0) in brcm_usb_phy_init()
135 brcm_usb_init_xhci(&priv->ini); in brcm_usb_phy_init()
136 phy->inited = true; in brcm_usb_phy_init()
137 dev_dbg(&gphy->dev, "INIT, id: %d, total: %d\n", phy->id, in brcm_usb_phy_init()
138 priv->init_count); in brcm_usb_phy_init()
147 container_of(phy, struct brcm_usb_phy_data, phys[phy->id]); in brcm_usb_phy_exit()
149 if (priv->pm_active) in brcm_usb_phy_exit()
152 dev_dbg(&gphy->dev, "EXIT\n"); in brcm_usb_phy_exit()
153 if (phy->id == BRCM_USB_PHY_2_0) in brcm_usb_phy_exit()
154 brcm_usb_uninit_eohci(&priv->ini); in brcm_usb_phy_exit()
155 if (phy->id == BRCM_USB_PHY_3_0) in brcm_usb_phy_exit()
156 brcm_usb_uninit_xhci(&priv->ini); in brcm_usb_phy_exit()
158 /* If both xhci and eohci are gone, reset everything else */ in brcm_usb_phy_exit()
159 mutex_lock(&priv->mutex); in brcm_usb_phy_exit()
160 if (--priv->init_count == 0) { in brcm_usb_phy_exit()
161 brcm_usb_uninit_common(&priv->ini); in brcm_usb_phy_exit()
162 clk_disable_unprepare(priv->usb_20_clk); in brcm_usb_phy_exit()
163 clk_disable_unprepare(priv->usb_30_clk); in brcm_usb_phy_exit()
164 clk_disable_unprepare(priv->suspend_clk); in brcm_usb_phy_exit()
166 mutex_unlock(&priv->mutex); in brcm_usb_phy_exit()
167 phy->inited = false; in brcm_usb_phy_exit()
186 switch (args->args[0]) { in brcm_usb_phy_xlate()
189 if (data->phys[BRCM_USB_PHY_2_0].phy) in brcm_usb_phy_xlate()
190 return data->phys[BRCM_USB_PHY_2_0].phy; in brcm_usb_phy_xlate()
195 if (data->phys[BRCM_USB_PHY_3_0].phy) in brcm_usb_phy_xlate()
196 return data->phys[BRCM_USB_PHY_3_0].phy; in brcm_usb_phy_xlate()
200 return ERR_PTR(-ENODEV); in brcm_usb_phy_xlate()
215 return -EINVAL; in name_to_value()
235 priv->ini.supported_port_modes)); in dr_mode_show()
251 priv->ini.port_mode = value; in dual_select_store()
252 brcm_usb_set_dual_select(&priv->ini); in dual_select_store()
267 value = brcm_usb_get_dual_select(&priv->ini); in dual_select_show()
292 -1,
301 -1,
311 -1,
323 -1,
333 -1,
339 .compatible = "brcm,bcm74110-usb-phy",
343 .compatible = "brcm,bcm4908-usb-phy",
347 .compatible = "brcm,bcm7216-usb-phy",
351 .compatible = "brcm,bcm7211-usb-phy",
355 .compatible = "brcm,brcmstb-usb-phy",
382 dev_dbg(&pdev->dev, in brcm_usb_get_regs()
387 dev_err(&pdev->dev, "can't get %s base addr\n", in brcm_usb_get_regs()
392 ini->regs[regs] = devm_ioremap_resource(&pdev->dev, res); in brcm_usb_get_regs()
393 if (IS_ERR(ini->regs[regs])) { in brcm_usb_get_regs()
394 dev_err(&pdev->dev, "can't map %s register space\n", in brcm_usb_get_regs()
405 struct device *dev = &pdev->dev; in brcm_usb_phy_dvr_init()
409 priv->usb_20_clk = of_clk_get_by_name(dn, "sw_usb"); in brcm_usb_phy_dvr_init()
410 if (IS_ERR(priv->usb_20_clk)) { in brcm_usb_phy_dvr_init()
411 if (PTR_ERR(priv->usb_20_clk) == -EPROBE_DEFER) in brcm_usb_phy_dvr_init()
412 return -EPROBE_DEFER; in brcm_usb_phy_dvr_init()
414 priv->usb_20_clk = NULL; in brcm_usb_phy_dvr_init()
416 err = clk_prepare_enable(priv->usb_20_clk); in brcm_usb_phy_dvr_init()
420 if (priv->has_eohci) { in brcm_usb_phy_dvr_init()
426 priv->phys[BRCM_USB_PHY_2_0].phy = gphy; in brcm_usb_phy_dvr_init()
427 priv->phys[BRCM_USB_PHY_2_0].id = BRCM_USB_PHY_2_0; in brcm_usb_phy_dvr_init()
428 phy_set_drvdata(gphy, &priv->phys[BRCM_USB_PHY_2_0]); in brcm_usb_phy_dvr_init()
431 if (priv->has_xhci) { in brcm_usb_phy_dvr_init()
437 priv->phys[BRCM_USB_PHY_3_0].phy = gphy; in brcm_usb_phy_dvr_init()
438 priv->phys[BRCM_USB_PHY_3_0].id = BRCM_USB_PHY_3_0; in brcm_usb_phy_dvr_init()
439 phy_set_drvdata(gphy, &priv->phys[BRCM_USB_PHY_3_0]); in brcm_usb_phy_dvr_init()
441 priv->usb_30_clk = of_clk_get_by_name(dn, "sw_usb3"); in brcm_usb_phy_dvr_init()
442 if (IS_ERR(priv->usb_30_clk)) { in brcm_usb_phy_dvr_init()
443 if (PTR_ERR(priv->usb_30_clk) == -EPROBE_DEFER) in brcm_usb_phy_dvr_init()
444 return -EPROBE_DEFER; in brcm_usb_phy_dvr_init()
447 priv->usb_30_clk = NULL; in brcm_usb_phy_dvr_init()
449 err = clk_prepare_enable(priv->usb_30_clk); in brcm_usb_phy_dvr_init()
454 priv->suspend_clk = clk_get(dev, "usb0_freerun"); in brcm_usb_phy_dvr_init()
455 if (IS_ERR(priv->suspend_clk)) { in brcm_usb_phy_dvr_init()
456 if (PTR_ERR(priv->suspend_clk) == -EPROBE_DEFER) in brcm_usb_phy_dvr_init()
457 return -EPROBE_DEFER; in brcm_usb_phy_dvr_init()
459 priv->suspend_clk = NULL; in brcm_usb_phy_dvr_init()
462 priv->wake_irq = platform_get_irq_byname_optional(pdev, "wake"); in brcm_usb_phy_dvr_init()
463 if (priv->wake_irq < 0) in brcm_usb_phy_dvr_init()
464 priv->wake_irq = platform_get_irq_byname_optional(pdev, "wakeup"); in brcm_usb_phy_dvr_init()
465 if (priv->wake_irq >= 0) { in brcm_usb_phy_dvr_init()
466 err = devm_request_irq(dev, priv->wake_irq, in brcm_usb_phy_dvr_init()
482 struct device *dev = &pdev->dev; in brcm_usb_phy_probe()
485 struct device_node *dn = pdev->dev.of_node; in brcm_usb_phy_probe()
494 return -ENOMEM; in brcm_usb_phy_probe()
497 priv->ini.family_id = brcmstb_get_family_id(); in brcm_usb_phy_probe()
498 priv->ini.product_id = brcmstb_get_product_id(); in brcm_usb_phy_probe()
500 info = of_device_get_match_data(&pdev->dev); in brcm_usb_phy_probe()
502 return -ENOENT; in brcm_usb_phy_probe()
504 info->init_func(&priv->ini); in brcm_usb_phy_probe()
507 priv->ini.family_name); in brcm_usb_phy_probe()
509 of_property_read_u32(dn, "brcm,ipp", &priv->ini.ipp); in brcm_usb_phy_probe()
510 of_property_read_u32(dn, "brcm,ioc", &priv->ini.ioc); in brcm_usb_phy_probe()
512 priv->ini.supported_port_modes = USB_CTLR_MODE_HOST; in brcm_usb_phy_probe()
517 mode, &priv->ini.supported_port_modes); in brcm_usb_phy_probe()
520 priv->ini.port_mode = priv->ini.supported_port_modes; in brcm_usb_phy_probe()
522 if (of_property_read_bool(dn, "brcm,has-xhci")) in brcm_usb_phy_probe()
523 priv->has_xhci = true; in brcm_usb_phy_probe()
524 if (of_property_read_bool(dn, "brcm,has-eohci")) in brcm_usb_phy_probe()
525 priv->has_eohci = true; in brcm_usb_phy_probe()
528 if (info->required_regs[x] >= BRCM_REGS_MAX) in brcm_usb_phy_probe()
531 err = brcm_usb_get_regs(pdev, info->required_regs[x], in brcm_usb_phy_probe()
532 &priv->ini, false); in brcm_usb_phy_probe()
534 return -EINVAL; in brcm_usb_phy_probe()
536 if (info->optional_reg) { in brcm_usb_phy_probe()
537 err = brcm_usb_get_regs(pdev, info->optional_reg, in brcm_usb_phy_probe()
538 &priv->ini, true); in brcm_usb_phy_probe()
540 return -EINVAL; in brcm_usb_phy_probe()
547 priv->pm_notifier.notifier_call = brcm_pm_notifier; in brcm_usb_phy_probe()
548 register_pm_notifier(&priv->pm_notifier); in brcm_usb_phy_probe()
550 mutex_init(&priv->mutex); in brcm_usb_phy_probe()
553 brcm_usb_init_ipp(&priv->ini); in brcm_usb_phy_probe()
559 if (priv->ini.supported_port_modes != USB_CTLR_MODE_DRD) in brcm_usb_phy_probe()
561 err = sysfs_create_group(&dev->kobj, &brcm_usb_phy_group); in brcm_usb_phy_probe()
566 rmap = syscon_regmap_lookup_by_phandle(dev->of_node, in brcm_usb_phy_probe()
567 "syscon-piarbctl"); in brcm_usb_phy_probe()
569 rmap = syscon_regmap_lookup_by_phandle(dev->of_node, in brcm_usb_phy_probe()
570 "brcm,syscon-piarbctl"); in brcm_usb_phy_probe()
572 priv->ini.syscon_piarbctl = rmap; in brcm_usb_phy_probe()
575 if (priv->has_xhci) in brcm_usb_phy_probe()
576 brcm_usb_uninit_xhci(&priv->ini); in brcm_usb_phy_probe()
577 if (priv->has_eohci) in brcm_usb_phy_probe()
578 brcm_usb_uninit_eohci(&priv->ini); in brcm_usb_phy_probe()
579 brcm_usb_uninit_common(&priv->ini); in brcm_usb_phy_probe()
580 clk_disable_unprepare(priv->usb_20_clk); in brcm_usb_phy_probe()
581 clk_disable_unprepare(priv->usb_30_clk); in brcm_usb_phy_probe()
590 struct brcm_usb_phy_data *priv = dev_get_drvdata(&pdev->dev); in brcm_usb_phy_remove()
592 sysfs_remove_group(&pdev->dev.kobj, &brcm_usb_phy_group); in brcm_usb_phy_remove()
593 unregister_pm_notifier(&priv->pm_notifier); in brcm_usb_phy_remove()
601 if (priv->init_count) { in brcm_usb_phy_suspend()
603 priv->ini.wake_enabled = device_may_wakeup(dev); in brcm_usb_phy_suspend()
604 if (priv->phys[BRCM_USB_PHY_3_0].inited) in brcm_usb_phy_suspend()
605 brcm_usb_uninit_xhci(&priv->ini); in brcm_usb_phy_suspend()
606 if (priv->phys[BRCM_USB_PHY_2_0].inited) in brcm_usb_phy_suspend()
607 brcm_usb_uninit_eohci(&priv->ini); in brcm_usb_phy_suspend()
608 brcm_usb_uninit_common(&priv->ini); in brcm_usb_phy_suspend()
612 * to work for both older XHCI->3.0-clks, EOHCI->2.0-clks in brcm_usb_phy_suspend()
613 * and newer XHCI->2.0-clks/3.0-clks. in brcm_usb_phy_suspend()
616 if (!priv->ini.wake_enabled) { in brcm_usb_phy_suspend()
617 if (priv->phys[BRCM_USB_PHY_3_0].inited) in brcm_usb_phy_suspend()
618 clk_disable_unprepare(priv->usb_30_clk); in brcm_usb_phy_suspend()
619 if (priv->phys[BRCM_USB_PHY_2_0].inited || in brcm_usb_phy_suspend()
620 !priv->has_eohci) in brcm_usb_phy_suspend()
621 clk_disable_unprepare(priv->usb_20_clk); in brcm_usb_phy_suspend()
623 if (priv->wake_irq >= 0) in brcm_usb_phy_suspend()
624 enable_irq_wake(priv->wake_irq); in brcm_usb_phy_suspend()
633 if (!priv->ini.wake_enabled) { in brcm_usb_phy_resume()
634 clk_prepare_enable(priv->usb_20_clk); in brcm_usb_phy_resume()
635 clk_prepare_enable(priv->usb_30_clk); in brcm_usb_phy_resume()
637 brcm_usb_init_ipp(&priv->ini); in brcm_usb_phy_resume()
643 if (priv->init_count) { in brcm_usb_phy_resume()
645 if (priv->wake_irq >= 0) in brcm_usb_phy_resume()
646 disable_irq_wake(priv->wake_irq); in brcm_usb_phy_resume()
647 brcm_usb_init_common(&priv->ini); in brcm_usb_phy_resume()
648 if (priv->phys[BRCM_USB_PHY_2_0].inited) { in brcm_usb_phy_resume()
649 brcm_usb_init_eohci(&priv->ini); in brcm_usb_phy_resume()
650 } else if (priv->has_eohci) { in brcm_usb_phy_resume()
651 brcm_usb_uninit_eohci(&priv->ini); in brcm_usb_phy_resume()
652 clk_disable_unprepare(priv->usb_20_clk); in brcm_usb_phy_resume()
654 if (priv->phys[BRCM_USB_PHY_3_0].inited) { in brcm_usb_phy_resume()
655 brcm_usb_init_xhci(&priv->ini); in brcm_usb_phy_resume()
656 } else if (priv->has_xhci) { in brcm_usb_phy_resume()
657 brcm_usb_uninit_xhci(&priv->ini); in brcm_usb_phy_resume()
658 clk_disable_unprepare(priv->usb_30_clk); in brcm_usb_phy_resume()
659 if (!priv->has_eohci) in brcm_usb_phy_resume()
660 clk_disable_unprepare(priv->usb_20_clk); in brcm_usb_phy_resume()
663 if (priv->has_xhci) in brcm_usb_phy_resume()
664 brcm_usb_uninit_xhci(&priv->ini); in brcm_usb_phy_resume()
665 if (priv->has_eohci) in brcm_usb_phy_resume()
666 brcm_usb_uninit_eohci(&priv->ini); in brcm_usb_phy_resume()
667 brcm_usb_uninit_common(&priv->ini); in brcm_usb_phy_resume()
668 clk_disable_unprepare(priv->usb_20_clk); in brcm_usb_phy_resume()
669 clk_disable_unprepare(priv->usb_30_clk); in brcm_usb_phy_resume()
671 priv->ini.wake_enabled = false; in brcm_usb_phy_resume()
686 .name = "brcmstb-usb-phy",
694 MODULE_ALIAS("platform:brcmstb-usb-phy");