FROMLIST: usb: dwc3: add disable u2mac linestate check quirk
authorWilliam Wu <william.wu@rock-chips.com>
Tue, 18 Apr 2017 05:17:39 +0000 (13:17 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Tue, 18 Apr 2017 09:55:20 +0000 (17:55 +0800)
This patch adds a quirk to disable USB 2.0 MAC linestate check
during HS transmit. Refer the dwc3 databook, we can use it for
some special platforms if the linestate not reflect the expected
line state(J) during transmission.

When use this quirk, the controller implements a fixed 40-bit
TxEndDelay after the packet is given on UTMI and ignores the
linestate during the transmit of a token (during token-to-token
and token-to-data IPGAP).

On some rockchip platforms (e.g. rk3399), it requires to disable
the u2mac linestate check to decrease the SSPLIT token to SETUP
token inter-packet delay from 566ns to 466ns, and fix the issue
that FS/LS devices not recognized if inserted through USB 3.0 HUB.

(am from https://patchwork.kernel.org/patch/9684951/)
Change-Id: I6298f59a5b89a76a90c628a58c932942ede2c3ef
Signed-off-by: William Wu <william.wu@rock-chips.com>
Documentation/devicetree/bindings/usb/dwc3.txt
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h

index 6c376308ac5a2fc6506ffb0371858d58bc08302d..23633568cfcc6cc219d718fcd2bbc301d4646fe1 100644 (file)
@@ -46,6 +46,8 @@ Optional properties:
                        a free-running PHY clock.
  - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
                        from P0 to P1/P2/P3 without delay.
+ - snps,tx-ipgap-linecheck-dis-quirk: when set, disable u2mac linestate check
+                       during HS transmit.
  - snps,xhci-slow-suspend-quirk: when set, need an extraordinary delay to wait
                        for xHC enter the Halted state (i.e. HCH in the USBSTS
                        register is '1').
index de2de4e685c4626f99ab4989e13a9c239f065631..acc6831eaf9570ce170ecc995c7adb08ff760ae5 100644 (file)
@@ -701,15 +701,19 @@ static int dwc3_core_init(struct dwc3 *dwc)
                break;
        }
 
+       reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+
        /*
         * 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_readl(dwc->regs, DWC3_GUCTL1);
+       if (dwc->revision >= DWC3_REVISION_290A)
                reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
-               dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
-       }
+
+       if (dwc->tx_ipgap_linecheck_dis_quirk)
+               reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
+
+       dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
 
        return 0;
 
@@ -991,6 +995,8 @@ static int dwc3_probe(struct platform_device *pdev)
                                "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->tx_ipgap_linecheck_dis_quirk = device_property_read_bool(dev,
+                               "snps,tx-ipgap-linecheck-dis-quirk");
        dwc->xhci_slow_suspend_quirk = device_property_read_bool(dev,
                                "snps,xhci-slow-suspend-quirk");
 
index 5f697c8f1ed1bb8a5a67f358888d48648d2f0e59..1e56b9b62b9a2399a7ccb16f1912d4d82d030fe1 100644 (file)
 #define DWC3_GCTL_DSBLCLKGTNG          (1 << 0)
 
 /* Global User Control 1 Register */
+#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS     BIT(28)
 #define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW  (1 << 24)
 
 /* Global USB2 PHY Configuration Register */
@@ -815,6 +816,8 @@ struct dwc3_scratchpad_array {
  *                     provide a free-running PHY clock.
  * @dis_del_phy_power_chg_quirk: set if we disable delay phy power
  *                     change quirk.
+ * @tx_ipgap_linecheck_dis_quirk: set if we disable u2mac linestate
+ *                     check during HS transmit.
  * @xhci_slow_suspend_quirk: set if need an extraordinary delay to wait
  *                     for xHC enter the Halted state after the Run/Stop
  *                     (R/S) bit is cleared to '0'.
@@ -966,6 +969,7 @@ struct dwc3 {
        unsigned                dis_rxdet_inp3_quirk:1;
        unsigned                dis_u2_freeclk_exists_quirk:1;
        unsigned                dis_del_phy_power_chg_quirk:1;
+       unsigned                tx_ipgap_linecheck_dis_quirk:1;
        unsigned                xhci_slow_suspend_quirk:1;
 
        unsigned                tx_de_emphasis_quirk:1;