Lines Matching +full:assert +full:- +full:falling +full:- +full:edge

1 // SPDX-License-Identifier: GPL-2.0
4 * Inspired by dwc3-of-simple.c
122 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL, in dwc3_qcom_vbus_override_enable()
124 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL, in dwc3_qcom_vbus_override_enable()
127 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_SS_PHY_CTRL, in dwc3_qcom_vbus_override_enable()
129 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_HS_PHY_CTRL, in dwc3_qcom_vbus_override_enable()
141 qcom->mode = event ? USB_DR_MODE_PERIPHERAL : USB_DR_MODE_HOST; in dwc3_qcom_vbus_notifier()
153 qcom->mode = event ? USB_DR_MODE_HOST : USB_DR_MODE_PERIPHERAL; in dwc3_qcom_host_notifier()
160 struct device *dev = qcom->dev; in dwc3_qcom_register_extcon()
164 if (!of_property_read_bool(dev->of_node, "extcon")) in dwc3_qcom_register_extcon()
167 qcom->edev = extcon_get_edev_by_phandle(dev, 0); in dwc3_qcom_register_extcon()
168 if (IS_ERR(qcom->edev)) in dwc3_qcom_register_extcon()
169 return dev_err_probe(dev, PTR_ERR(qcom->edev), in dwc3_qcom_register_extcon()
172 qcom->vbus_nb.notifier_call = dwc3_qcom_vbus_notifier; in dwc3_qcom_register_extcon()
174 qcom->host_edev = extcon_get_edev_by_phandle(dev, 1); in dwc3_qcom_register_extcon()
175 if (IS_ERR(qcom->host_edev)) in dwc3_qcom_register_extcon()
176 qcom->host_edev = NULL; in dwc3_qcom_register_extcon()
178 ret = devm_extcon_register_notifier(dev, qcom->edev, EXTCON_USB, in dwc3_qcom_register_extcon()
179 &qcom->vbus_nb); in dwc3_qcom_register_extcon()
185 if (qcom->host_edev) in dwc3_qcom_register_extcon()
186 host_edev = qcom->host_edev; in dwc3_qcom_register_extcon()
188 host_edev = qcom->edev; in dwc3_qcom_register_extcon()
190 qcom->host_nb.notifier_call = dwc3_qcom_host_notifier; in dwc3_qcom_register_extcon()
192 &qcom->host_nb); in dwc3_qcom_register_extcon()
199 if (extcon_get_state(qcom->edev, EXTCON_USB) || in dwc3_qcom_register_extcon()
201 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, true, qcom->edev); in dwc3_qcom_register_extcon()
203 dwc3_qcom_vbus_notifier(&qcom->vbus_nb, false, qcom->edev); in dwc3_qcom_register_extcon()
212 ret = icc_enable(qcom->icc_path_ddr); in dwc3_qcom_interconnect_enable()
216 ret = icc_enable(qcom->icc_path_apps); in dwc3_qcom_interconnect_enable()
218 icc_disable(qcom->icc_path_ddr); in dwc3_qcom_interconnect_enable()
227 ret = icc_disable(qcom->icc_path_ddr); in dwc3_qcom_interconnect_disable()
231 ret = icc_disable(qcom->icc_path_apps); in dwc3_qcom_interconnect_disable()
233 icc_enable(qcom->icc_path_ddr); in dwc3_qcom_interconnect_disable()
239 * dwc3_qcom_interconnect_init() - Get interconnect path handles
247 struct device *dev = qcom->dev; in dwc3_qcom_interconnect_init()
250 qcom->icc_path_ddr = of_icc_get(dev, "usb-ddr"); in dwc3_qcom_interconnect_init()
251 if (IS_ERR(qcom->icc_path_ddr)) { in dwc3_qcom_interconnect_init()
252 return dev_err_probe(dev, PTR_ERR(qcom->icc_path_ddr), in dwc3_qcom_interconnect_init()
253 "failed to get usb-ddr path\n"); in dwc3_qcom_interconnect_init()
256 qcom->icc_path_apps = of_icc_get(dev, "apps-usb"); in dwc3_qcom_interconnect_init()
257 if (IS_ERR(qcom->icc_path_apps)) { in dwc3_qcom_interconnect_init()
258 ret = dev_err_probe(dev, PTR_ERR(qcom->icc_path_apps), in dwc3_qcom_interconnect_init()
259 "failed to get apps-usb path\n"); in dwc3_qcom_interconnect_init()
263 max_speed = usb_get_maximum_speed(&qcom->dwc3->dev); in dwc3_qcom_interconnect_init()
265 ret = icc_set_bw(qcom->icc_path_ddr, in dwc3_qcom_interconnect_init()
268 ret = icc_set_bw(qcom->icc_path_ddr, in dwc3_qcom_interconnect_init()
272 dev_err(dev, "failed to set bandwidth for usb-ddr path: %d\n", ret); in dwc3_qcom_interconnect_init()
276 ret = icc_set_bw(qcom->icc_path_apps, APPS_USB_AVG_BW, APPS_USB_PEAK_BW); in dwc3_qcom_interconnect_init()
278 dev_err(dev, "failed to set bandwidth for apps-usb path: %d\n", ret); in dwc3_qcom_interconnect_init()
285 icc_put(qcom->icc_path_apps); in dwc3_qcom_interconnect_init()
287 icc_put(qcom->icc_path_ddr); in dwc3_qcom_interconnect_init()
292 * dwc3_qcom_interconnect_exit() - Release interconnect path handles
299 icc_put(qcom->icc_path_ddr); in dwc3_qcom_interconnect_exit()
300 icc_put(qcom->icc_path_apps); in dwc3_qcom_interconnect_exit()
311 dwc = platform_get_drvdata(qcom->dwc3); in dwc3_qcom_is_host()
317 return dwc->xhci; in dwc3_qcom_is_host()
322 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); in dwc3_qcom_read_usb2_speed()
329 hcd = platform_get_drvdata(dwc->xhci); in dwc3_qcom_read_usb2_speed()
332 udev = usb_hub_find_child(hcd->self.root_hub, port_index + 1); in dwc3_qcom_read_usb2_speed()
339 return udev->speed; in dwc3_qcom_read_usb2_speed()
365 dwc3_qcom_disable_wakeup_irq(port->qusb2_phy_irq); in dwc3_qcom_disable_port_interrupts()
367 if (port->usb2_speed == USB_SPEED_LOW) { in dwc3_qcom_disable_port_interrupts()
368 dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq); in dwc3_qcom_disable_port_interrupts()
369 } else if ((port->usb2_speed == USB_SPEED_HIGH) || in dwc3_qcom_disable_port_interrupts()
370 (port->usb2_speed == USB_SPEED_FULL)) { in dwc3_qcom_disable_port_interrupts()
371 dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq); in dwc3_qcom_disable_port_interrupts()
373 dwc3_qcom_disable_wakeup_irq(port->dp_hs_phy_irq); in dwc3_qcom_disable_port_interrupts()
374 dwc3_qcom_disable_wakeup_irq(port->dm_hs_phy_irq); in dwc3_qcom_disable_port_interrupts()
377 dwc3_qcom_disable_wakeup_irq(port->ss_phy_irq); in dwc3_qcom_disable_port_interrupts()
382 dwc3_qcom_enable_wakeup_irq(port->qusb2_phy_irq, 0); in dwc3_qcom_enable_port_interrupts()
387 * as falling edge to detect both disconnect and remote wakeup scenarios. When in dwc3_qcom_enable_port_interrupts()
388 * LS device is connected, configure DM line as falling edge to detect both in dwc3_qcom_enable_port_interrupts()
390 * DP and DM lines as rising edge to detect HS/HS/LS device connect scenario. in dwc3_qcom_enable_port_interrupts()
393 if (port->usb2_speed == USB_SPEED_LOW) { in dwc3_qcom_enable_port_interrupts()
394 dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq, in dwc3_qcom_enable_port_interrupts()
396 } else if ((port->usb2_speed == USB_SPEED_HIGH) || in dwc3_qcom_enable_port_interrupts()
397 (port->usb2_speed == USB_SPEED_FULL)) { in dwc3_qcom_enable_port_interrupts()
398 dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq, in dwc3_qcom_enable_port_interrupts()
401 dwc3_qcom_enable_wakeup_irq(port->dp_hs_phy_irq, in dwc3_qcom_enable_port_interrupts()
403 dwc3_qcom_enable_wakeup_irq(port->dm_hs_phy_irq, in dwc3_qcom_enable_port_interrupts()
407 dwc3_qcom_enable_wakeup_irq(port->ss_phy_irq, 0); in dwc3_qcom_enable_port_interrupts()
414 for (i = 0; i < qcom->num_ports; i++) in dwc3_qcom_disable_interrupts()
415 dwc3_qcom_disable_port_interrupts(&qcom->ports[i]); in dwc3_qcom_disable_interrupts()
422 for (i = 0; i < qcom->num_ports; i++) in dwc3_qcom_enable_interrupts()
423 dwc3_qcom_enable_port_interrupts(&qcom->ports[i]); in dwc3_qcom_enable_interrupts()
431 if (qcom->is_suspended) in dwc3_qcom_suspend()
434 for (i = 0; i < qcom->num_ports; i++) { in dwc3_qcom_suspend()
435 val = readl(qcom->qscratch_base + pwr_evnt_irq_stat_reg[i]); in dwc3_qcom_suspend()
437 dev_err(qcom->dev, "port-%d HS-PHY not in L2\n", i + 1); in dwc3_qcom_suspend()
440 for (i = qcom->num_clocks - 1; i >= 0; i--) in dwc3_qcom_suspend()
441 clk_disable_unprepare(qcom->clks[i]); in dwc3_qcom_suspend()
445 dev_warn(qcom->dev, "failed to disable interconnect: %d\n", ret); in dwc3_qcom_suspend()
452 for (i = 0; i < qcom->num_ports; i++) in dwc3_qcom_suspend()
453 qcom->ports[i].usb2_speed = dwc3_qcom_read_usb2_speed(qcom, i); in dwc3_qcom_suspend()
457 qcom->is_suspended = true; in dwc3_qcom_suspend()
467 if (!qcom->is_suspended) in dwc3_qcom_resume()
473 for (i = 0; i < qcom->num_clocks; i++) { in dwc3_qcom_resume()
474 ret = clk_prepare_enable(qcom->clks[i]); in dwc3_qcom_resume()
476 while (--i >= 0) in dwc3_qcom_resume()
477 clk_disable_unprepare(qcom->clks[i]); in dwc3_qcom_resume()
484 dev_warn(qcom->dev, "failed to enable interconnect: %d\n", ret); in dwc3_qcom_resume()
487 for (i = 0; i < qcom->num_ports; i++) { in dwc3_qcom_resume()
488 dwc3_qcom_setbits(qcom->qscratch_base, in dwc3_qcom_resume()
493 qcom->is_suspended = false; in dwc3_qcom_resume()
501 struct dwc3 *dwc = platform_get_drvdata(qcom->dwc3); in qcom_dwc3_resume_irq()
504 if (qcom->pm_suspended) in qcom_dwc3_resume_irq()
512 pm_runtime_resume(&dwc->xhci->dev); in qcom_dwc3_resume_irq()
520 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, in dwc3_qcom_select_utmi_clk()
525 dwc3_qcom_setbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, in dwc3_qcom_select_utmi_clk()
530 dwc3_qcom_clrbits(qcom->qscratch_base, QSCRATCH_GENERAL_CFG, in dwc3_qcom_select_utmi_clk()
540 ret = devm_request_threaded_irq(qcom->dev, irq, NULL, in dwc3_qcom_request_irq()
545 dev_err(qcom->dev, "failed to request irq %s: %d\n", name, ret); in dwc3_qcom_request_irq()
558 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "dp_hs_phy_%d", port_index + 1); in dwc3_qcom_setup_port_irq()
560 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "dp_hs_phy_irq"); in dwc3_qcom_setup_port_irq()
562 return -ENOMEM; in dwc3_qcom_setup_port_irq()
569 qcom->ports[port_index].dp_hs_phy_irq = irq; in dwc3_qcom_setup_port_irq()
573 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "dm_hs_phy_%d", port_index + 1); in dwc3_qcom_setup_port_irq()
575 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "dm_hs_phy_irq"); in dwc3_qcom_setup_port_irq()
577 return -ENOMEM; in dwc3_qcom_setup_port_irq()
584 qcom->ports[port_index].dm_hs_phy_irq = irq; in dwc3_qcom_setup_port_irq()
588 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ss_phy_%d", port_index + 1); in dwc3_qcom_setup_port_irq()
590 irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ss_phy_irq"); in dwc3_qcom_setup_port_irq()
592 return -ENOMEM; in dwc3_qcom_setup_port_irq()
599 qcom->ports[port_index].ss_phy_irq = irq; in dwc3_qcom_setup_port_irq()
610 qcom->ports[port_index].qusb2_phy_irq = irq; in dwc3_qcom_setup_port_irq()
631 return port_num - 1; in dwc3_qcom_find_num_ports()
644 qcom->num_ports = dwc3_qcom_find_num_ports(pdev); in dwc3_qcom_setup_irq()
645 is_multiport = (qcom->num_ports > 1); in dwc3_qcom_setup_irq()
647 for (i = 0; i < qcom->num_ports; i++) { in dwc3_qcom_setup_irq()
658 struct device *dev = qcom->dev; in dwc3_qcom_clk_init()
659 struct device_node *np = dev->of_node; in dwc3_qcom_clk_init()
668 qcom->num_clocks = count; in dwc3_qcom_clk_init()
670 qcom->clks = devm_kcalloc(dev, qcom->num_clocks, in dwc3_qcom_clk_init()
672 if (!qcom->clks) in dwc3_qcom_clk_init()
673 return -ENOMEM; in dwc3_qcom_clk_init()
675 for (i = 0; i < qcom->num_clocks; i++) { in dwc3_qcom_clk_init()
681 while (--i >= 0) in dwc3_qcom_clk_init()
682 clk_put(qcom->clks[i]); in dwc3_qcom_clk_init()
688 while (--i >= 0) { in dwc3_qcom_clk_init()
689 clk_disable_unprepare(qcom->clks[i]); in dwc3_qcom_clk_init()
690 clk_put(qcom->clks[i]); in dwc3_qcom_clk_init()
697 qcom->clks[i] = clk; in dwc3_qcom_clk_init()
706 struct device_node *np = pdev->dev.of_node; in dwc3_qcom_of_register_core()
707 struct device *dev = &pdev->dev; in dwc3_qcom_of_register_core()
714 return -ENODEV; in dwc3_qcom_of_register_core()
719 dev_err(dev, "failed to register dwc3 core - %d\n", ret); in dwc3_qcom_of_register_core()
723 qcom->dwc3 = of_find_device_by_node(dwc3_np); in dwc3_qcom_of_register_core()
724 if (!qcom->dwc3) { in dwc3_qcom_of_register_core()
725 ret = -ENODEV; in dwc3_qcom_of_register_core()
735 struct device_node *np = pdev->dev.of_node; in dwc3_qcom_probe()
736 struct device *dev = &pdev->dev; in dwc3_qcom_probe()
742 qcom = devm_kzalloc(&pdev->dev, sizeof(*qcom), GFP_KERNEL); in dwc3_qcom_probe()
744 return -ENOMEM; in dwc3_qcom_probe()
747 qcom->dev = &pdev->dev; in dwc3_qcom_probe()
749 qcom->resets = devm_reset_control_array_get_optional_exclusive(dev); in dwc3_qcom_probe()
750 if (IS_ERR(qcom->resets)) { in dwc3_qcom_probe()
751 return dev_err_probe(&pdev->dev, PTR_ERR(qcom->resets), in dwc3_qcom_probe()
755 ret = reset_control_assert(qcom->resets); in dwc3_qcom_probe()
757 dev_err(&pdev->dev, "failed to assert resets, err=%d\n", ret); in dwc3_qcom_probe()
763 ret = reset_control_deassert(qcom->resets); in dwc3_qcom_probe()
765 dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret); in dwc3_qcom_probe()
775 qcom->qscratch_base = devm_platform_ioremap_resource(pdev, 0); in dwc3_qcom_probe()
776 if (IS_ERR(qcom->qscratch_base)) { in dwc3_qcom_probe()
777 ret = PTR_ERR(qcom->qscratch_base); in dwc3_qcom_probe()
792 "qcom,select-utmi-as-pipe-clk"); in dwc3_qcom_probe()
806 qcom->mode = usb_get_dr_mode(&qcom->dwc3->dev); in dwc3_qcom_probe()
809 if (qcom->mode != USB_DR_MODE_HOST) in dwc3_qcom_probe()
817 wakeup_source = of_property_read_bool(dev->of_node, "wakeup-source"); in dwc3_qcom_probe()
818 device_init_wakeup(&pdev->dev, wakeup_source); in dwc3_qcom_probe()
819 device_init_wakeup(&qcom->dwc3->dev, wakeup_source); in dwc3_qcom_probe()
821 qcom->is_suspended = false; in dwc3_qcom_probe()
831 of_platform_depopulate(&pdev->dev); in dwc3_qcom_probe()
832 platform_device_put(qcom->dwc3); in dwc3_qcom_probe()
834 for (i = qcom->num_clocks - 1; i >= 0; i--) { in dwc3_qcom_probe()
835 clk_disable_unprepare(qcom->clks[i]); in dwc3_qcom_probe()
836 clk_put(qcom->clks[i]); in dwc3_qcom_probe()
839 reset_control_assert(qcom->resets); in dwc3_qcom_probe()
847 struct device *dev = &pdev->dev; in dwc3_qcom_remove()
850 of_platform_depopulate(&pdev->dev); in dwc3_qcom_remove()
851 platform_device_put(qcom->dwc3); in dwc3_qcom_remove()
853 for (i = qcom->num_clocks - 1; i >= 0; i--) { in dwc3_qcom_remove()
854 clk_disable_unprepare(qcom->clks[i]); in dwc3_qcom_remove()
855 clk_put(qcom->clks[i]); in dwc3_qcom_remove()
857 qcom->num_clocks = 0; in dwc3_qcom_remove()
860 reset_control_assert(qcom->resets); in dwc3_qcom_remove()
876 qcom->pm_suspended = true; in dwc3_qcom_pm_suspend()
891 qcom->pm_suspended = false; in dwc3_qcom_pm_resume()
926 .name = "dwc3-qcom",