clock.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * clock.c
  4. *
  5. * Clock initialization for AM33XX boards.
  6. * Derived from OMAP4 boards
  7. *
  8. * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
  9. */
  10. #include <common.h>
  11. #include <hang.h>
  12. #include <init.h>
  13. #include <log.h>
  14. #include <asm/arch/cpu.h>
  15. #include <asm/arch/clock.h>
  16. #include <asm/arch/hardware.h>
  17. #include <asm/arch/sys_proto.h>
  18. #include <asm/io.h>
  19. static void setup_post_dividers(const struct dpll_regs *dpll_regs,
  20. const struct dpll_params *params)
  21. {
  22. /* Setup post-dividers */
  23. if (params->m2 >= 0)
  24. writel(params->m2, dpll_regs->cm_div_m2_dpll);
  25. if (params->m3 >= 0)
  26. writel(params->m3, dpll_regs->cm_div_m3_dpll);
  27. if (params->m4 >= 0)
  28. writel(params->m4, dpll_regs->cm_div_m4_dpll);
  29. if (params->m5 >= 0)
  30. writel(params->m5, dpll_regs->cm_div_m5_dpll);
  31. if (params->m6 >= 0)
  32. writel(params->m6, dpll_regs->cm_div_m6_dpll);
  33. }
  34. static inline void do_lock_dpll(const struct dpll_regs *dpll_regs)
  35. {
  36. clrsetbits_le32(dpll_regs->cm_clkmode_dpll,
  37. CM_CLKMODE_DPLL_DPLL_EN_MASK,
  38. DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT);
  39. }
  40. static inline void wait_for_lock(const struct dpll_regs *dpll_regs)
  41. {
  42. if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK,
  43. (void *)dpll_regs->cm_idlest_dpll, LDELAY)) {
  44. printf("DPLL locking failed for 0x%x\n",
  45. dpll_regs->cm_clkmode_dpll);
  46. hang();
  47. }
  48. }
  49. static inline void do_bypass_dpll(const struct dpll_regs *dpll_regs)
  50. {
  51. clrsetbits_le32(dpll_regs->cm_clkmode_dpll,
  52. CM_CLKMODE_DPLL_DPLL_EN_MASK,
  53. DPLL_EN_MN_BYPASS << CM_CLKMODE_DPLL_EN_SHIFT);
  54. }
  55. static inline void wait_for_bypass(const struct dpll_regs *dpll_regs)
  56. {
  57. if (!wait_on_value(ST_DPLL_CLK_MASK, 0,
  58. (void *)dpll_regs->cm_idlest_dpll, LDELAY)) {
  59. printf("Bypassing DPLL failed 0x%x\n",
  60. dpll_regs->cm_clkmode_dpll);
  61. }
  62. }
  63. static void bypass_dpll(const struct dpll_regs *dpll_regs)
  64. {
  65. do_bypass_dpll(dpll_regs);
  66. wait_for_bypass(dpll_regs);
  67. }
  68. void do_setup_dpll(const struct dpll_regs *dpll_regs,
  69. const struct dpll_params *params)
  70. {
  71. u32 temp;
  72. if (!params)
  73. return;
  74. temp = readl(dpll_regs->cm_clksel_dpll);
  75. bypass_dpll(dpll_regs);
  76. /* Set M & N */
  77. temp &= ~CM_CLKSEL_DPLL_M_MASK;
  78. temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK;
  79. temp &= ~CM_CLKSEL_DPLL_N_MASK;
  80. temp |= (params->n << CM_CLKSEL_DPLL_N_SHIFT) & CM_CLKSEL_DPLL_N_MASK;
  81. writel(temp, dpll_regs->cm_clksel_dpll);
  82. setup_post_dividers(dpll_regs, params);
  83. /* Wait till the DPLL locks */
  84. do_lock_dpll(dpll_regs);
  85. wait_for_lock(dpll_regs);
  86. }
  87. static void setup_dplls(void)
  88. {
  89. const struct dpll_params *params;
  90. params = get_dpll_core_params();
  91. do_setup_dpll(&dpll_core_regs, params);
  92. params = get_dpll_mpu_params();
  93. do_setup_dpll(&dpll_mpu_regs, params);
  94. params = get_dpll_per_params();
  95. do_setup_dpll(&dpll_per_regs, params);
  96. writel(0x300, &cmwkup->clkdcoldodpllper);
  97. params = get_dpll_ddr_params();
  98. do_setup_dpll(&dpll_ddr_regs, params);
  99. }
  100. static inline void wait_for_clk_enable(u32 *clkctrl_addr)
  101. {
  102. u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED;
  103. u32 bound = LDELAY;
  104. while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) ||
  105. (idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) {
  106. clkctrl = readl(clkctrl_addr);
  107. idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
  108. MODULE_CLKCTRL_IDLEST_SHIFT;
  109. if (--bound == 0) {
  110. printf("Clock enable failed for 0x%p idlest 0x%x\n",
  111. clkctrl_addr, clkctrl);
  112. return;
  113. }
  114. }
  115. }
  116. static inline void enable_clock_module(u32 *const clkctrl_addr, u32 enable_mode,
  117. u32 wait_for_enable)
  118. {
  119. clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
  120. enable_mode << MODULE_CLKCTRL_MODULEMODE_SHIFT);
  121. debug("Enable clock module - %p\n", clkctrl_addr);
  122. if (wait_for_enable)
  123. wait_for_clk_enable(clkctrl_addr);
  124. }
  125. static inline void wait_for_clk_disable(u32 *clkctrl_addr)
  126. {
  127. u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_FULLY_FUNCTIONAL;
  128. u32 bound = LDELAY;
  129. while ((idlest != MODULE_CLKCTRL_IDLEST_DISABLED)) {
  130. clkctrl = readl(clkctrl_addr);
  131. idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >>
  132. MODULE_CLKCTRL_IDLEST_SHIFT;
  133. if (--bound == 0) {
  134. printf("Clock disable failed for 0x%p idlest 0x%x\n",
  135. clkctrl_addr, clkctrl);
  136. return;
  137. }
  138. }
  139. }
  140. static inline void disable_clock_module(u32 *const clkctrl_addr,
  141. u32 wait_for_disable)
  142. {
  143. clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK,
  144. MODULE_CLKCTRL_MODULEMODE_SW_DISABLE <<
  145. MODULE_CLKCTRL_MODULEMODE_SHIFT);
  146. debug("Disable clock module - %p\n", clkctrl_addr);
  147. if (wait_for_disable)
  148. wait_for_clk_disable(clkctrl_addr);
  149. }
  150. static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode)
  151. {
  152. clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
  153. enable_mode << CD_CLKCTRL_CLKTRCTRL_SHIFT);
  154. debug("Enable clock domain - %p\n", clkctrl_reg);
  155. }
  156. static inline void disable_clock_domain(u32 *const clkctrl_reg)
  157. {
  158. clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK,
  159. CD_CLKCTRL_CLKTRCTRL_SW_SLEEP <<
  160. CD_CLKCTRL_CLKTRCTRL_SHIFT);
  161. debug("Disable clock domain - %p\n", clkctrl_reg);
  162. }
  163. void do_enable_clocks(u32 *const *clk_domains,
  164. u32 *const *clk_modules_explicit_en, u8 wait_for_enable)
  165. {
  166. u32 i, max = 100;
  167. /* Put the clock domains in SW_WKUP mode */
  168. for (i = 0; (i < max) && clk_domains[i]; i++) {
  169. enable_clock_domain(clk_domains[i],
  170. CD_CLKCTRL_CLKTRCTRL_SW_WKUP);
  171. }
  172. /* Clock modules that need to be put in SW_EXPLICIT_EN mode */
  173. for (i = 0; (i < max) && clk_modules_explicit_en[i]; i++) {
  174. enable_clock_module(clk_modules_explicit_en[i],
  175. MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN,
  176. wait_for_enable);
  177. };
  178. }
  179. void do_disable_clocks(u32 *const *clk_domains,
  180. u32 *const *clk_modules_disable,
  181. u8 wait_for_disable)
  182. {
  183. u32 i, max = 100;
  184. /* Clock modules that need to be put in SW_DISABLE */
  185. for (i = 0; (i < max) && clk_modules_disable[i]; i++)
  186. disable_clock_module(clk_modules_disable[i],
  187. wait_for_disable);
  188. /* Put the clock domains in SW_SLEEP mode */
  189. for (i = 0; (i < max) && clk_domains[i]; i++)
  190. disable_clock_domain(clk_domains[i]);
  191. }
  192. /*
  193. * Before scaling up the clocks we need to have the PMIC scale up the
  194. * voltages first. This will be dependent on which PMIC is in use
  195. * and in some cases we may not be scaling things up at all and thus not
  196. * need to do anything here.
  197. */
  198. __weak void scale_vcores(void)
  199. {
  200. }
  201. void setup_early_clocks(void)
  202. {
  203. setup_clocks_for_console();
  204. enable_basic_clocks();
  205. timer_init();
  206. }
  207. void prcm_init(void)
  208. {
  209. scale_vcores();
  210. setup_dplls();
  211. }
  212. void rtc_only_prcm_init(void)
  213. {
  214. const struct dpll_params *params;
  215. rtc_only_enable_basic_clocks();
  216. params = get_dpll_ddr_params();
  217. do_setup_dpll(&dpll_ddr_regs, params);
  218. }