usb: dwc3: core: Call dwc3_core_get_phy() before initializing phys
[linux-2.6-block.git] / drivers / usb / dwc3 / core.c
index 455d89a1cd6dbbb3e3f707bc42bada4a9569e5d7..03474d3575abe1381771a88eeb563a39649aa162 100644 (file)
@@ -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
@@ -751,6 +766,10 @@ static int dwc3_core_init(struct dwc3 *dwc)
                        dwc->maximum_speed = USB_SPEED_HIGH;
        }
 
+       ret = dwc3_core_get_phy(dwc);
+       if (ret)
+               goto err0;
+
        ret = dwc3_core_soft_reset(dwc);
        if (ret)
                goto err0;
@@ -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);