1
0

omap4usb.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. omap4usb.c
  5. Abstract:
  6. This module fires up the OMAP4 High Speed USB controller.
  7. Author:
  8. Evan Green 24-Mar-2013
  9. Environment:
  10. Firmware
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <uefifw.h>
  16. #include "pandafw.h"
  17. //
  18. // --------------------------------------------------------------------- Macros
  19. //
  20. #define ULPI_SET_REGISTER(_Register) (_Register + 1)
  21. #define ULPI_CLEAR_REGISTER(_Register) (_Register + 1)
  22. //
  23. // These macros read from and write to the L3 INIT CM2 block.
  24. //
  25. #define OMAP4_READ_L3_INIT_CM2_REGISTER(_Register) \
  26. *(volatile UINT32 *)((UINT8 *)EfiOmap4L3InitCm2Address + (_Register))
  27. #define OMAP4_WRITE_L3_INIT_CM2_REGISTER(_Register, _Value) \
  28. *((volatile UINT32 *)((UINT8 *)EfiOmap4L3InitCm2Address + (_Register))) = \
  29. (_Value)
  30. //
  31. // These macros read from and write to the OMAP4 SCRM.
  32. //
  33. #define OMAP4_READ_SCRM_REGISTER(_Register) \
  34. *(volatile UINT32 *)((UINT8 *)EfiOmap4ScrmAddress + (_Register))
  35. #define OMAP4_WRITE_SCRM_REGISTER(_Register, _Value) \
  36. *((volatile UINT32 *)((UINT8 *)EfiOmap4ScrmAddress + (_Register))) = \
  37. (_Value)
  38. //
  39. // These macros read from and write to the OMAP4 High Speed USB Host block.
  40. //
  41. #define OMAP4_READ_HS_USB_HOST_REGISTER(_Register) \
  42. *(volatile UINT32 *)((UINT8 *)EfiOmap4HsUsbHostAddress + (_Register))
  43. #define OMAP4_WRITE_HS_USB_HOST_REGISTER(_Register, _Value) \
  44. *((volatile UINT32 *)((UINT8 *)EfiOmap4HsUsbHostAddress + (_Register))) = \
  45. (_Value)
  46. //
  47. // These macros read from and write to the OMAP4 EHCI registers.
  48. //
  49. #define OMAP4_READ_EHCI_REGISTER(_Register) \
  50. *(volatile UINT32 *)((UINT8 *)EfiOmap4EhciAddress + (_Register))
  51. #define OMAP4_WRITE_EHCI_REGISTER(_Register, _Value) \
  52. *((volatile UINT32 *)((UINT8 *)EfiOmap4EhciAddress + (_Register))) = \
  53. (_Value)
  54. //
  55. // These macros read from and write to the OMAP4 USB TLL config registers.
  56. //
  57. #define OMAP4_READ_USB_TLL_CONFIG_REGISTER(_Register) \
  58. *(volatile UINT32 *)((UINT8 *)EfiOmap4UsbTllConfigAddress + (_Register))
  59. #define OMAP4_WRITE_USB_TLL_CONFIG_REGISTER(_Register, _Value) \
  60. *((volatile UINT32 *)((UINT8 *)EfiOmap4UsbTllConfigAddress + \
  61. (_Register))) = (_Value)
  62. //
  63. // ---------------------------------------------------------------- Definitions
  64. //
  65. #define OMAP4_HS_USB_PORT_COUNT 1
  66. #define OMAP4_L3_INIT_CM2_USB_HOST_PORT_1_UTMI_EXTERNALLY_CLOCKED (1 << 24)
  67. #define OMAP4_L3_INIT_CM2_USB_HOST_48_MHZ_CLOCK_ENABLED (1 << 15)
  68. #define OMAP4_L3_INIT_CM2_USB_HOST_MODULE_ENABLED (0x2 << 0)
  69. #define OMAP4_L3_INIT_CM2_USB_TLL_ENABLED (0x1 << 0)
  70. #define OMAP4_L3_INIT_CM2_FULL_SPEED_USB_CLOCK_ENABLED (0x2 << 0)
  71. #define OMAP4_L3_INIT_CM2_USB_PHY_48_MHZ_CLOCK_ENABLE (1 << 8)
  72. #define OMAP4_L3_INIT_CM2_USB_PHY_ENABLED (0x1 << 0)
  73. #define OMAP4_USB_TLL_CLOCKS_ON_DURING_IDLE (1 << 8)
  74. #define OMAP4_USB_TLL_CONFIG_NO_IDLE (0x1 << 3)
  75. #define OMAP4_USB_TLL_CONFIG_WAKEUP_ENABLE (1 << 2)
  76. #define OMAP4_USB_TLL_CONFIG_SOFT_RESET (1 << 1)
  77. #define OMAP4_USB_TLL_STATUS_RESET_DONE (1 << 0)
  78. #define OMAP4_AUX_CLOCK_DIVIDE_BY_2 (0x1 << 16)
  79. #define OMAP4_AUX_CLOCK_ENABLED (1 << 8)
  80. #define OMAP4_ALT_CLOCK_ENABLE_EXT (1 << 3)
  81. #define OMAP4_ALT_CLOCK_ENABLE_INT (1 << 2)
  82. #define OMAP4_ALT_CLOCK_ACTIVE (0x1 << 0)
  83. #define OMAP4_HS_USB_SYSTEM_CONFIG_STANDBY_MASK (0x3 << 4)
  84. #define OMAP4_HS_USB_SYSTEM_CONFIG_NO_STANDBY (0x1 << 4)
  85. #define OMAP4_HS_USB_SYSTEM_CONFIG_IDLE_MASK (0x3 << 2)
  86. #define OMAP4_HS_USB_SYSTEM_CONFIG_NO_IDLE (0x1 << 2)
  87. #define OMAP4_HS_USB_HOST_CONFIG_INCR4_ENABLE (1 << 2)
  88. #define OMAP4_HS_USB_HOST_CONFIG_INCR8_ENABLE (1 << 3)
  89. #define OMAP4_HS_USB_HOST_CONFIG_INCR16_ENABLE (1 << 4)
  90. #define OMAP4_HS_USB_HOST_CONFIG_INCR_ALIGNED (1 << 5)
  91. #define OMAP4_HS_USB_P1_MODE_MASK (0x3 << 16)
  92. #define OMAP4_HS_USB_P2_MODE_MASK (0x3 << 18)
  93. #define OMAP4_EHCI_INSNREG4_DISABLE_UNSUSPEND (1 << 5)
  94. #define OMAP4_EHCI_INSNREG5_ULPI_DIRECT_REGISTER_ADDRESS_SHIFT 16
  95. #define OMAP4_EHCI_INSNREG5_ULPI_WRITE (0x2 << 22)
  96. #define OMAP4_EHCI_INSNREG5_ULPI_PORT_SHIFT 24
  97. #define OMAP4_EHCI_INSNREG5_ULPI_START_ACCESS (1 << 31)
  98. #define ULPI_FUNCTION_CONTROL 0x04
  99. #define ULPI_FUNCTION_CONTROL_RESET (1 << 5)
  100. //
  101. // ----------------------------------------------- Internal Function Prototypes
  102. //
  103. //
  104. // ------------------------------------------------------ Data Type Definitions
  105. //
  106. typedef enum _OMAP4_L3_INIT_CM2_REGISTER {
  107. Omap4L3InitCm2UsbHostClockControl = 0x58, // CM_L3INIT_HSUSBHOST_CLKCTRL
  108. Omap4L3InitCm2UsbTllClockControl = 0x68, // CM_L3INIT_HSUSBTLL_CLKCTRL
  109. Omap4L3InitCm2FullSpeedUsbClockControl = 0xD0, // CM_L3INIT_FSUSB_CLKCTRL
  110. Omap4L3InitCm2UsbPhyClockControl = 0xE0, // CM_L3INIT_USBPHY_CLKCTRL
  111. } OMAP4_L3_INIT_CM2_REGISTER, POMAP4_L3_INIT_CM2_REGISTER;
  112. typedef enum _OMAP4_SCRM_REGISTER {
  113. Omap4ScrmAltClockSource = 0x110, // ALTCLKSRC
  114. Omap4ScrmAuxClock3 = 0x31C, // AUXCLK3
  115. } OMAP4_SCRM_REGISTER, *POMAP4_SCRM_REGISTER;
  116. typedef enum _OMAP4_HS_USB_HOST_REGISTER {
  117. Omap4HsUsbHostSystemConfiguration = 0x10, // UHH_SYSCONFIG
  118. Omap4HsUsbHostConfiguration = 0x40, // UHH_HOSTCONFIG
  119. } OMAP4_HS_USB_HOST_REGISTER, POMAP4_HS_USB_HOST_REGISTER;
  120. typedef enum _OMAP4_EHCI_REGISTER {
  121. Omap4EhciImplementationRegister4 = 0xA0, // INSNREG04
  122. Omap4EhciImplementationRegister5 = 0xA4, // INSNREG05
  123. } OMAP4_EHCI_REGISTER, *POMAP4_EHCI_REGISTER;
  124. typedef enum _OMAP4_USB_TLL_CONFIG_REGISTER {
  125. Omap4UsbTllSystemConfiguration = 0x10, // USBTLL_SYSCONFIG
  126. Omap4UsbTllSystemStatus = 0x14, // USBTLL_SYSSTATUS
  127. } OMAP4_USB_TLL_CONFIG_REGISTER, *POMAP4_USB_TLL_CONFIG_REGISTER;
  128. //
  129. // -------------------------------------------------------------------- Globals
  130. //
  131. //
  132. // Store a pointer to the L3 INIT CM2 register block.
  133. //
  134. VOID *EfiOmap4L3InitCm2Address = (VOID *)OMAP4430_L3_INIT_CM2_BASE;
  135. //
  136. // Store a pointer to the SCRM.
  137. //
  138. VOID *EfiOmap4ScrmAddress = (VOID *)OMAP4430_SCRM_BASE;
  139. //
  140. // Store a pointer to the High Speed USB Host block.
  141. //
  142. VOID *EfiOmap4HsUsbHostAddress = (VOID *)OMAP4430_HS_USB_HOST_BASE;
  143. //
  144. // Store a pointer to the EHCI register base.
  145. //
  146. VOID *EfiOmap4EhciAddress = (VOID *)OMAP4430_EHCI_BASE;
  147. //
  148. // Store a pointer to the USB TLL configuration register base.
  149. //
  150. VOID *EfiOmap4UsbTllConfigAddress = (VOID *)OMAP4430_USB_TLL_CONFIG_BASE;
  151. //
  152. // ------------------------------------------------------------------ Functions
  153. //
  154. VOID
  155. EfipOmap4UsbInitialize (
  156. VOID
  157. )
  158. /*++
  159. Routine Description:
  160. This routine performs any board-specific high speed USB initialization.
  161. Arguments:
  162. None.
  163. Return Value:
  164. None.
  165. --*/
  166. {
  167. UINT32 PortIndex;
  168. UINT32 Value;
  169. //
  170. // Enable the USB module's clocks.
  171. //
  172. Value = OMAP4_L3_INIT_CM2_USB_HOST_PORT_1_UTMI_EXTERNALLY_CLOCKED |
  173. OMAP4_L3_INIT_CM2_USB_HOST_MODULE_ENABLED;
  174. OMAP4_WRITE_L3_INIT_CM2_REGISTER(Omap4L3InitCm2UsbHostClockControl, Value);
  175. Value = OMAP4_L3_INIT_CM2_FULL_SPEED_USB_CLOCK_ENABLED;
  176. OMAP4_WRITE_L3_INIT_CM2_REGISTER(Omap4L3InitCm2FullSpeedUsbClockControl,
  177. Value);
  178. Value = OMAP4_L3_INIT_CM2_USB_TLL_ENABLED;
  179. OMAP4_WRITE_L3_INIT_CM2_REGISTER(Omap4L3InitCm2UsbTllClockControl, Value);
  180. Value = (1 << 9) |
  181. OMAP4_L3_INIT_CM2_USB_PHY_48_MHZ_CLOCK_ENABLE |
  182. OMAP4_L3_INIT_CM2_USB_PHY_ENABLED;
  183. OMAP4_WRITE_L3_INIT_CM2_REGISTER(Omap4L3InitCm2UsbPhyClockControl, Value);
  184. //
  185. // Reset the USB TLL module, and wait for reset to complete.
  186. //
  187. Value = OMAP4_USB_TLL_CONFIG_SOFT_RESET;
  188. OMAP4_WRITE_USB_TLL_CONFIG_REGISTER(Omap4UsbTllSystemConfiguration, Value);
  189. do {
  190. Value = OMAP4_READ_USB_TLL_CONFIG_REGISTER(Omap4UsbTllSystemStatus);
  191. } while ((Value & OMAP4_USB_TLL_STATUS_RESET_DONE) == 0);
  192. Value = OMAP4_USB_TLL_CLOCKS_ON_DURING_IDLE |
  193. OMAP4_USB_TLL_CONFIG_NO_IDLE |
  194. OMAP4_USB_TLL_CONFIG_WAKEUP_ENABLE;
  195. OMAP4_WRITE_USB_TLL_CONFIG_REGISTER(Omap4UsbTllSystemConfiguration, Value);
  196. //
  197. // The USB3320C ULPI PHY's clock is fed by fref_clk3_out, a pin sourced by
  198. // AUXCLK3. Enable that puppy and set it to run at the required 19.2MHz,
  199. // half of the system clock's 38.4MHz.
  200. //
  201. Value = OMAP4_AUX_CLOCK_DIVIDE_BY_2 | OMAP4_AUX_CLOCK_ENABLED;
  202. OMAP4_WRITE_SCRM_REGISTER(Omap4ScrmAuxClock3, Value);
  203. Value = OMAP4_ALT_CLOCK_ENABLE_EXT | OMAP4_ALT_CLOCK_ENABLE_INT |
  204. OMAP4_ALT_CLOCK_ACTIVE;
  205. OMAP4_WRITE_SCRM_REGISTER(Omap4ScrmAltClockSource, Value);
  206. //
  207. // Set up the serial configuration (ULPI bypass) and burst configuration.
  208. //
  209. Value = OMAP4_READ_HS_USB_HOST_REGISTER(Omap4HsUsbHostSystemConfiguration);
  210. Value &= ~(OMAP4_HS_USB_SYSTEM_CONFIG_STANDBY_MASK |
  211. OMAP4_HS_USB_SYSTEM_CONFIG_IDLE_MASK);
  212. Value |= OMAP4_HS_USB_SYSTEM_CONFIG_NO_STANDBY |
  213. OMAP4_HS_USB_SYSTEM_CONFIG_NO_IDLE;
  214. OMAP4_WRITE_HS_USB_HOST_REGISTER(Omap4HsUsbHostSystemConfiguration, Value);
  215. Value = OMAP4_READ_HS_USB_HOST_REGISTER(Omap4HsUsbHostConfiguration);
  216. Value |= OMAP4_HS_USB_HOST_CONFIG_INCR4_ENABLE |
  217. OMAP4_HS_USB_HOST_CONFIG_INCR8_ENABLE |
  218. OMAP4_HS_USB_HOST_CONFIG_INCR16_ENABLE;
  219. Value &= ~(OMAP4_HS_USB_HOST_CONFIG_INCR_ALIGNED |
  220. OMAP4_HS_USB_P1_MODE_MASK |
  221. OMAP4_HS_USB_P2_MODE_MASK);
  222. OMAP4_WRITE_HS_USB_HOST_REGISTER(Omap4HsUsbHostConfiguration, Value);
  223. //
  224. // Turn on the magic disable unsuspend bit to prevent the root hub from
  225. // coming out of suspend when the run bit is cleared.
  226. //
  227. OMAP4_WRITE_EHCI_REGISTER(Omap4EhciImplementationRegister4,
  228. OMAP4_EHCI_INSNREG4_DISABLE_UNSUSPEND);
  229. //
  230. // Set GPIO 62 to take the USB3320C PHY out of reset.
  231. //
  232. Value = READ_GPIO2_REGISTER(OmapGpioOutputEnable);
  233. WRITE_GPIO2_REGISTER(OmapGpioOutputEnable, Value & ~(1 << (62 - 32)));
  234. WRITE_GPIO2_REGISTER(OmapGpioOutputSet, (1 << (62 - 32)));
  235. //
  236. // Reset the PHY on each port.
  237. //
  238. for (PortIndex = 0; PortIndex < OMAP4_HS_USB_PORT_COUNT; PortIndex += 1) {
  239. //
  240. // Send a RESET command, which is a write, to the function control
  241. // address of the given port.
  242. //
  243. Value = ULPI_FUNCTION_CONTROL_RESET |
  244. (ULPI_SET_REGISTER(ULPI_FUNCTION_CONTROL) <<
  245. OMAP4_EHCI_INSNREG5_ULPI_DIRECT_REGISTER_ADDRESS_SHIFT) |
  246. OMAP4_EHCI_INSNREG5_ULPI_WRITE |
  247. ((PortIndex + 1) << OMAP4_EHCI_INSNREG5_ULPI_PORT_SHIFT) |
  248. OMAP4_EHCI_INSNREG5_ULPI_START_ACCESS;
  249. OMAP4_WRITE_EHCI_REGISTER(Omap4EhciImplementationRegister5, Value);
  250. do {
  251. Value = OMAP4_READ_EHCI_REGISTER(Omap4EhciImplementationRegister5);
  252. } while ((Value & OMAP4_EHCI_INSNREG5_ULPI_START_ACCESS) != 0);
  253. }
  254. //
  255. // Set GPIO 1 to enable the TPS73633 LDO which provides power to the root
  256. // hub slash ethernet combo. For the output enable register, when a bit is
  257. // 0, then the GPIO is in output mode.
  258. //
  259. Value = READ_GPIO1_REGISTER(OmapGpioOutputEnable);
  260. WRITE_GPIO1_REGISTER(OmapGpioOutputEnable, Value & ~(1 << 1));
  261. WRITE_GPIO1_REGISTER(OmapGpioOutputSet, (1 << 1));
  262. return;
  263. }