diff options
Diffstat (limited to 'drivers/usb/dwc3/core.c')
-rw-r--r-- | drivers/usb/dwc3/core.c | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 455d89a1cd6d..326b302fc440 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -151,11 +151,24 @@ static void __dwc3_set_mode(struct work_struct *work) switch (dwc->desired_dr_role) { case DWC3_GCTL_PRTCAP_HOST: ret = dwc3_host_init(dwc); - if (ret) + if (ret) { dev_err(dwc->dev, "failed to initialize host\n"); + } else { + if (dwc->usb2_phy) + otg_set_vbus(dwc->usb2_phy->otg, true); + if (dwc->usb2_generic_phy) + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); + + } break; case DWC3_GCTL_PRTCAP_DEVICE: dwc3_event_buffers_setup(dwc); + + if (dwc->usb2_phy) + otg_set_vbus(dwc->usb2_phy->otg, false); + if (dwc->usb2_generic_phy) + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE); + ret = dwc3_gadget_init(dwc); if (ret) dev_err(dwc->dev, "failed to initialize peripheral\n"); @@ -721,6 +734,8 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GCTL, reg); } +static int dwc3_core_get_phy(struct dwc3 *dwc); + /** * dwc3_core_init - Low-level initialization of DWC3 Core * @dwc: Pointer to our controller context structure @@ -759,6 +774,10 @@ static int dwc3_core_init(struct dwc3 *dwc) if (ret) goto err0; + ret = dwc3_core_get_phy(dwc); + if (ret) + goto err0; + dwc3_core_setup_global_control(dwc); dwc3_core_num_eps(dwc); @@ -796,13 +815,19 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); } - /* - * Enable hardware control of sending remote wakeup in HS when - * the device is in the L1 state. - */ - if (dwc->revision >= DWC3_REVISION_290A) { + if (dwc->revision >= DWC3_REVISION_250A) { reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); - reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW; + + /* + * Enable hardware control of sending remote wakeup + * in HS when the device is in the L1 state. + */ + if (dwc->revision >= DWC3_REVISION_290A) + reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW; + + if (dwc->dis_tx_ipgap_linecheck_quirk) + reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS; + dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); } @@ -903,6 +928,12 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE); + + if (dwc->usb2_phy) + otg_set_vbus(dwc->usb2_phy->otg, false); + if (dwc->usb2_generic_phy) + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_DEVICE); + ret = dwc3_gadget_init(dwc); if (ret) { if (ret != -EPROBE_DEFER) @@ -912,6 +943,12 @@ static int dwc3_core_init_mode(struct dwc3 *dwc) break; case USB_DR_MODE_HOST: dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_HOST); + + if (dwc->usb2_phy) + otg_set_vbus(dwc->usb2_phy->otg, true); + if (dwc->usb2_generic_phy) + phy_set_mode(dwc->usb2_generic_phy, PHY_MODE_USB_HOST); + ret = dwc3_host_init(dwc); if (ret) { if (ret != -EPROBE_DEFER) @@ -1023,6 +1060,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) "snps,dis-u2-freeclk-exists-quirk"); dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev, "snps,dis-del-phy-power-chg-quirk"); + dwc->dis_tx_ipgap_linecheck_quirk = device_property_read_bool(dev, + "snps,dis-tx-ipgap-linecheck-quirk"); dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, "snps,tx_de_emphasis_quirk"); @@ -1148,10 +1187,6 @@ static int dwc3_probe(struct platform_device *pdev) platform_set_drvdata(pdev, dwc); dwc3_cache_hwparams(dwc); - ret = dwc3_core_get_phy(dwc); - if (ret) - goto err0; - spin_lock_init(&dwc->lock); pm_runtime_set_active(dev); |