096-06-usb-dwc3-core-improve-reset-sequence.patch 3.0 KB

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