clock.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*++
  2. Copyright (c) 2014 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. clock.c
  5. Abstract:
  6. This module manages power and clocks for TI OMAP4 devices.
  7. Author:
  8. Evan Green 3-Mar-2014
  9. Environment:
  10. Firmware
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <uefifw.h>
  16. #include "dev/omap4.h"
  17. //
  18. // --------------------------------------------------------------------- Macros
  19. //
  20. //
  21. // This macro reads from an OMAP4 PRCM Register. _Base should be a pointer, and
  22. // _Register should be a register offset in ULONGs.
  23. //
  24. #define READ_PRCM_REGISTER(_Base, _Register) \
  25. EfiReadRegister32((UINT32 *)(_Base) + (_Register))
  26. //
  27. // This macro writes to an OMAP4 PRCM Register. _Base should be a pointer,
  28. // _Register should be register offset in ULONGs, and _Value should be a ULONG.
  29. //
  30. #define WRITE_PRCM_REGISTER(_Base, _Register, _Value) \
  31. EfiWriteRegister32((UINT32 *)(_Base) + (_Register), (_Value))
  32. //
  33. // ---------------------------------------------------------------- Definitions
  34. //
  35. //
  36. // Define clock/reset base addresses for OMAP4 SoCs.
  37. //
  38. #define OMAP4_WAKEUP_CLOCK_BASE 0x4A307800
  39. #define OMAP4_L4_CLOCK_BASE 0x4A009400
  40. #define OMAP4_AUDIO_CLOCK_BASE 0x4A004500
  41. //
  42. // This bit is set to select the always on 32kHz clock source to drive the
  43. // timer counter.
  44. //
  45. #define GPTIMER_SELECT_32KHZ_CLOCK 0x01000000
  46. #define GPTIMER_SELECT_SYSTEM_CLOCK 0x00000000
  47. //
  48. // These bits define the operating mode of the functional clock.
  49. //
  50. #define GPTIMER_CLOCK_MODE_MASK 0x03
  51. #define GPTIMER_ENABLE_CLOCK 0x02
  52. //
  53. // Define the clock control bits for the Audio backend control.
  54. //
  55. #define AUDIO_CLOCK_CONTROL_MODE_MASK 0x3
  56. #define AUDIO_CLOCK_CONTROL_NO_SLEEP 0x0
  57. //
  58. // ----------------------------------------------- Internal Function Prototypes
  59. //
  60. //
  61. // ------------------------------------------------------ Data Type Definitions
  62. //
  63. //
  64. // Register offsets for the Wakeup Clock Management interface (WKUP_CM). All
  65. // offsets are in UINT32s.
  66. //
  67. typedef enum _WKUP_CM_REGISTER {
  68. WakeupClockControl = 0x00, // CM_WKUP_CLKSTCTRL
  69. WakeupClockGpTimer1Control = 0x10, // CM_WKUP_GPTIMER1_CLKCTRL
  70. } WKUP_CM_REGISTER, *PWKUP_CM_REGISTER;
  71. //
  72. // Register offsets for the L4 Interconnect Clock Managment interface
  73. // (L4PER_CM). All offsets are in UINT32s.
  74. //
  75. typedef enum _L4PER_CM_REGISTER {
  76. L4ClockControl = 0x00, // CM_L4PER_CLKSTCTRL
  77. L4ClockGpTimer10Control = 0x0A, // CM_L4PER_GPTIMER10_CLKCTRL
  78. L4ClockGpTimer11Control = 0x0C, // CM_L4PER_GPTIMER11_CLKCTRL
  79. L4ClockGpTimer2Control = 0x0E, // CM_L4PER_GPTIMER2_CLKCTRL
  80. L4ClockGpTimer3Control = 0x10, // CM_L4PER_GPTIMER3_CLKCTRL
  81. L4ClockGpTimer4Control = 0x12, // CM_L4PER_GPTIMER4_CLKCTRL
  82. L4ClockGpTimer9Control = 0x14, // CM_L4PER_GPTIMER9_CLKCTRL
  83. } L4PER_CM_REGISTER, *PL4PER_CM_REGISTER;
  84. //
  85. // Register offsets for the Audio Back-End Clock Management interface (ABE_CM1).
  86. // All offsets are in UINT32s.
  87. //
  88. typedef enum _ABE_CM1_REGISTER {
  89. AudioClockControl = 0x00, // CM1_ABE_CLKSTCTRL
  90. AudioClockGpTimer5Control = 0x1A, // CM1_ABE_GPTIMER5_CLKCTRL
  91. AudioClockGpTimer6Control = 0x1C, // CM1_ABE_GPTIMER6_CLKCTRL
  92. AudioClockGpTimer7Control = 0x1E, // CM1_ABE_GPTIMER7_CLKCTRL
  93. AudioClockGpTimer8Control = 0x20, // CM1_ABE_GPTIMER8_CLKCTRL
  94. } ABE_CM1_REGISTER, *PABE_CM1_REGISTER;
  95. //
  96. // -------------------------------------------------------------------- Globals
  97. //
  98. //
  99. // Store pointers to pieces of the PRCM.
  100. //
  101. VOID *EfiOmap4WakeupClockControl = (VOID *)OMAP4_WAKEUP_CLOCK_BASE;
  102. VOID *EfiOmap4L4ClockControl = (VOID *)OMAP4_L4_CLOCK_BASE;
  103. VOID *EfiOmap4AudioClockControl = (VOID *)OMAP4_AUDIO_CLOCK_BASE;
  104. //
  105. // ------------------------------------------------------------------ Functions
  106. //
  107. VOID
  108. EfipOmap4InitializePowerAndClocks (
  109. VOID
  110. )
  111. /*++
  112. Routine Description:
  113. This routine initializes the PRCM and turns on clocks and power domains
  114. needed by the system.
  115. Arguments:
  116. None.
  117. Return Value:
  118. Status code.
  119. --*/
  120. {
  121. UINT32 Value;
  122. //
  123. // Enable GP Timer 1, and set it to run at the system clock frequency.
  124. //
  125. Value = GPTIMER_SELECT_SYSTEM_CLOCK | GPTIMER_ENABLE_CLOCK;
  126. WRITE_PRCM_REGISTER(EfiOmap4WakeupClockControl,
  127. WakeupClockGpTimer1Control,
  128. Value);
  129. //
  130. // Enable GP Timers 2-4 and 9-11 to run at the 32kHz clock speed.
  131. //
  132. Value = GPTIMER_SELECT_32KHZ_CLOCK | GPTIMER_ENABLE_CLOCK;
  133. WRITE_PRCM_REGISTER(EfiOmap4L4ClockControl,
  134. L4ClockGpTimer2Control,
  135. Value);
  136. WRITE_PRCM_REGISTER(EfiOmap4L4ClockControl,
  137. L4ClockGpTimer3Control,
  138. Value);
  139. WRITE_PRCM_REGISTER(EfiOmap4L4ClockControl,
  140. L4ClockGpTimer4Control,
  141. Value);
  142. WRITE_PRCM_REGISTER(EfiOmap4L4ClockControl,
  143. L4ClockGpTimer9Control,
  144. Value);
  145. WRITE_PRCM_REGISTER(EfiOmap4L4ClockControl,
  146. L4ClockGpTimer10Control,
  147. Value);
  148. WRITE_PRCM_REGISTER(EfiOmap4L4ClockControl,
  149. L4ClockGpTimer11Control,
  150. Value);
  151. //
  152. // Enable the Audio Back-End clock.
  153. //
  154. Value = READ_PRCM_REGISTER(EfiOmap4AudioClockControl, AudioClockControl);
  155. Value &= ~AUDIO_CLOCK_CONTROL_MODE_MASK;
  156. Value |= AUDIO_CLOCK_CONTROL_NO_SLEEP;
  157. WRITE_PRCM_REGISTER(EfiOmap4AudioClockControl, AudioClockControl, Value);
  158. //
  159. // Enable GP Timers 5-8 to run at the 32kHz always on clock rate.
  160. //
  161. Value = GPTIMER_SELECT_32KHZ_CLOCK | GPTIMER_ENABLE_CLOCK;
  162. WRITE_PRCM_REGISTER(EfiOmap4AudioClockControl,
  163. AudioClockGpTimer5Control,
  164. Value);
  165. WRITE_PRCM_REGISTER(EfiOmap4AudioClockControl,
  166. AudioClockGpTimer6Control,
  167. Value);
  168. WRITE_PRCM_REGISTER(EfiOmap4AudioClockControl,
  169. AudioClockGpTimer7Control,
  170. Value);
  171. WRITE_PRCM_REGISTER(EfiOmap4AudioClockControl,
  172. AudioClockGpTimer8Control,
  173. Value);
  174. return;
  175. }
  176. //
  177. // --------------------------------------------------------- Internal Functions
  178. //