usb: dwc3: add dis_u3_autosuspend_quirk
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc3 / core.c
index ae93fa0861fde31ea05f65fbc459cef72a958f36..db5f8e056d293c30cf73f5b20f3885e1b8ff7953 100644 (file)
@@ -448,6 +448,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
        if (dwc->dis_u3_susphy_quirk)
                reg &= ~DWC3_GUSB3PIPECTL_SUSPHY;
 
+       if (dwc->dis_del_phy_power_chg_quirk)
+               reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE;
+
        dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
        reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
@@ -485,6 +488,23 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
                break;
        }
 
+       switch (dwc->hsphy_mode) {
+       case USBPHY_INTERFACE_MODE_UTMI:
+               reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+                      DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+               reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
+                      DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
+               break;
+       case USBPHY_INTERFACE_MODE_UTMIW:
+               reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+                      DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+               reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
+                      DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
+               break;
+       default:
+               break;
+       }
+
        /*
         * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
         * '0' during coreConsultant configuration. So default value will
@@ -500,6 +520,9 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
        if (dwc->dis_enblslpm_quirk)
                reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
 
+       if (dwc->dis_u2_freeclk_exists_quirk)
+               reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
        return 0;
@@ -666,6 +689,18 @@ static int dwc3_core_init(struct dwc3 *dwc)
                goto err4;
        }
 
+       switch (dwc->dr_mode) {
+       case USB_DR_MODE_PERIPHERAL:
+               dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
+               break;
+       case USB_DR_MODE_HOST:
+               dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
+               break;
+       default:
+               dev_dbg(dwc->dev, "Unsupported mode %d\n", dwc->dr_mode);
+               break;
+       }
+
        return 0;
 
 err4:
@@ -903,6 +938,7 @@ static int dwc3_probe(struct platform_device *pdev)
 
        dwc->maximum_speed = usb_get_maximum_speed(dev);
        dwc->dr_mode = usb_get_dr_mode(dev);
+       dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
 
        dwc->has_lpm_erratum = device_property_read_bool(dev,
                                "snps,has-lpm-erratum");
@@ -931,6 +967,8 @@ static int dwc3_probe(struct platform_device *pdev)
                                "snps,lfps_filter_quirk");
        dwc->rx_detect_poll_quirk = device_property_read_bool(dev,
                                "snps,rx_detect_poll_quirk");
+       dwc->dis_u3_autosuspend_quirk = device_property_read_bool(dev,
+                               "snps,dis-u3-autosuspend-quirk");
        dwc->dis_u3_susphy_quirk = device_property_read_bool(dev,
                                "snps,dis_u3_susphy_quirk");
        dwc->dis_u2_susphy_quirk = device_property_read_bool(dev,
@@ -939,6 +977,12 @@ static int dwc3_probe(struct platform_device *pdev)
                                "snps,dis_enblslpm_quirk");
        dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev,
                                "snps,dis_rxdet_inp3_quirk");
+       dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev,
+                               "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->xhci_slow_suspend_quirk = device_property_read_bool(dev,
+                               "snps,xhci-slow-suspend-quirk");
 
        dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
                                "snps,tx_de_emphasis_quirk");
@@ -1217,6 +1261,9 @@ static int dwc3_suspend(struct device *dev)
        struct dwc3     *dwc = dev_get_drvdata(dev);
        int             ret;
 
+       if (pm_runtime_suspended(dwc->dev))
+               return 0;
+
        ret = dwc3_suspend_common(dwc);
        if (ret)
                return ret;
@@ -1231,6 +1278,9 @@ static int dwc3_resume(struct device *dev)
        struct dwc3     *dwc = dev_get_drvdata(dev);
        int             ret;
 
+       if (pm_runtime_suspended(dwc->dev))
+               return 0;
+
        pinctrl_pm_select_default_state(dev);
 
        ret = dwc3_resume_common(dwc);