aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch
diff options
context:
space:
mode:
authorPavel Kubelun <be.dissent@gmail.com>2016-11-12 14:35:56 +0300
committerJohn Crispin <john@phrozen.org>2016-11-21 09:58:42 +0100
commit70434c3f948749690de24effbfd98f7a64e0991f (patch)
tree31de7f236a55c7649afcf2b7fea8d75ec4a5f3ed /target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch
parent6e65576f2d808513148bc8b6e399e62805c3fe03 (diff)
downloadupstream-70434c3f948749690de24effbfd98f7a64e0991f.tar.gz
upstream-70434c3f948749690de24effbfd98f7a64e0991f.tar.bz2
upstream-70434c3f948749690de24effbfd98f7a64e0991f.zip
ipq806x: switch to upstream usb driver and backport fixes
Also removing fifo-resize property drom DT as it has been removed from the driver. Signed-off-by: Pavel Kubelun <be.dissent@gmail.com>
Diffstat (limited to 'target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch')
-rw-r--r--target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch101
1 files changed, 101 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch b/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch
new file mode 100644
index 0000000000..197dd057d2
--- /dev/null
+++ b/target/linux/ipq806x/patches-4.4/096-06-usb-dwc3-core-improve-reset-sequence.patch
@@ -0,0 +1,101 @@
+From f59dcab176293b646e1358144c93c58c3cda2813 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <felipe.balbi@linux.intel.com>
+Date: Fri, 11 Mar 2016 10:51:52 +0200
+Subject: usb: dwc3: core: improve reset sequence
+
+According to Synopsys Databook, we shouldn't be
+relying on GCTL.CORESOFTRESET bit as that's only for
+debugging purposes. Instead, let's use DCTL.CSFTRST
+if we're OTG or PERIPHERAL mode.
+
+Host side block will be reset by XHCI driver if
+necessary. Note that this reduces amount of time
+spent on dwc3_probe() by a long margin.
+
+We're still gonna wait for reset to finish for a
+long time (default to 1ms max), but tests show that
+the reset polling loop executed at most 19 times
+(modprobe dwc3 && modprobe -r dwc3 executed 1000
+times in a row).
+
+Suggested-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+---
+ drivers/usb/dwc3/core.c | 48 ++++++++++++++++++------------------------------
+ 1 file changed, 18 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 17fd814..fa20f5a9 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
+ static int dwc3_core_soft_reset(struct dwc3 *dwc)
+ {
+ u32 reg;
++ int retries = 1000;
+ int ret;
+
+- /* Before Resetting PHY, put Core in Reset */
+- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+- reg |= DWC3_GCTL_CORESOFTRESET;
+- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+-
+- /* Assert USB3 PHY reset */
+- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+- reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
+- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+-
+- /* Assert USB2 PHY reset */
+- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+- reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
+- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+-
+ usb_phy_init(dwc->usb2_phy);
+ usb_phy_init(dwc->usb3_phy);
+ ret = phy_init(dwc->usb2_generic_phy);
+@@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
+ phy_exit(dwc->usb2_generic_phy);
+ return ret;
+ }
+- mdelay(100);
+
+- /* Clear USB3 PHY reset */
+- reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
+- reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
+- dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
++ /*
++ * We're resetting only the device side because, if we're in host mode,
++ * XHCI driver will reset the host block. If dwc3 was configured for
++ * host-only mode, then we can return early.
++ */
++ if (dwc->dr_mode == USB_DR_MODE_HOST)
++ return 0;
+
+- /* Clear USB2 PHY reset */
+- reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+- reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
+- dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
++ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
++ reg |= DWC3_DCTL_CSFTRST;
++ dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+
+- mdelay(100);
++ do {
++ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
++ if (!(reg & DWC3_DCTL_CSFTRST))
++ return 0;
+
+- /* After PHYs are stable we can take Core out of reset state */
+- reg = dwc3_readl(dwc->regs, DWC3_GCTL);
+- reg &= ~DWC3_GCTL_CORESOFTRESET;
+- dwc3_writel(dwc->regs, DWC3_GCTL, reg);
++ udelay(1);
++ } while (--retries);
+
+- return 0;
++ return -ETIMEDOUT;
+ }
+
+ /**
+--
+cgit v0.12