ehci-mx5.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
  4. * Copyright (C) 2010 Freescale Semiconductor, Inc.
  5. */
  6. #include <common.h>
  7. #include <usb.h>
  8. #include <errno.h>
  9. #include <linux/compiler.h>
  10. #include <usb/ehci-ci.h>
  11. #include <asm/io.h>
  12. #include <asm/arch/imx-regs.h>
  13. #include <asm/arch/clock.h>
  14. #include <dm.h>
  15. #include <power/regulator.h>
  16. #include "ehci.h"
  17. #define MX5_USBOTHER_REGS_OFFSET 0x800
  18. #define MXC_OTG_OFFSET 0
  19. #define MXC_H1_OFFSET 0x200
  20. #define MXC_H2_OFFSET 0x400
  21. #define MXC_H3_OFFSET 0x600
  22. #define MXC_USBCTRL_OFFSET 0
  23. #define MXC_USB_PHY_CTR_FUNC_OFFSET 0x8
  24. #define MXC_USB_PHY_CTR_FUNC2_OFFSET 0xc
  25. #define MXC_USB_CTRL_1_OFFSET 0x10
  26. #define MXC_USBH2CTRL_OFFSET 0x14
  27. #define MXC_USBH3CTRL_OFFSET 0x18
  28. /* USB_CTRL */
  29. /* OTG wakeup intr enable */
  30. #define MXC_OTG_UCTRL_OWIE_BIT (1 << 27)
  31. /* OTG power mask */
  32. #define MXC_OTG_UCTRL_OPM_BIT (1 << 24)
  33. /* OTG power pin polarity */
  34. #define MXC_OTG_UCTRL_O_PWR_POL_BIT (1 << 24)
  35. /* Host1 ULPI interrupt enable */
  36. #define MXC_H1_UCTRL_H1UIE_BIT (1 << 12)
  37. /* HOST1 wakeup intr enable */
  38. #define MXC_H1_UCTRL_H1WIE_BIT (1 << 11)
  39. /* HOST1 power mask */
  40. #define MXC_H1_UCTRL_H1PM_BIT (1 << 8)
  41. /* HOST1 power pin polarity */
  42. #define MXC_H1_UCTRL_H1_PWR_POL_BIT (1 << 8)
  43. /* USB_PHY_CTRL_FUNC */
  44. /* OTG Polarity of Overcurrent */
  45. #define MXC_OTG_PHYCTRL_OC_POL_BIT (1 << 9)
  46. /* OTG Disable Overcurrent Event */
  47. #define MXC_OTG_PHYCTRL_OC_DIS_BIT (1 << 8)
  48. /* UH1 Polarity of Overcurrent */
  49. #define MXC_H1_OC_POL_BIT (1 << 6)
  50. /* UH1 Disable Overcurrent Event */
  51. #define MXC_H1_OC_DIS_BIT (1 << 5)
  52. /* OTG Power Pin Polarity */
  53. #define MXC_OTG_PHYCTRL_PWR_POL_BIT (1 << 3)
  54. /* USBH2CTRL */
  55. #define MXC_H2_UCTRL_H2_OC_POL_BIT (1 << 31)
  56. #define MXC_H2_UCTRL_H2_OC_DIS_BIT (1 << 30)
  57. #define MXC_H2_UCTRL_H2UIE_BIT (1 << 8)
  58. #define MXC_H2_UCTRL_H2WIE_BIT (1 << 7)
  59. #define MXC_H2_UCTRL_H2PM_BIT (1 << 4)
  60. #define MXC_H2_UCTRL_H2_PWR_POL_BIT (1 << 4)
  61. /* USBH3CTRL */
  62. #define MXC_H3_UCTRL_H3_OC_POL_BIT (1 << 31)
  63. #define MXC_H3_UCTRL_H3_OC_DIS_BIT (1 << 30)
  64. #define MXC_H3_UCTRL_H3UIE_BIT (1 << 8)
  65. #define MXC_H3_UCTRL_H3WIE_BIT (1 << 7)
  66. #define MXC_H3_UCTRL_H3_PWR_POL_BIT (1 << 4)
  67. /* USB_CTRL_1 */
  68. #define MXC_USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
  69. int mxc_set_usbcontrol(int port, unsigned int flags)
  70. {
  71. unsigned int v;
  72. void __iomem *usb_base = (void __iomem *)OTG_BASE_ADDR;
  73. void __iomem *usbother_base;
  74. int ret = 0;
  75. usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
  76. switch (port) {
  77. case 0: /* OTG port */
  78. if (flags & MXC_EHCI_INTERNAL_PHY) {
  79. v = __raw_readl(usbother_base +
  80. MXC_USB_PHY_CTR_FUNC_OFFSET);
  81. if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
  82. v |= MXC_OTG_PHYCTRL_OC_POL_BIT;
  83. else
  84. v &= ~MXC_OTG_PHYCTRL_OC_POL_BIT;
  85. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  86. /* OC/USBPWR is used */
  87. v &= ~MXC_OTG_PHYCTRL_OC_DIS_BIT;
  88. else
  89. /* OC/USBPWR is not used */
  90. v |= MXC_OTG_PHYCTRL_OC_DIS_BIT;
  91. #ifdef CONFIG_MX51
  92. if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
  93. v |= MXC_OTG_PHYCTRL_PWR_POL_BIT;
  94. else
  95. v &= ~MXC_OTG_PHYCTRL_PWR_POL_BIT;
  96. #endif
  97. __raw_writel(v, usbother_base +
  98. MXC_USB_PHY_CTR_FUNC_OFFSET);
  99. v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
  100. #ifdef CONFIG_MX51
  101. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  102. v &= ~MXC_OTG_UCTRL_OPM_BIT;
  103. else
  104. v |= MXC_OTG_UCTRL_OPM_BIT;
  105. #endif
  106. #ifdef CONFIG_MX53
  107. if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
  108. v |= MXC_OTG_UCTRL_O_PWR_POL_BIT;
  109. else
  110. v &= ~MXC_OTG_UCTRL_O_PWR_POL_BIT;
  111. #endif
  112. __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
  113. }
  114. break;
  115. case 1: /* Host 1 ULPI */
  116. #ifdef CONFIG_MX51
  117. /* The clock for the USBH1 ULPI port will come externally
  118. from the PHY. */
  119. v = __raw_readl(usbother_base + MXC_USB_CTRL_1_OFFSET);
  120. __raw_writel(v | MXC_USB_CTRL_UH1_EXT_CLK_EN, usbother_base +
  121. MXC_USB_CTRL_1_OFFSET);
  122. #endif
  123. v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
  124. #ifdef CONFIG_MX51
  125. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  126. v &= ~MXC_H1_UCTRL_H1PM_BIT; /* H1 power mask unused */
  127. else
  128. v |= MXC_H1_UCTRL_H1PM_BIT; /* H1 power mask used */
  129. #endif
  130. #ifdef CONFIG_MX53
  131. if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
  132. v |= MXC_H1_UCTRL_H1_PWR_POL_BIT;
  133. else
  134. v &= ~MXC_H1_UCTRL_H1_PWR_POL_BIT;
  135. #endif
  136. __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
  137. v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
  138. if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
  139. v |= MXC_H1_OC_POL_BIT;
  140. else
  141. v &= ~MXC_H1_OC_POL_BIT;
  142. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  143. v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */
  144. else
  145. v |= MXC_H1_OC_DIS_BIT; /* OC is not used */
  146. __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
  147. break;
  148. case 2: /* Host 2 ULPI */
  149. v = __raw_readl(usbother_base + MXC_USBH2CTRL_OFFSET);
  150. #ifdef CONFIG_MX51
  151. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  152. v &= ~MXC_H2_UCTRL_H2PM_BIT; /* H2 power mask unused */
  153. else
  154. v |= MXC_H2_UCTRL_H2PM_BIT; /* H2 power mask used */
  155. #endif
  156. #ifdef CONFIG_MX53
  157. if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
  158. v |= MXC_H2_UCTRL_H2_OC_POL_BIT;
  159. else
  160. v &= ~MXC_H2_UCTRL_H2_OC_POL_BIT;
  161. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  162. v &= ~MXC_H2_UCTRL_H2_OC_DIS_BIT; /* OC is used */
  163. else
  164. v |= MXC_H2_UCTRL_H2_OC_DIS_BIT; /* OC is not used */
  165. if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
  166. v |= MXC_H2_UCTRL_H2_PWR_POL_BIT;
  167. else
  168. v &= ~MXC_H2_UCTRL_H2_PWR_POL_BIT;
  169. #endif
  170. __raw_writel(v, usbother_base + MXC_USBH2CTRL_OFFSET);
  171. break;
  172. #ifdef CONFIG_MX53
  173. case 3: /* Host 3 ULPI */
  174. v = __raw_readl(usbother_base + MXC_USBH3CTRL_OFFSET);
  175. if (flags & MXC_EHCI_OC_PIN_ACTIVE_LOW)
  176. v |= MXC_H3_UCTRL_H3_OC_POL_BIT;
  177. else
  178. v &= ~MXC_H3_UCTRL_H3_OC_POL_BIT;
  179. if (flags & MXC_EHCI_POWER_PINS_ENABLED)
  180. v &= ~MXC_H3_UCTRL_H3_OC_DIS_BIT; /* OC is used */
  181. else
  182. v |= MXC_H3_UCTRL_H3_OC_DIS_BIT; /* OC is not used */
  183. if (flags & MXC_EHCI_PWR_PIN_ACTIVE_HIGH)
  184. v |= MXC_H3_UCTRL_H3_PWR_POL_BIT;
  185. else
  186. v &= ~MXC_H3_UCTRL_H3_PWR_POL_BIT;
  187. __raw_writel(v, usbother_base + MXC_USBH3CTRL_OFFSET);
  188. break;
  189. #endif
  190. }
  191. return ret;
  192. }
  193. int __weak board_ehci_hcd_init(int port)
  194. {
  195. return 0;
  196. }
  197. void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
  198. {
  199. }
  200. __weak void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
  201. uint32_t *reg)
  202. {
  203. mdelay(50);
  204. }
  205. #if !CONFIG_IS_ENABLED(DM_USB)
  206. static const struct ehci_ops mx5_ehci_ops = {
  207. .powerup_fixup = mx5_ehci_powerup_fixup,
  208. };
  209. int ehci_hcd_init(int index, enum usb_init_type init,
  210. struct ehci_hccr **hccr, struct ehci_hcor **hcor)
  211. {
  212. struct usb_ehci *ehci;
  213. /* The only user for this is efikamx-usb */
  214. ehci_set_controller_priv(index, NULL, &mx5_ehci_ops);
  215. set_usboh3_clk();
  216. enable_usboh3_clk(true);
  217. set_usb_phy_clk();
  218. enable_usb_phy1_clk(true);
  219. enable_usb_phy2_clk(true);
  220. mdelay(1);
  221. /* Do board specific initialization */
  222. board_ehci_hcd_init(CONFIG_MXC_USB_PORT);
  223. ehci = (struct usb_ehci *)(OTG_BASE_ADDR +
  224. (0x200 * CONFIG_MXC_USB_PORT));
  225. *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
  226. *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
  227. HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
  228. setbits_le32(&ehci->usbmode, CM_HOST);
  229. __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
  230. setbits_le32(&ehci->portsc, USB_EN);
  231. mxc_set_usbcontrol(CONFIG_MXC_USB_PORT, CONFIG_MXC_USB_FLAGS);
  232. mdelay(10);
  233. /* Do board specific post-initialization */
  234. board_ehci_hcd_postinit(ehci, CONFIG_MXC_USB_PORT);
  235. return 0;
  236. }
  237. int ehci_hcd_stop(int index)
  238. {
  239. return 0;
  240. }
  241. #else /* CONFIG_IS_ENABLED(DM_USB) */
  242. struct ehci_mx5_priv_data {
  243. struct ehci_ctrl ctrl;
  244. struct usb_ehci *ehci;
  245. struct udevice *vbus_supply;
  246. enum usb_init_type init_type;
  247. int portnr;
  248. };
  249. static const struct ehci_ops mx5_ehci_ops = {
  250. .powerup_fixup = mx5_ehci_powerup_fixup,
  251. };
  252. static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
  253. {
  254. struct usb_platdata *plat = dev_get_platdata(dev);
  255. const char *mode;
  256. mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "dr_mode", NULL);
  257. if (mode) {
  258. if (strcmp(mode, "peripheral") == 0)
  259. plat->init_type = USB_INIT_DEVICE;
  260. else if (strcmp(mode, "host") == 0)
  261. plat->init_type = USB_INIT_HOST;
  262. else
  263. return -EINVAL;
  264. }
  265. return 0;
  266. }
  267. static int ehci_usb_probe(struct udevice *dev)
  268. {
  269. struct usb_platdata *plat = dev_get_platdata(dev);
  270. struct usb_ehci *ehci = (struct usb_ehci *)devfdt_get_addr(dev);
  271. struct ehci_mx5_priv_data *priv = dev_get_priv(dev);
  272. enum usb_init_type type = plat->init_type;
  273. struct ehci_hccr *hccr;
  274. struct ehci_hcor *hcor;
  275. int ret;
  276. set_usboh3_clk();
  277. enable_usboh3_clk(true);
  278. set_usb_phy_clk();
  279. enable_usb_phy1_clk(true);
  280. enable_usb_phy2_clk(true);
  281. mdelay(1);
  282. priv->ehci = ehci;
  283. priv->portnr = dev->seq;
  284. priv->init_type = type;
  285. ret = device_get_supply_regulator(dev, "vbus-supply",
  286. &priv->vbus_supply);
  287. if (ret)
  288. debug("%s: No vbus supply\n", dev->name);
  289. if (!ret && priv->vbus_supply) {
  290. ret = regulator_set_enable(priv->vbus_supply,
  291. (type == USB_INIT_DEVICE) ?
  292. false : true);
  293. if (ret) {
  294. puts("Error enabling VBUS supply\n");
  295. return ret;
  296. }
  297. }
  298. hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
  299. hcor = (struct ehci_hcor *)((uint32_t)hccr +
  300. HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
  301. setbits_le32(&ehci->usbmode, CM_HOST);
  302. __raw_writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
  303. setbits_le32(&ehci->portsc, USB_EN);
  304. mxc_set_usbcontrol(priv->portnr, CONFIG_MXC_USB_FLAGS);
  305. mdelay(10);
  306. return ehci_register(dev, hccr, hcor, &mx5_ehci_ops, 0,
  307. priv->init_type);
  308. }
  309. static const struct udevice_id mx5_usb_ids[] = {
  310. { .compatible = "fsl,imx53-usb" },
  311. { }
  312. };
  313. U_BOOT_DRIVER(usb_mx5) = {
  314. .name = "ehci_mx5",
  315. .id = UCLASS_USB,
  316. .of_match = mx5_usb_ids,
  317. .ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
  318. .probe = ehci_usb_probe,
  319. .remove = ehci_deregister,
  320. .ops = &ehci_usb_ops,
  321. .platdata_auto_alloc_size = sizeof(struct usb_platdata),
  322. .priv_auto_alloc_size = sizeof(struct ehci_mx5_priv_data),
  323. .flags = DM_FLAG_ALLOC_PRIV_DMA,
  324. };
  325. #endif /* !CONFIG_IS_ENABLED(DM_USB) */