ls1c_clock.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2017-09-06 勤为本 first version
  9. */
  10. #include "ls1c_regs.h"
  11. #include "ls1c_public.h"
  12. // 晶振的频率
  13. #define AHB_CLK (24000000)
  14. #define APB_CLK (AHB_CLK)
  15. // START_FREQ寄存器bits
  16. #define M_PLL_SHIFT (8)
  17. #define M_PLL (0xff << M_PLL_SHIFT) // PLL倍频系数的整数部分
  18. #define FRAC_N_SHIFT (16)
  19. #define FRAC_N (0xff << FRAC_N_SHIFT) // PLL倍频系数的小数部分
  20. #define DIV_SDRAM_SHIFT (0)
  21. #define DIV_SDRAM (0x3 << DIV_SDRAM_SHIFT)
  22. // CLK_DIV_PARAM寄存器bits
  23. #define DIV_PIX_EN (0x1 << 31)
  24. #define DIV_PIX (0x7f << 24)
  25. #define DIV_CAM_EN (0x1 << 23)
  26. #define DIV_CAM (0x7f << 16)
  27. #define DIV_CPU_EN (0x1 << 15)
  28. #define DIV_CPU (0x7f << 8)
  29. #define DIV_PIX_VALID (0x1 << 5)
  30. #define DIV_PIX_SEL (0x1 << 4)
  31. #define DIV_CAM_VALID (0x1 << 3)
  32. #define DIV_CAM_SEL (0x1 << 2)
  33. #define DIV_CPU_VALID (0x1 << 1)
  34. #define DIV_CPU_SEL (0x1 << 0)
  35. #define DIV_PIX_SHIFT (24)
  36. #define DIV_CAM_SHIFT (16)
  37. #define DIV_CPU_SHIFT (8)
  38. /*
  39. * 获取PLL频率
  40. * @ret PLL频率
  41. */
  42. unsigned long clk_get_pll_rate(void)
  43. {
  44. unsigned int ctrl;
  45. unsigned long pll_rate = 0;
  46. ctrl = reg_read_32((volatile unsigned int *)LS1C_START_FREQ);
  47. pll_rate = (((ctrl & M_PLL) >> M_PLL_SHIFT) + ((ctrl & FRAC_N) >> FRAC_N_SHIFT)) * APB_CLK / 4;
  48. return pll_rate;
  49. }
  50. /*
  51. * 获取CPU频率
  52. * @ret CPU频率
  53. */
  54. unsigned long clk_get_cpu_rate(void)
  55. {
  56. unsigned long pll_rate, cpu_rate;
  57. unsigned int ctrl;
  58. pll_rate = clk_get_pll_rate();
  59. ctrl = reg_read_32((volatile unsigned int *)LS1C_CLK_DIV_PARAM);
  60. // 选择时钟来源
  61. if (DIV_CPU_SEL & ctrl) // pll分频作为时钟信号
  62. {
  63. if (DIV_CPU_EN & ctrl)
  64. {
  65. cpu_rate = pll_rate / ((ctrl & DIV_CPU) >> DIV_CPU_SHIFT);
  66. }
  67. else
  68. {
  69. cpu_rate = pll_rate / 2;
  70. }
  71. }
  72. else // bypass模式,晶振作为时钟输入
  73. {
  74. cpu_rate = APB_CLK;
  75. }
  76. return cpu_rate;
  77. }
  78. /*
  79. * 获取DDR频率
  80. * @ret DDR频率
  81. */
  82. unsigned long clk_get_ddr_rate(void)
  83. {
  84. unsigned long cpu_rate = 0;
  85. unsigned long ddr_rate = 0;
  86. unsigned int ctrl;
  87. cpu_rate = clk_get_cpu_rate();
  88. ctrl = reg_read_32((volatile unsigned int *)LS1C_START_FREQ);
  89. ctrl = (ctrl & DIV_SDRAM) >> DIV_SDRAM_SHIFT;
  90. switch (ctrl)
  91. {
  92. case 0:
  93. ddr_rate = cpu_rate / 2;
  94. break;
  95. case 1:
  96. ddr_rate = cpu_rate / 4;
  97. break;
  98. case 2:
  99. case 3:
  100. ddr_rate = cpu_rate / 3;
  101. break;
  102. }
  103. return ddr_rate;
  104. }
  105. /*
  106. * 获取APB频率
  107. * @ret APB频率
  108. */
  109. unsigned long clk_get_apb_rate(void)
  110. {
  111. return clk_get_ddr_rate();
  112. }
  113. /*
  114. * 获取DC频率
  115. * @ret DC频率
  116. */
  117. unsigned long clk_get_dc_rate(void)
  118. {
  119. unsigned long pll_rate, dc_rate;
  120. unsigned int ctrl;
  121. pll_rate = clk_get_pll_rate();
  122. ctrl = reg_read_32((volatile unsigned int *)LS1C_CLK_DIV_PARAM);
  123. dc_rate = pll_rate / ((ctrl & DIV_PIX) >> DIV_PIX_SHIFT);
  124. return dc_rate;
  125. }