bsp_clock.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. * 2020-12-20 Lyons first version
  9. * 2021-06-24 RiceChen add spi and lcd clock config
  10. */
  11. #include "board.h"
  12. #include "fsl_clock.h"
  13. #define _K_GPT_LOAD_VALUE RT_UINT32_MAX
  14. /* only used by MCIMX6Y2.h */
  15. uint32_t *g_ccm_vbase = (uint32_t*)IMX6ULL_CCM_BASE;
  16. uint32_t *g_ccm_analog_vbase = (uint32_t*)IMX6ULL_CCM_ANALOGY_BASE;
  17. uint32_t *g_pmu_vbase = (uint32_t*)IMX6ULL_PMU_BASE;
  18. uint32_t g_usbphy1_base = IMX6ULL_USBPHY1_BASE;
  19. uint32_t g_usbphy2_base = IMX6ULL_USBPHY2_BASE;
  20. uint32_t g_usb1_base = IMX6ULL_USB1_BASE;
  21. uint32_t g_usb2_base = IMX6ULL_USB2_BASE;
  22. uint32_t g_usb_analog_base = IMX6ULL_USB_ANALOG_BASE;
  23. /* used by all files */
  24. uint32_t *g_iomuxc_vbase = (uint32_t*)IMX6ULL_IOMUXC_BASE;
  25. uint32_t *g_iomuxc_snvs_vbase = (uint32_t*)IMX6ULL_IOMUXC_SNVS_BASE;
  26. uint32_t *g_src_vbase = (uint32_t*)IMX6ULL_SRC_BASE;
  27. uint32_t *g_wdog1_vbase = (uint32_t*)IMX6ULL_WATCHDOG1_BASE;
  28. uint32_t *g_snvs_vbase = (uint32_t*)IMX6ULL_SNVS_BASE;
  29. _internal_rw uint32_t *_s_gpt1_vbase = (uint32_t*)IMX6ULL_GPT1_BASE;
  30. static void _clk_enable( CCM_Type *base )
  31. {
  32. base->CCGR0 = 0XFFFFFFFF;
  33. base->CCGR1 = 0XFFFFFFFF;
  34. base->CCGR2 = 0XFFFFFFFF;
  35. base->CCGR3 = 0XFFFFFFFF;
  36. base->CCGR4 = 0XFFFFFFFF;
  37. base->CCGR5 = 0XFFFFFFFF;
  38. base->CCGR6 = 0XFFFFFFFF;
  39. }
  40. void BOARD_BootClockRUN(void)
  41. {
  42. rt_uint32_t reg_value;
  43. /* Boot ROM did initialize the XTAL, here we only sets external XTAL OSC freq */
  44. CLOCK_SetXtalFreq(24000000U);
  45. CLOCK_SetRtcXtalFreq(32768U);
  46. /*
  47. * ARM_CLK from 'pll1_sw_clk', whitch from 'pll1_main_clk' or 'step_clk'
  48. * if edit 'pll1_main_clk', switch to 'step_clk' first
  49. */
  50. reg_value = CCM->CCSR;
  51. if (0 == (reg_value & CCM_CCSR_PLL1_SW_CLK_SEL_MASK)) //if sel 'pll1_main_clk'
  52. {
  53. reg_value &= ~CCM_CCSR_STEP_SEL_MASK;
  54. reg_value |= CCM_CCSR_STEP_SEL(0); //sel 'osc_clk(24M)'
  55. reg_value |= CCM_CCSR_PLL1_SW_CLK_SEL(1); //sel 'step_clk'
  56. CCM->CCSR = reg_value;
  57. }
  58. /*
  59. * set PLL1(ARM PLL) at 1056MHz
  60. * set ARM_CLK at 528MHz
  61. * PLL output frequency = Fref * DIV_SEL / 2
  62. * = 24M * DIV_SEL / 2 = 1056M
  63. */
  64. CCM_ANALOG->PLL_ARM = CCM_ANALOG_PLL_ARM_ENABLE(1)
  65. | CCM_ANALOG_PLL_ARM_DIV_SELECT(88);
  66. reg_value = CCM->CCSR;
  67. reg_value &= ~CCM_CCSR_PLL1_SW_CLK_SEL_MASK;
  68. reg_value |= CCM_CCSR_PLL1_SW_CLK_SEL(0); //resel 'pll1_main_clk'
  69. CCM->CCSR = reg_value;
  70. CCM->CACRR = CCM_CACRR_ARM_PODF(1); //'CACRR[ARM_PODF]=0b001' divide by 2
  71. /*
  72. * set PLL2(System PLL) at fixed 528MHz
  73. * PLL2_PFD0: 528M * 18 / FRAC
  74. * PLL2_PFD1: 528M * 18 / FRAC
  75. * PLL2_PFD2: 528M * 18 / FRAC
  76. * PLL2_PFD3: 528M * 18 / FRAC
  77. */
  78. reg_value = CCM_ANALOG->PFD_528;
  79. reg_value &= ~0x3F3F3F3F;
  80. reg_value |= CCM_ANALOG_PFD_528_SET_PFD0_FRAC(27); //27: 352MHz
  81. reg_value |= CCM_ANALOG_PFD_528_SET_PFD1_FRAC(16); //16: 594MHz
  82. reg_value |= CCM_ANALOG_PFD_528_SET_PFD2_FRAC(24); //24: 396MHz
  83. reg_value |= CCM_ANALOG_PFD_528_SET_PFD3_FRAC(32); //32: 297MHz
  84. CCM_ANALOG->PFD_528 = reg_value;
  85. /*
  86. * set PLL3(USB PLL) at fixed 480MHz
  87. * PLL3_PFD0: 480M * 18 / FRAC
  88. * PLL3_PFD1: 480M * 18 / FRAC
  89. * PLL3_PFD2: 480M * 18 / FRAC
  90. * PLL3_PFD3: 480M * 18 / FRAC
  91. */
  92. reg_value = CCM_ANALOG->PFD_480;
  93. reg_value &= ~0x3F3F3F3F;
  94. reg_value |= CCM_ANALOG_PFD_480_SET_PFD0_FRAC(12); //12: 720MHz
  95. reg_value |= CCM_ANALOG_PFD_480_SET_PFD1_FRAC(16); //16: 540MHz
  96. reg_value |= CCM_ANALOG_PFD_480_SET_PFD2_FRAC(17); //17: 508.24MHz
  97. reg_value |= CCM_ANALOG_PFD_480_SET_PFD3_FRAC(19); //19: 457.74MHz
  98. CCM_ANALOG->PFD_480 = reg_value;
  99. /*
  100. * set PERCLK_CLK at 66MHz from IPG_CLK
  101. */
  102. reg_value = CCM->CSCMR1;
  103. reg_value &= ~CCM_CSCMR1_PERCLK_CLK_SEL_MASK;
  104. reg_value |= CCM_CSCMR1_PERCLK_CLK_SEL(0); //sel IPG_CLK
  105. reg_value &= ~CCM_CSCMR1_PERCLK_PODF_MASK;
  106. reg_value |= CCM_CSCMR1_PERCLK_PODF(0); //'CSCMR1[PERCLK_PODF]=0b000000' divide by 1
  107. CCM->CSCMR1 = reg_value;
  108. CLOCK_DeinitAudioPll();
  109. CLOCK_DeinitVideoPll();
  110. CLOCK_DeinitEnetPll();
  111. /* Configure UART divider to default */
  112. CLOCK_SetMux(kCLOCK_UartMux, 0); /* Set UART source to PLL3 80M */
  113. CLOCK_SetDiv(kCLOCK_UartDiv, 0); /* Set UART divider to 1 */
  114. /* Configure ECSPI divider to default */
  115. CLOCK_SetMux(kCLOCK_EcspiMux, 0); /* Set ECSPI source to PLL3 60M */
  116. CLOCK_SetDiv(kCLOCK_EcspiDiv, 0); /* Set ECSPI divider to 1 */
  117. /* Set LCDIF_PRED. */
  118. CLOCK_SetDiv(kCLOCK_Lcdif1PreDiv, 2);
  119. /* Set LCDIF_CLK_PODF. */
  120. CLOCK_SetDiv(kCLOCK_Lcdif1Div, 4);
  121. /* Set Lcdif pre clock source. */
  122. CLOCK_SetMux(kCLOCK_Lcdif1PreMux, 2);
  123. CLOCK_SetMux(kCLOCK_Lcdif1Mux, 0);
  124. }
  125. void BOARD_DelayInit(void)
  126. {
  127. GPT_Type *_GPT = (GPT_Type*)_s_gpt1_vbase;
  128. _GPT->CR = 0;
  129. _GPT->CR = GPT_CR_SWR(1);
  130. while (_GPT->CR & GPT_CR_SWR_MASK);
  131. /*
  132. * 000 No clock
  133. * 001 derive clock from ipg_clk
  134. * 010 derive clock from ipg_clk_highfreq
  135. * 011 derive clock from External Clock
  136. * 100 derive clock from ipg_clk_32k
  137. * 101 derive clock from ipg_clk_24M
  138. */
  139. _GPT->CR = GPT_CR_CLKSRC(0x1);
  140. _GPT->PR = GPT_PR_PRESCALER(65); //Set GPT1 Clock to 66MHz/66 = 1MHz
  141. _GPT->OCR[0] = GPT_OCR_COMP(_K_GPT_LOAD_VALUE);
  142. _GPT->CR |= GPT_CR_EN(1);
  143. }
  144. //execution before SystemClockInit called
  145. void SystemAddressMapping(void)
  146. {
  147. g_ccm_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_ccm_vbase);
  148. g_ccm_analog_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_ccm_analog_vbase);
  149. g_pmu_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_pmu_vbase);
  150. g_iomuxc_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_iomuxc_vbase);
  151. g_iomuxc_snvs_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_iomuxc_snvs_vbase);
  152. g_src_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_src_vbase);
  153. g_wdog1_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_wdog1_vbase);
  154. g_snvs_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)g_snvs_vbase);
  155. _s_gpt1_vbase = (uint32_t*)platform_get_periph_vaddr((rt_uint32_t)_s_gpt1_vbase);
  156. g_usbphy1_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usbphy1_base);
  157. g_usbphy2_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usbphy2_base);
  158. g_usb1_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usb1_base);
  159. g_usb2_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usb2_base);
  160. g_usb_analog_base = (uint32_t)platform_get_periph_vaddr((rt_uint32_t)g_usb_analog_base);
  161. }
  162. void SystemClockInit(void)
  163. {
  164. BOARD_BootClockRUN();
  165. BOARD_DelayInit();
  166. _clk_enable(CCM);
  167. }
  168. void rt_hw_us_delay(uint32_t us)
  169. {
  170. GPT_Type *_GPT = (GPT_Type*)_s_gpt1_vbase;
  171. rt_uint64_t old_cnt, new_cnt;
  172. rt_uint64_t total = 0;
  173. old_cnt = _GPT->CNT;
  174. while (1)
  175. {
  176. new_cnt = _GPT->CNT;
  177. if (old_cnt != new_cnt)
  178. {
  179. if (new_cnt > old_cnt)
  180. {
  181. total += (new_cnt - old_cnt);
  182. } else {
  183. total += (new_cnt + _K_GPT_LOAD_VALUE - old_cnt);
  184. }
  185. old_cnt = new_cnt;
  186. if (total >= us)
  187. break;
  188. }
  189. }
  190. }
  191. void rt_hw_ms_delay(uint32_t ms)
  192. {
  193. while (ms--)
  194. {
  195. rt_hw_us_delay(1000);
  196. }
  197. }