xhci-exynos5.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * SAMSUNG EXYNOS5 USB HOST XHCI Controller
  4. *
  5. * Copyright (C) 2012 Samsung Electronics Co.Ltd
  6. * Vivek Gautam <gautam.vivek@samsung.com>
  7. * Vikas Sajjan <vikas.sajjan@samsung.com>
  8. */
  9. /*
  10. * This file is a conglomeration for DWC3-init sequence and further
  11. * exynos5 specific PHY-init sequence.
  12. */
  13. #include <common.h>
  14. #include <dm.h>
  15. #include <fdtdec.h>
  16. #include <linux/libfdt.h>
  17. #include <malloc.h>
  18. #include <usb.h>
  19. #include <watchdog.h>
  20. #include <asm/arch/cpu.h>
  21. #include <asm/arch/power.h>
  22. #include <asm/arch/xhci-exynos.h>
  23. #include <asm/gpio.h>
  24. #include <linux/errno.h>
  25. #include <linux/compat.h>
  26. #include <linux/usb/dwc3.h>
  27. #include <usb/xhci.h>
  28. /* Declare global data pointer */
  29. DECLARE_GLOBAL_DATA_PTR;
  30. struct exynos_xhci_platdata {
  31. fdt_addr_t hcd_base;
  32. fdt_addr_t phy_base;
  33. struct gpio_desc vbus_gpio;
  34. };
  35. /**
  36. * Contains pointers to register base addresses
  37. * for the usb controller.
  38. */
  39. struct exynos_xhci {
  40. struct usb_platdata usb_plat;
  41. struct xhci_ctrl ctrl;
  42. struct exynos_usb3_phy *usb3_phy;
  43. struct xhci_hccr *hcd;
  44. struct dwc3 *dwc3_reg;
  45. };
  46. static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
  47. {
  48. struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
  49. const void *blob = gd->fdt_blob;
  50. unsigned int node;
  51. int depth;
  52. /*
  53. * Get the base address for XHCI controller from the device node
  54. */
  55. plat->hcd_base = devfdt_get_addr(dev);
  56. if (plat->hcd_base == FDT_ADDR_T_NONE) {
  57. debug("Can't get the XHCI register base address\n");
  58. return -ENXIO;
  59. }
  60. depth = 0;
  61. node = fdtdec_next_compatible_subnode(blob, dev_of_offset(dev),
  62. COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth);
  63. if (node <= 0) {
  64. debug("XHCI: Can't get device node for usb3-phy controller\n");
  65. return -ENODEV;
  66. }
  67. /*
  68. * Get the base address for usbphy from the device node
  69. */
  70. plat->phy_base = fdtdec_get_addr(blob, node, "reg");
  71. if (plat->phy_base == FDT_ADDR_T_NONE) {
  72. debug("Can't get the usbphy register address\n");
  73. return -ENXIO;
  74. }
  75. /* Vbus gpio */
  76. gpio_request_by_name(dev, "samsung,vbus-gpio", 0,
  77. &plat->vbus_gpio, GPIOD_IS_OUT);
  78. return 0;
  79. }
  80. static void exynos5_usb3_phy_init(struct exynos_usb3_phy *phy)
  81. {
  82. u32 reg;
  83. /* enabling usb_drd phy */
  84. set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_EN);
  85. /* Reset USB 3.0 PHY */
  86. writel(0x0, &phy->phy_reg0);
  87. clrbits_le32(&phy->phy_param0,
  88. /* Select PHY CLK source */
  89. PHYPARAM0_REF_USE_PAD |
  90. /* Set Loss-of-Signal Detector sensitivity */
  91. PHYPARAM0_REF_LOSLEVEL_MASK);
  92. setbits_le32(&phy->phy_param0, PHYPARAM0_REF_LOSLEVEL);
  93. writel(0x0, &phy->phy_resume);
  94. /*
  95. * Setting the Frame length Adj value[6:1] to default 0x20
  96. * See xHCI 1.0 spec, 5.2.4
  97. */
  98. setbits_le32(&phy->link_system,
  99. LINKSYSTEM_XHCI_VERSION_CONTROL |
  100. LINKSYSTEM_FLADJ(0x20));
  101. /* Set Tx De-Emphasis level */
  102. clrbits_le32(&phy->phy_param1, PHYPARAM1_PCS_TXDEEMPH_MASK);
  103. setbits_le32(&phy->phy_param1, PHYPARAM1_PCS_TXDEEMPH);
  104. setbits_le32(&phy->phy_batchg, PHYBATCHG_UTMI_CLKSEL);
  105. /* PHYTEST POWERDOWN Control */
  106. clrbits_le32(&phy->phy_test,
  107. PHYTEST_POWERDOWN_SSP |
  108. PHYTEST_POWERDOWN_HSP);
  109. /* UTMI Power Control */
  110. writel(PHYUTMI_OTGDISABLE, &phy->phy_utmi);
  111. /* Use core clock from main PLL */
  112. reg = PHYCLKRST_REFCLKSEL_EXT_REFCLK |
  113. /* Default 24Mhz crystal clock */
  114. PHYCLKRST_FSEL(FSEL_CLKSEL_24M) |
  115. PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF |
  116. PHYCLKRST_SSC_REFCLKSEL(0x88) |
  117. /* Force PortReset of PHY */
  118. PHYCLKRST_PORTRESET |
  119. /* Digital power supply in normal operating mode */
  120. PHYCLKRST_RETENABLEN |
  121. /* Enable ref clock for SS function */
  122. PHYCLKRST_REF_SSP_EN |
  123. /* Enable spread spectrum */
  124. PHYCLKRST_SSC_EN |
  125. /* Power down HS Bias and PLL blocks in suspend mode */
  126. PHYCLKRST_COMMONONN;
  127. writel(reg, &phy->phy_clk_rst);
  128. /* giving time to Phy clock to settle before resetting */
  129. udelay(10);
  130. reg &= ~PHYCLKRST_PORTRESET;
  131. writel(reg, &phy->phy_clk_rst);
  132. }
  133. static void exynos5_usb3_phy_exit(struct exynos_usb3_phy *phy)
  134. {
  135. setbits_le32(&phy->phy_utmi,
  136. PHYUTMI_OTGDISABLE |
  137. PHYUTMI_FORCESUSPEND |
  138. PHYUTMI_FORCESLEEP);
  139. clrbits_le32(&phy->phy_clk_rst,
  140. PHYCLKRST_REF_SSP_EN |
  141. PHYCLKRST_SSC_EN |
  142. PHYCLKRST_COMMONONN);
  143. /* PHYTEST POWERDOWN Control to remove leakage current */
  144. setbits_le32(&phy->phy_test,
  145. PHYTEST_POWERDOWN_SSP |
  146. PHYTEST_POWERDOWN_HSP);
  147. /* disabling usb_drd phy */
  148. set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_DISABLE);
  149. }
  150. static int exynos_xhci_core_init(struct exynos_xhci *exynos)
  151. {
  152. int ret;
  153. exynos5_usb3_phy_init(exynos->usb3_phy);
  154. ret = dwc3_core_init(exynos->dwc3_reg);
  155. if (ret) {
  156. debug("failed to initialize core\n");
  157. return -EINVAL;
  158. }
  159. /* We are hard-coding DWC3 core to Host Mode */
  160. dwc3_set_mode(exynos->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
  161. return 0;
  162. }
  163. static void exynos_xhci_core_exit(struct exynos_xhci *exynos)
  164. {
  165. exynos5_usb3_phy_exit(exynos->usb3_phy);
  166. }
  167. static int xhci_usb_probe(struct udevice *dev)
  168. {
  169. struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
  170. struct exynos_xhci *ctx = dev_get_priv(dev);
  171. struct xhci_hcor *hcor;
  172. int ret;
  173. ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
  174. ctx->usb3_phy = (struct exynos_usb3_phy *)plat->phy_base;
  175. ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
  176. hcor = (struct xhci_hcor *)((uint32_t)ctx->hcd +
  177. HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));
  178. /* setup the Vbus gpio here */
  179. if (dm_gpio_is_valid(&plat->vbus_gpio))
  180. dm_gpio_set_value(&plat->vbus_gpio, 1);
  181. ret = exynos_xhci_core_init(ctx);
  182. if (ret) {
  183. puts("XHCI: failed to initialize controller\n");
  184. return -EINVAL;
  185. }
  186. return xhci_register(dev, ctx->hcd, hcor);
  187. }
  188. static int xhci_usb_remove(struct udevice *dev)
  189. {
  190. struct exynos_xhci *ctx = dev_get_priv(dev);
  191. int ret;
  192. ret = xhci_deregister(dev);
  193. if (ret)
  194. return ret;
  195. exynos_xhci_core_exit(ctx);
  196. return 0;
  197. }
  198. static const struct udevice_id xhci_usb_ids[] = {
  199. { .compatible = "samsung,exynos5250-xhci" },
  200. { }
  201. };
  202. U_BOOT_DRIVER(usb_xhci) = {
  203. .name = "xhci_exynos",
  204. .id = UCLASS_USB,
  205. .of_match = xhci_usb_ids,
  206. .ofdata_to_platdata = xhci_usb_ofdata_to_platdata,
  207. .probe = xhci_usb_probe,
  208. .remove = xhci_usb_remove,
  209. .ops = &xhci_usb_ops,
  210. .platdata_auto_alloc_size = sizeof(struct exynos_xhci_platdata),
  211. .priv_auto_alloc_size = sizeof(struct exynos_xhci),
  212. .flags = DM_FLAG_ALLOC_PRIV_DMA,
  213. };