Lines Matching +full:disable +full:- +full:hibernation +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0
3 * drd.c - DesignWare USB3 DRD Controller Dual-role support
5 * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com
21 u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN); in dwc3_otg_disable_events()
24 dwc3_writel(dwc->regs, DWC3_OEVTEN, reg); in dwc3_otg_disable_events()
29 u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN); in dwc3_otg_enable_events()
32 dwc3_writel(dwc->regs, DWC3_OEVTEN, reg); in dwc3_otg_enable_events()
37 u32 reg = dwc3_readl(dwc->regs, DWC3_OEVT); in dwc3_otg_clear_events()
39 dwc3_writel(dwc->regs, DWC3_OEVTEN, reg); in dwc3_otg_clear_events()
56 spin_lock(&dwc->lock); in dwc3_otg_thread_irq()
57 if (dwc->otg_restart_host) { in dwc3_otg_thread_irq()
59 dwc->otg_restart_host = false; in dwc3_otg_thread_irq()
62 spin_unlock(&dwc->lock); in dwc3_otg_thread_irq()
75 reg = dwc3_readl(dwc->regs, DWC3_OEVT); in dwc3_otg_irq()
77 /* ignore non OTG events, we can't disable them in OEVTEN */ in dwc3_otg_irq()
79 dwc3_writel(dwc->regs, DWC3_OEVT, reg); in dwc3_otg_irq()
83 if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST && in dwc3_otg_irq()
85 dwc->otg_restart_host = true; in dwc3_otg_irq()
86 dwc3_writel(dwc->regs, DWC3_OEVT, reg); in dwc3_otg_irq()
103 reg = dwc3_readl(dwc->regs, DWC3_OCFG); in dwc3_otgregs_init()
105 dwc3_writel(dwc->regs, DWC3_OCFG, reg); in dwc3_otgregs_init()
107 /* Disable hibernation for simplicity */ in dwc3_otgregs_init()
108 reg = dwc3_readl(dwc->regs, DWC3_GCTL); in dwc3_otgregs_init()
110 dwc3_writel(dwc->regs, DWC3_GCTL, reg); in dwc3_otgregs_init()
114 * Figure 11-4 OTG Driver Overall Programming Flow in dwc3_otgregs_init()
117 reg = dwc3_readl(dwc->regs, DWC3_OCFG); in dwc3_otgregs_init()
119 dwc3_writel(dwc->regs, DWC3_OCFG, reg); in dwc3_otgregs_init()
130 reg = dwc3_readl(dwc->regs, DWC3_OCTL); in dwc3_otgregs_init()
134 dwc3_writel(dwc->regs, DWC3_OCTL, reg); in dwc3_otgregs_init()
139 struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); in dwc3_otg_get_irq()
146 if (irq == -EPROBE_DEFER) in dwc3_otg_get_irq()
153 if (irq == -EPROBE_DEFER) in dwc3_otg_get_irq()
161 irq = -EINVAL; in dwc3_otg_get_irq()
172 * As per Figure 11-4 OTG Driver Overall Programming Flow, in dwc3_otg_init()
178 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); in dwc3_otg_init()
180 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); in dwc3_otg_init()
188 /* disable all OTG IRQs */ in dwc3_otg_exit()
199 /* As per Figure 11-10 A-Device Flow Diagram */ in dwc3_otg_host_init()
206 reg = dwc3_readl(dwc->regs, DWC3_OCTL); in dwc3_otg_host_init()
209 dwc3_writel(dwc->regs, DWC3_OCTL, reg); in dwc3_otg_host_init()
214 reg = dwc3_readl(dwc->regs, DWC3_OCFG); in dwc3_otg_host_init()
216 dwc3_writel(dwc->regs, DWC3_OCFG, reg); in dwc3_otg_host_init()
220 * We don't want SRP/HNP for simple dual-role so leave in dwc3_otg_host_init()
227 * We don't want HNP/role-swap so leave these disabled. in dwc3_otg_host_init()
231 if (!dwc->dis_u2_susphy_quirk) { in dwc3_otg_host_init()
232 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); in dwc3_otg_host_init()
234 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); in dwc3_otg_host_init()
238 reg = dwc3_readl(dwc->regs, DWC3_OCTL); in dwc3_otg_host_init()
240 dwc3_writel(dwc->regs, DWC3_OCTL, reg); in dwc3_otg_host_init()
249 * Exit from A-device flow as per in dwc3_otg_host_exit()
250 * Figure 11-4 OTG Driver Overall Programming Flow in dwc3_otg_host_exit()
257 * But we don't disable any OTG events in dwc3_otg_host_exit()
261 reg = dwc3_readl(dwc->regs, DWC3_OCTL); in dwc3_otg_host_exit()
263 dwc3_writel(dwc->regs, DWC3_OCTL, reg); in dwc3_otg_host_exit()
271 /* As per Figure 11-20 B-Device Flow Diagram */ in dwc3_otg_device_init()
275 * but we keep them 0 for simple dual-role operation. in dwc3_otg_device_init()
277 reg = dwc3_readl(dwc->regs, DWC3_OCFG); in dwc3_otg_device_init()
280 dwc3_writel(dwc->regs, DWC3_OCFG, reg); in dwc3_otg_device_init()
286 reg = dwc3_readl(dwc->regs, DWC3_OCTL); in dwc3_otg_device_init()
290 dwc3_writel(dwc->regs, DWC3_OCTL, reg); in dwc3_otg_device_init()
294 if (!dwc->dis_u2_susphy_quirk) { in dwc3_otg_device_init()
295 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); in dwc3_otg_device_init()
297 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); in dwc3_otg_device_init()
308 * Exit from B-device flow as per in dwc3_otg_device_exit()
309 * Figure 11-4 OTG Driver Overall Programming Flow in dwc3_otg_device_exit()
322 reg = dwc3_readl(dwc->regs, DWC3_OCTL); in dwc3_otg_device_exit()
325 dwc3_writel(dwc->regs, DWC3_OCTL, reg); in dwc3_otg_device_exit()
335 if (dwc->dr_mode != USB_DR_MODE_OTG) in dwc3_otg_update()
339 if (dwc->current_dr_role != DWC3_GCTL_PRTCAP_OTG) in dwc3_otg_update()
343 reg = dwc3_readl(dwc->regs, DWC3_OSTS); in dwc3_otg_update()
346 dwc->desired_otg_role = id ? DWC3_OTG_ROLE_DEVICE : in dwc3_otg_update()
350 if (dwc->desired_otg_role == dwc->current_otg_role) in dwc3_otg_update()
353 switch (dwc->current_otg_role) { in dwc3_otg_update()
356 spin_lock_irqsave(&dwc->lock, flags); in dwc3_otg_update()
358 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_otg_update()
362 spin_lock_irqsave(&dwc->lock, flags); in dwc3_otg_update()
365 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_otg_update()
371 spin_lock_irqsave(&dwc->lock, flags); in dwc3_otg_update()
373 dwc->current_otg_role = dwc->desired_otg_role; in dwc3_otg_update()
375 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_otg_update()
377 switch (dwc->desired_otg_role) { in dwc3_otg_update()
379 spin_lock_irqsave(&dwc->lock, flags); in dwc3_otg_update()
382 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_otg_update()
385 dev_err(dwc->dev, "failed to initialize host\n"); in dwc3_otg_update()
387 if (dwc->usb2_phy) in dwc3_otg_update()
388 otg_set_vbus(dwc->usb2_phy->otg, true); in dwc3_otg_update()
389 if (dwc->usb2_generic_phy) in dwc3_otg_update()
390 phy_set_mode(dwc->usb2_generic_phy, in dwc3_otg_update()
395 spin_lock_irqsave(&dwc->lock, flags); in dwc3_otg_update()
399 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_otg_update()
401 if (dwc->usb2_phy) in dwc3_otg_update()
402 otg_set_vbus(dwc->usb2_phy->otg, false); in dwc3_otg_update()
403 if (dwc->usb2_generic_phy) in dwc3_otg_update()
404 phy_set_mode(dwc->usb2_generic_phy, in dwc3_otg_update()
408 dev_err(dwc->dev, "failed to initialize peripheral\n"); in dwc3_otg_update()
419 if (dwc->edev) { in dwc3_drd_update()
420 id = extcon_get_state(dwc->edev, EXTCON_USB_HOST); in dwc3_drd_update()
447 u32 mode; in dwc3_usb_role_switch_set() local
451 mode = DWC3_GCTL_PRTCAP_HOST; in dwc3_usb_role_switch_set()
454 mode = DWC3_GCTL_PRTCAP_DEVICE; in dwc3_usb_role_switch_set()
457 if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) in dwc3_usb_role_switch_set()
458 mode = DWC3_GCTL_PRTCAP_HOST; in dwc3_usb_role_switch_set()
460 mode = DWC3_GCTL_PRTCAP_DEVICE; in dwc3_usb_role_switch_set()
464 dwc3_set_mode(dwc, mode); in dwc3_usb_role_switch_set()
474 spin_lock_irqsave(&dwc->lock, flags); in dwc3_usb_role_switch_get()
475 switch (dwc->current_dr_role) { in dwc3_usb_role_switch_get()
483 role = dwc->current_otg_role; in dwc3_usb_role_switch_get()
486 if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) in dwc3_usb_role_switch_get()
492 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_usb_role_switch_get()
499 u32 mode; in dwc3_setup_role_switch() local
501 dwc->role_switch_default_mode = usb_get_role_switch_default_mode(dwc->dev); in dwc3_setup_role_switch()
502 if (dwc->role_switch_default_mode == USB_DR_MODE_HOST) { in dwc3_setup_role_switch()
503 mode = DWC3_GCTL_PRTCAP_HOST; in dwc3_setup_role_switch()
505 dwc->role_switch_default_mode = USB_DR_MODE_PERIPHERAL; in dwc3_setup_role_switch()
506 mode = DWC3_GCTL_PRTCAP_DEVICE; in dwc3_setup_role_switch()
508 dwc3_set_mode(dwc, mode); in dwc3_setup_role_switch()
510 dwc3_role_switch.fwnode = dev_fwnode(dwc->dev); in dwc3_setup_role_switch()
514 dwc->role_sw = usb_role_switch_register(dwc->dev, &dwc3_role_switch); in dwc3_setup_role_switch()
515 if (IS_ERR(dwc->role_sw)) in dwc3_setup_role_switch()
516 return PTR_ERR(dwc->role_sw); in dwc3_setup_role_switch()
518 if (dwc->dev->of_node) { in dwc3_setup_role_switch()
520 int ret = devm_of_platform_populate(dwc->dev); in dwc3_setup_role_switch()
523 usb_role_switch_unregister(dwc->role_sw); in dwc3_setup_role_switch()
524 dwc->role_sw = NULL; in dwc3_setup_role_switch()
525 dev_err(dwc->dev, "DWC3 platform devices creation failed: %i\n", ret); in dwc3_setup_role_switch()
542 device_property_read_bool(dwc->dev, "usb-role-switch")) in dwc3_drd_init()
545 if (dwc->edev) { in dwc3_drd_init()
546 dwc->edev_nb.notifier_call = dwc3_drd_notifier; in dwc3_drd_init()
547 ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST, in dwc3_drd_init()
548 &dwc->edev_nb); in dwc3_drd_init()
550 dev_err(dwc->dev, "couldn't register cable notifier\n"); in dwc3_drd_init()
563 dwc->otg_irq = irq; in dwc3_drd_init()
565 /* disable all OTG IRQs */ in dwc3_drd_init()
570 ret = request_threaded_irq(dwc->otg_irq, dwc3_otg_irq, in dwc3_drd_init()
572 IRQF_SHARED, "dwc3-otg", dwc); in dwc3_drd_init()
574 dev_err(dwc->dev, "failed to request irq #%d --> %d\n", in dwc3_drd_init()
575 dwc->otg_irq, ret); in dwc3_drd_init()
576 ret = -ENODEV; in dwc3_drd_init()
591 if (dwc->role_sw) in dwc3_drd_exit()
592 usb_role_switch_unregister(dwc->role_sw); in dwc3_drd_exit()
594 if (dwc->edev) in dwc3_drd_exit()
595 extcon_unregister_notifier(dwc->edev, EXTCON_USB_HOST, in dwc3_drd_exit()
596 &dwc->edev_nb); in dwc3_drd_exit()
598 cancel_work_sync(&dwc->drd_work); in dwc3_drd_exit()
601 switch (dwc->current_dr_role) { in dwc3_drd_exit()
611 spin_lock_irqsave(&dwc->lock, flags); in dwc3_drd_exit()
612 dwc->desired_otg_role = DWC3_OTG_ROLE_IDLE; in dwc3_drd_exit()
613 spin_unlock_irqrestore(&dwc->lock, flags); in dwc3_drd_exit()
620 if (dwc->otg_irq) in dwc3_drd_exit()
621 free_irq(dwc->otg_irq, dwc); in dwc3_drd_exit()