1
0

system_clock.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2011-01-13 weety first version
  9. */
  10. #include <rtthread.h>
  11. #include "at91sam9g45.h"
  12. static rt_list_t clocks;
  13. struct clk {
  14. char name[32];
  15. rt_uint32_t rate_hz;
  16. struct clk *parent;
  17. rt_list_t node;
  18. };
  19. static struct clk clk32k = {
  20. "clk32k",
  21. AT91C_SLOW_CLOCK,
  22. RT_NULL,
  23. {RT_NULL, RT_NULL},
  24. };
  25. static struct clk main_clk = {
  26. "main",
  27. 0,
  28. RT_NULL,
  29. {RT_NULL, RT_NULL},
  30. };
  31. static struct clk plla = {
  32. "plla",
  33. 0,
  34. &main_clk,
  35. {RT_NULL, RT_NULL},
  36. };
  37. static struct clk mck = {
  38. "mck",
  39. 0,
  40. RT_NULL,
  41. {RT_NULL, RT_NULL},
  42. };
  43. static struct clk upllck = {
  44. "upllck",
  45. 480*1000*1000,
  46. &main_clk,
  47. {RT_NULL, RT_NULL},
  48. };
  49. static struct clk *const standard_pmc_clocks[] = {
  50. /* four primary clocks */
  51. &clk32k,
  52. &main_clk,
  53. &plla,
  54. /* MCK */
  55. &mck
  56. };
  57. /* clocks cannot be de-registered no refcounting necessary */
  58. struct clk *clk_get(const char *id)
  59. {
  60. struct clk *clk;
  61. rt_list_t *list;
  62. for (list = (&clocks)->next; list != &clocks; list = list->next)
  63. {
  64. clk = (struct clk *)rt_list_entry(list, struct clk, node);
  65. if (rt_strcmp(id, clk->name) == 0)
  66. return clk;
  67. }
  68. return RT_NULL;
  69. }
  70. rt_uint32_t clk_get_rate(struct clk *clk)
  71. {
  72. rt_uint32_t rate;
  73. for (;;) {
  74. rate = clk->rate_hz;
  75. if (rate || !clk->parent)
  76. break;
  77. clk = clk->parent;
  78. }
  79. return rate;
  80. }
  81. static void at91_upllck_init(rt_uint32_t main_clock)
  82. {
  83. // EHCI USB use fixed 480MHz clock
  84. }
  85. static struct clk *at91_css_to_clk(unsigned long css)
  86. {
  87. switch (css) {
  88. case AT91C_PMC_CSS_SLOW_CLK:
  89. return &clk32k;
  90. case AT91C_PMC_CSS_MAIN_CLK:
  91. return &main_clk;
  92. case AT91C_PMC_CSS_PLLA_CLK:
  93. return &plla;
  94. case AT91C_PMC_CSS_UPLL_CLK:
  95. return &upllck;
  96. }
  97. return RT_NULL;
  98. }
  99. // TODO: how to auto-set register value by OSC and MCK
  100. /* Settings at 400/133MHz */
  101. // In datasheet, ATMEL says 12MHz main crystal startup time less than 2ms, so we
  102. // configure OSC startup timeout to 64*8/32768=15.6ms, should enough
  103. #define BOARD_OSCOUNT (AT91C_CKGR_OSCOUNT & (64 << 8))
  104. // MAINCK => Divider(DIVA) => PLLA(MULA, OUTA) => /1/2 Divider(PLLADIV2) => PLLACK
  105. // pls. refer to doc6438G figure 24-6 on pg294. ICPLLA in reg PMC_PLLICPR
  106. // 12MHz / 3 * (199 + 1) = 800MHz
  107. // OUTA/ICPLLA can as ICPLLA:OUTA[1]:OUTA[0] = (800-PLLAOUT(MHz))/50
  108. // PLLACOUNT field occupy bit[13:8], max value is 0x3F, then about 19.2ms
  109. #define BOARD_CKGR_PLLA (AT91C_CKGR_SRCA | AT91C_CKGR_OUTA_0)
  110. #define BOARD_PLLACOUNT (0x3F << 8)
  111. #define BOARD_MULA (AT91C_CKGR_MULA & (199 << 16))
  112. #define BOARD_DIVA (AT91C_CKGR_DIVA & 3)
  113. // Clock Source => select(CCS) => Prescaler(PRES) => Master Clock Divider(MDIV) => MCK
  114. // => Processor Clock Divider => PCK
  115. // Master clock can refer to doc6438G figure 25-2 on pg298
  116. // PLLADIV2=1(div 2, 400MHz), PRES=0(no div, 400MHz),
  117. // MDIV=3(Master Clock divided by 3, 133MHz), CSS=0(still Slow Clock)
  118. #define BOARD_PRESCALER (0x00001300) //400/133MHz
  119. #define MHz(n) ((n) * 1000 * 1000)
  120. #define OSC_FREQ MHz(12)
  121. #define PLLA_FREQ MHz(800)
  122. static void at91_plla_init(void)
  123. {
  124. rt_uint32_t pllar, mckr;
  125. // Code refer to doc6438G, 25.10 Programming Sequence
  126. /* Initialize main oscillator
  127. ****************************/
  128. // enable main OSC and wait OSC startup time timeout.
  129. AT91C_BASE_PMC->PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN;
  130. while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));
  131. /* Initialize PLLA, Set PLL to 800MHz and wait PLL stable */
  132. pllar = (MHz(800) - PLLA_FREQ) / MHz(50); // please refer to Table 46-15 of doc 6438G
  133. AT91C_BASE_PMC->PMC_PLLICPR = (pllar >> 2) & 1; // ICPLLA
  134. pllar = (pllar & 3) << 14; // OUTA
  135. pllar |= BOARD_DIVA; // PLLA input clock as 4MHz
  136. pllar |= BOARD_MULA; // PLLA output clock as 800MHz
  137. pllar |= BOARD_PLLACOUNT;
  138. pllar |= AT91C_CKGR_SRCA; // I don't known what means, but seems must set it
  139. AT91C_BASE_PMC->PMC_PLLAR = pllar;
  140. while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA));
  141. /* Wait for the master clock if it was already initialized */
  142. // make sure Master clock in READY status before operate it
  143. while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
  144. /* Switch to fast clock
  145. **********************/
  146. /* setup main clock divisor and prescaler, 400MHz/133MHz, but don't switch */
  147. mckr = AT91C_BASE_PMC->PMC_MCKR;
  148. if ((mckr & AT91C_PMC_MDIV) != (BOARD_PRESCALER & AT91C_PMC_MDIV))
  149. {
  150. mckr = (mckr & ~(unsigned int)AT91C_PMC_MDIV) | (BOARD_PRESCALER & AT91C_PMC_MDIV);
  151. AT91C_BASE_PMC->PMC_MCKR = mckr;
  152. while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
  153. }
  154. /* Switch to PLL + prescaler, now Switch to PLLA as source, run on the fly */
  155. if ((mckr & AT91C_PMC_CSS) != AT91C_PMC_CSS_PLLA_CLK)
  156. {
  157. mckr = (mckr & ~(unsigned int)AT91C_PMC_CSS) | AT91C_PMC_CSS_PLLA_CLK;
  158. AT91C_BASE_PMC->PMC_MCKR = mckr;
  159. while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));
  160. }
  161. plla.rate_hz = PLLA_FREQ;
  162. }
  163. #define false 0
  164. #define true 1
  165. int at91_clock_init(rt_uint32_t main_clock)
  166. {
  167. unsigned tmp, freq, mckr, mdiv;
  168. int i;
  169. /*
  170. * When the bootloader initialized the main oscillator correctly,
  171. * there's no problem using the cycle counter. But if it didn't,
  172. * or when using oscillator bypass mode, we must be told the speed
  173. * of the main clock.
  174. */
  175. if (!main_clock) {
  176. do {
  177. tmp = readl(AT91C_CKGR_MCFR);
  178. } while (!(tmp & AT91C_CKGR_MAINRDY));
  179. main_clock = (tmp & AT91C_CKGR_MAINF) * (AT91C_SLOW_CLOCK / 16);
  180. }
  181. main_clk.rate_hz = main_clock;
  182. at91_plla_init();
  183. at91_upllck_init(main_clock);
  184. /*
  185. * MCK and CPU derive from one of those primary clocks.
  186. * For now, assume this parentage won't change.
  187. */
  188. mckr = readl(AT91C_PMC_MCKR);
  189. mck.parent = at91_css_to_clk(mckr & AT91C_PMC_CSS);
  190. freq = mck.parent->rate_hz;
  191. freq /= (1 << ((mckr & AT91C_PMC_PRES) >> 2)); /* prescale */
  192. mdiv = 1 << ((mckr & AT91C_PMC_MDIV) >> 8);
  193. if (mdiv == 8) mdiv = 3;
  194. freq /= mdiv; /* mdiv */
  195. if (mckr & AT91C_PMC_PLLADIV2) freq /= 2; /* plla_div2 */
  196. mck.rate_hz = freq;
  197. /* Register the PMC's standard clocks */
  198. rt_list_init(&clocks);
  199. for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
  200. rt_list_insert_after(&clocks, &standard_pmc_clocks[i]->node);
  201. rt_list_insert_after(&clocks, &upllck.node);
  202. /* MCK and CPU clock are "always on" */
  203. //clk_enable(&mck);
  204. /*rt_kprintf("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n",
  205. freq / 1000000, (unsigned) mck.rate_hz / 1000000,
  206. (unsigned) main_clock / 1000000,
  207. ((unsigned) main_clock % 1000000) / 1000);*///cause blocked
  208. return 0;
  209. }
  210. /**
  211. * @brief System Clock Configuration
  212. */
  213. void rt_hw_clock_init(void)
  214. {
  215. at91_clock_init(MHz(12));
  216. }