ls1c_clock.c 3.3 KB

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