xhci-exynos5.c 6.2 KB

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