kernel: update kernel 4.4 to version 4.4.110
[librecmc/librecmc.git] / target / linux / ipq806x / patches-4.4 / 096-06-usb-dwc3-core-improve-reset-sequence.patch
1 From f59dcab176293b646e1358144c93c58c3cda2813 Mon Sep 17 00:00:00 2001
2 From: Felipe Balbi <felipe.balbi@linux.intel.com>
3 Date: Fri, 11 Mar 2016 10:51:52 +0200
4 Subject: usb: dwc3: core: improve reset sequence
5
6 According to Synopsys Databook, we shouldn't be
7 relying on GCTL.CORESOFTRESET bit as that's only for
8 debugging purposes. Instead, let's use DCTL.CSFTRST
9 if we're OTG or PERIPHERAL mode.
10
11 Host side block will be reset by XHCI driver if
12 necessary. Note that this reduces amount of time
13 spent on dwc3_probe() by a long margin.
14
15 We're still gonna wait for reset to finish for a
16 long time (default to 1ms max), but tests show that
17 the reset polling loop executed at most 19 times
18 (modprobe dwc3 && modprobe -r dwc3 executed 1000
19 times in a row).
20
21 Suggested-by: Mian Yousaf Kaukab <yousaf.kaukab@intel.com>
22 Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
23 ---
24  drivers/usb/dwc3/core.c | 48 ++++++++++++++++++------------------------------
25  1 file changed, 18 insertions(+), 30 deletions(-)
26
27 --- a/drivers/usb/dwc3/core.c
28 +++ b/drivers/usb/dwc3/core.c
29 @@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32
30  static int dwc3_core_soft_reset(struct dwc3 *dwc)
31  {
32         u32             reg;
33 +       int             retries = 1000;
34         int             ret;
35  
36 -       /* Before Resetting PHY, put Core in Reset */
37 -       reg = dwc3_readl(dwc->regs, DWC3_GCTL);
38 -       reg |= DWC3_GCTL_CORESOFTRESET;
39 -       dwc3_writel(dwc->regs, DWC3_GCTL, reg);
40 -
41 -       /* Assert USB3 PHY reset */
42 -       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
43 -       reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
44 -       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
45 -
46 -       /* Assert USB2 PHY reset */
47 -       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
48 -       reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
49 -       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
50 -
51         usb_phy_init(dwc->usb2_phy);
52         usb_phy_init(dwc->usb3_phy);
53         ret = phy_init(dwc->usb2_generic_phy);
54 @@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct d
55                 phy_exit(dwc->usb2_generic_phy);
56                 return ret;
57         }
58 -       mdelay(100);
59  
60 -       /* Clear USB3 PHY reset */
61 -       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
62 -       reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
63 -       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
64 -
65 -       /* Clear USB2 PHY reset */
66 -       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
67 -       reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
68 -       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
69 -
70 -       mdelay(100);
71 -
72 -       /* After PHYs are stable we can take Core out of reset state */
73 -       reg = dwc3_readl(dwc->regs, DWC3_GCTL);
74 -       reg &= ~DWC3_GCTL_CORESOFTRESET;
75 -       dwc3_writel(dwc->regs, DWC3_GCTL, reg);
76 +       /*
77 +        * We're resetting only the device side because, if we're in host mode,
78 +        * XHCI driver will reset the host block. If dwc3 was configured for
79 +        * host-only mode, then we can return early.
80 +        */
81 +       if (dwc->dr_mode == USB_DR_MODE_HOST)
82 +               return 0;
83 +
84 +       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
85 +       reg |= DWC3_DCTL_CSFTRST;
86 +       dwc3_writel(dwc->regs, DWC3_DCTL, reg);
87 +
88 +       do {
89 +               reg = dwc3_readl(dwc->regs, DWC3_DCTL);
90 +               if (!(reg & DWC3_DCTL_CSFTRST))
91 +                       return 0;
92 +
93 +               udelay(1);
94 +       } while (--retries);
95  
96 -       return 0;
97 +       return -ETIMEDOUT;
98  }
99  
100  /**