ehci-vf.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Copyright (c) 2015 Sanchayan Maity <sanchayan.maity@toradex.com>
  3. * Copyright (C) 2015 Toradex AG
  4. *
  5. * Based on ehci-mx6 driver
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <usb.h>
  11. #include <errno.h>
  12. #include <linux/compiler.h>
  13. #include <asm/io.h>
  14. #include <asm/arch/clock.h>
  15. #include <asm/arch/imx-regs.h>
  16. #include <asm/arch/crm_regs.h>
  17. #include <asm/imx-common/iomux-v3.h>
  18. #include <asm/imx-common/regs-usbphy.h>
  19. #include <usb/ehci-ci.h>
  20. #include "ehci.h"
  21. #define USB_NC_REG_OFFSET 0x00000800
  22. #define ANADIG_PLL_CTRL_EN_USB_CLKS (1 << 6)
  23. #define UCTRL_OVER_CUR_POL (1 << 8) /* OTG Polarity of Overcurrent */
  24. #define UCTRL_OVER_CUR_DIS (1 << 7) /* Disable OTG Overcurrent Detection */
  25. /* USBCMD */
  26. #define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
  27. #define UCMD_RESET (1 << 1) /* controller reset */
  28. static const unsigned phy_bases[] = {
  29. USB_PHY0_BASE_ADDR,
  30. USB_PHY1_BASE_ADDR,
  31. };
  32. static const unsigned nc_reg_bases[] = {
  33. USBC0_BASE_ADDR,
  34. USBC1_BASE_ADDR,
  35. };
  36. static void usb_internal_phy_clock_gate(int index)
  37. {
  38. void __iomem *phy_reg;
  39. phy_reg = (void __iomem *)phy_bases[index];
  40. clrbits_le32(phy_reg + USBPHY_CTRL, USBPHY_CTRL_CLKGATE);
  41. }
  42. static void usb_power_config(int index)
  43. {
  44. struct anadig_reg __iomem *anadig =
  45. (struct anadig_reg __iomem *)ANADIG_BASE_ADDR;
  46. void __iomem *pll_ctrl;
  47. switch (index) {
  48. case 0:
  49. pll_ctrl = &anadig->pll3_ctrl;
  50. clrbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_BYPASS);
  51. setbits_le32(pll_ctrl, ANADIG_PLL3_CTRL_ENABLE
  52. | ANADIG_PLL3_CTRL_POWERDOWN
  53. | ANADIG_PLL_CTRL_EN_USB_CLKS);
  54. break;
  55. case 1:
  56. pll_ctrl = &anadig->pll7_ctrl;
  57. clrbits_le32(pll_ctrl, ANADIG_PLL7_CTRL_BYPASS);
  58. setbits_le32(pll_ctrl, ANADIG_PLL7_CTRL_ENABLE
  59. | ANADIG_PLL7_CTRL_POWERDOWN
  60. | ANADIG_PLL_CTRL_EN_USB_CLKS);
  61. break;
  62. default:
  63. return;
  64. }
  65. }
  66. static void usb_phy_enable(int index, struct usb_ehci *ehci)
  67. {
  68. void __iomem *phy_reg;
  69. void __iomem *phy_ctrl;
  70. void __iomem *usb_cmd;
  71. phy_reg = (void __iomem *)phy_bases[index];
  72. phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL);
  73. usb_cmd = (void __iomem *)&ehci->usbcmd;
  74. /* Stop then Reset */
  75. clrbits_le32(usb_cmd, UCMD_RUN_STOP);
  76. while (readl(usb_cmd) & UCMD_RUN_STOP)
  77. ;
  78. setbits_le32(usb_cmd, UCMD_RESET);
  79. while (readl(usb_cmd) & UCMD_RESET)
  80. ;
  81. /* Reset USBPHY module */
  82. setbits_le32(phy_ctrl, USBPHY_CTRL_SFTRST);
  83. udelay(10);
  84. /* Remove CLKGATE and SFTRST */
  85. clrbits_le32(phy_ctrl, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST);
  86. udelay(10);
  87. /* Power up the PHY */
  88. writel(0, phy_reg + USBPHY_PWD);
  89. /* Enable FS/LS device */
  90. setbits_le32(phy_ctrl, USBPHY_CTRL_ENUTMILEVEL2 |
  91. USBPHY_CTRL_ENUTMILEVEL3);
  92. }
  93. static void usb_oc_config(int index)
  94. {
  95. void __iomem *ctrl;
  96. ctrl = (void __iomem *)(nc_reg_bases[index] + USB_NC_REG_OFFSET);
  97. setbits_le32(ctrl, UCTRL_OVER_CUR_POL);
  98. setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
  99. }
  100. int __weak board_usb_phy_mode(int port)
  101. {
  102. return 0;
  103. }
  104. int __weak board_ehci_hcd_init(int port)
  105. {
  106. return 0;
  107. }
  108. int ehci_hcd_init(int index, enum usb_init_type init,
  109. struct ehci_hccr **hccr, struct ehci_hcor **hcor)
  110. {
  111. struct usb_ehci *ehci;
  112. enum usb_init_type type;
  113. if (index >= ARRAY_SIZE(nc_reg_bases))
  114. return -EINVAL;
  115. ehci = (struct usb_ehci *)nc_reg_bases[index];
  116. /* Do board specific initialisation */
  117. board_ehci_hcd_init(index);
  118. usb_power_config(index);
  119. usb_oc_config(index);
  120. usb_internal_phy_clock_gate(index);
  121. usb_phy_enable(index, ehci);
  122. *hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
  123. *hcor = (struct ehci_hcor *)((uint32_t)*hccr +
  124. HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
  125. type = board_usb_phy_mode(index);
  126. if (type != init)
  127. return -ENODEV;
  128. if (init == USB_INIT_DEVICE) {
  129. setbits_le32(&ehci->usbmode, CM_DEVICE);
  130. writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
  131. setbits_le32(&ehci->portsc, USB_EN);
  132. } else if (init == USB_INIT_HOST) {
  133. setbits_le32(&ehci->usbmode, CM_HOST);
  134. writel((PORT_PTS_UTMI | PORT_PTS_PTW), &ehci->portsc);
  135. setbits_le32(&ehci->portsc, USB_EN);
  136. }
  137. return 0;
  138. }
  139. int ehci_hcd_stop(int index)
  140. {
  141. return 0;
  142. }