xhci-dwc3.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2015 Freescale Semiconductor, Inc.
  4. *
  5. * DWC3 controller driver
  6. *
  7. * Author: Ramneek Mehresh<ramneek.mehresh@freescale.com>
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <fdtdec.h>
  12. #include <generic-phy.h>
  13. #include <usb.h>
  14. #include "xhci.h"
  15. #include <asm/io.h>
  16. #include <linux/usb/dwc3.h>
  17. #include <linux/usb/otg.h>
  18. struct xhci_dwc3_platdata {
  19. struct phy *usb_phys;
  20. int num_phys;
  21. };
  22. void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
  23. {
  24. clrsetbits_le32(&dwc3_reg->g_ctl,
  25. DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG),
  26. DWC3_GCTL_PRTCAPDIR(mode));
  27. }
  28. static void dwc3_phy_reset(struct dwc3 *dwc3_reg)
  29. {
  30. /* Assert USB3 PHY reset */
  31. setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
  32. /* Assert USB2 PHY reset */
  33. setbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
  34. mdelay(100);
  35. /* Clear USB3 PHY reset */
  36. clrbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
  37. /* Clear USB2 PHY reset */
  38. clrbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
  39. }
  40. void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
  41. {
  42. /* Before Resetting PHY, put Core in Reset */
  43. setbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
  44. /* reset USB3 phy - if required */
  45. dwc3_phy_reset(dwc3_reg);
  46. mdelay(100);
  47. /* After PHYs are stable we can take Core out of reset state */
  48. clrbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
  49. }
  50. int dwc3_core_init(struct dwc3 *dwc3_reg)
  51. {
  52. u32 reg;
  53. u32 revision;
  54. unsigned int dwc3_hwparams1;
  55. revision = readl(&dwc3_reg->g_snpsid);
  56. /* This should read as U3 followed by revision number */
  57. if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) {
  58. puts("this is not a DesignWare USB3 DRD Core\n");
  59. return -1;
  60. }
  61. dwc3_core_soft_reset(dwc3_reg);
  62. dwc3_hwparams1 = readl(&dwc3_reg->g_hwparams1);
  63. reg = readl(&dwc3_reg->g_ctl);
  64. reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
  65. reg &= ~DWC3_GCTL_DISSCRAMBLE;
  66. switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1)) {
  67. case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
  68. reg &= ~DWC3_GCTL_DSBLCLKGTNG;
  69. break;
  70. default:
  71. debug("No power optimization available\n");
  72. }
  73. /*
  74. * WORKAROUND: DWC3 revisions <1.90a have a bug
  75. * where the device can fail to connect at SuperSpeed
  76. * and falls back to high-speed mode which causes
  77. * the device to enter a Connect/Disconnect loop
  78. */
  79. if ((revision & DWC3_REVISION_MASK) < 0x190a)
  80. reg |= DWC3_GCTL_U2RSTECN;
  81. writel(reg, &dwc3_reg->g_ctl);
  82. return 0;
  83. }
  84. void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
  85. {
  86. setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL |
  87. GFLADJ_30MHZ(val));
  88. }
  89. #ifdef CONFIG_DM_USB
  90. static int xhci_dwc3_setup_phy(struct udevice *dev)
  91. {
  92. struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
  93. int i, ret, count;
  94. /* Return if no phy declared */
  95. if (!dev_read_prop(dev, "phys", NULL))
  96. return 0;
  97. count = dev_count_phandle_with_args(dev, "phys", "#phy-cells");
  98. if (count <= 0)
  99. return count;
  100. plat->usb_phys = devm_kcalloc(dev, count, sizeof(struct phy),
  101. GFP_KERNEL);
  102. if (!plat->usb_phys)
  103. return -ENOMEM;
  104. for (i = 0; i < count; i++) {
  105. ret = generic_phy_get_by_index(dev, i, &plat->usb_phys[i]);
  106. if (ret && ret != -ENOENT) {
  107. pr_err("Failed to get USB PHY%d for %s\n",
  108. i, dev->name);
  109. return ret;
  110. }
  111. ++plat->num_phys;
  112. }
  113. for (i = 0; i < plat->num_phys; i++) {
  114. ret = generic_phy_init(&plat->usb_phys[i]);
  115. if (ret) {
  116. pr_err("Can't init USB PHY%d for %s\n",
  117. i, dev->name);
  118. goto phys_init_err;
  119. }
  120. }
  121. for (i = 0; i < plat->num_phys; i++) {
  122. ret = generic_phy_power_on(&plat->usb_phys[i]);
  123. if (ret) {
  124. pr_err("Can't power USB PHY%d for %s\n",
  125. i, dev->name);
  126. goto phys_poweron_err;
  127. }
  128. }
  129. return 0;
  130. phys_poweron_err:
  131. for (; i >= 0; i--)
  132. generic_phy_power_off(&plat->usb_phys[i]);
  133. for (i = 0; i < plat->num_phys; i++)
  134. generic_phy_exit(&plat->usb_phys[i]);
  135. return ret;
  136. phys_init_err:
  137. for (; i >= 0; i--)
  138. generic_phy_exit(&plat->usb_phys[i]);
  139. return ret;
  140. }
  141. static int xhci_dwc3_shutdown_phy(struct udevice *dev)
  142. {
  143. struct xhci_dwc3_platdata *plat = dev_get_platdata(dev);
  144. int i, ret;
  145. for (i = 0; i < plat->num_phys; i++) {
  146. if (!generic_phy_valid(&plat->usb_phys[i]))
  147. continue;
  148. ret = generic_phy_power_off(&plat->usb_phys[i]);
  149. ret |= generic_phy_exit(&plat->usb_phys[i]);
  150. if (ret) {
  151. pr_err("Can't shutdown USB PHY%d for %s\n",
  152. i, dev->name);
  153. }
  154. }
  155. return 0;
  156. }
  157. static int xhci_dwc3_probe(struct udevice *dev)
  158. {
  159. struct xhci_hcor *hcor;
  160. struct xhci_hccr *hccr;
  161. struct dwc3 *dwc3_reg;
  162. enum usb_dr_mode dr_mode;
  163. int ret;
  164. hccr = (struct xhci_hccr *)((uintptr_t)dev_read_addr(dev));
  165. hcor = (struct xhci_hcor *)((uintptr_t)hccr +
  166. HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
  167. ret = xhci_dwc3_setup_phy(dev);
  168. if (ret)
  169. return ret;
  170. dwc3_reg = (struct dwc3 *)((char *)(hccr) + DWC3_REG_OFFSET);
  171. dwc3_core_init(dwc3_reg);
  172. dr_mode = usb_get_dr_mode(dev_of_offset(dev));
  173. if (dr_mode == USB_DR_MODE_UNKNOWN)
  174. /* by default set dual role mode to HOST */
  175. dr_mode = USB_DR_MODE_HOST;
  176. dwc3_set_mode(dwc3_reg, dr_mode);
  177. return xhci_register(dev, hccr, hcor);
  178. }
  179. static int xhci_dwc3_remove(struct udevice *dev)
  180. {
  181. xhci_dwc3_shutdown_phy(dev);
  182. return xhci_deregister(dev);
  183. }
  184. static const struct udevice_id xhci_dwc3_ids[] = {
  185. { .compatible = "snps,dwc3" },
  186. { }
  187. };
  188. U_BOOT_DRIVER(xhci_dwc3) = {
  189. .name = "xhci-dwc3",
  190. .id = UCLASS_USB,
  191. .of_match = xhci_dwc3_ids,
  192. .probe = xhci_dwc3_probe,
  193. .remove = xhci_dwc3_remove,
  194. .ops = &xhci_usb_ops,
  195. .priv_auto_alloc_size = sizeof(struct xhci_ctrl),
  196. .platdata_auto_alloc_size = sizeof(struct xhci_dwc3_platdata),
  197. .flags = DM_FLAG_ALLOC_PRIV_DMA,
  198. };
  199. #endif