clock.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2014 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <asm/io.h>
  7. #include <asm/arch/immap_ls102xa.h>
  8. #include <asm/arch/clock.h>
  9. #include <fsl_ifc.h>
  10. DECLARE_GLOBAL_DATA_PTR;
  11. #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
  12. #define CONFIG_SYS_FSL_NUM_CC_PLLS 2
  13. #endif
  14. void get_sys_info(struct sys_info *sys_info)
  15. {
  16. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  17. struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR);
  18. unsigned int cpu;
  19. const u8 core_cplx_pll[6] = {
  20. [0] = 0, /* CC1 PPL / 1 */
  21. [1] = 0, /* CC1 PPL / 2 */
  22. [4] = 1, /* CC2 PPL / 1 */
  23. [5] = 1, /* CC2 PPL / 2 */
  24. };
  25. const u8 core_cplx_pll_div[6] = {
  26. [0] = 1, /* CC1 PPL / 1 */
  27. [1] = 2, /* CC1 PPL / 2 */
  28. [4] = 1, /* CC2 PPL / 1 */
  29. [5] = 2, /* CC2 PPL / 2 */
  30. };
  31. uint i;
  32. uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
  33. uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
  34. unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
  35. sys_info->freq_systembus = sysclk;
  36. #ifdef CONFIG_DDR_CLK_FREQ
  37. sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
  38. #else
  39. sys_info->freq_ddrbus = sysclk;
  40. #endif
  41. sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >>
  42. RCWSR0_SYS_PLL_RAT_SHIFT) & RCWSR0_SYS_PLL_RAT_MASK;
  43. sys_info->freq_ddrbus *= (in_be32(&gur->rcwsr[0]) >>
  44. RCWSR0_MEM_PLL_RAT_SHIFT) & RCWSR0_MEM_PLL_RAT_MASK;
  45. for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
  46. ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f;
  47. if (ratio[i] > 4)
  48. freq_c_pll[i] = sysclk * ratio[i];
  49. else
  50. freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
  51. }
  52. for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) {
  53. u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27)
  54. & 0xf;
  55. u32 cplx_pll = core_cplx_pll[c_pll_sel];
  56. sys_info->freq_processor[cpu] =
  57. freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
  58. }
  59. #if defined(CONFIG_FSL_IFC)
  60. sys_info->freq_localbus = sys_info->freq_systembus;
  61. #endif
  62. }
  63. int get_clocks(void)
  64. {
  65. struct sys_info sys_info;
  66. get_sys_info(&sys_info);
  67. gd->cpu_clk = sys_info.freq_processor[0];
  68. gd->bus_clk = sys_info.freq_systembus;
  69. gd->mem_clk = sys_info.freq_ddrbus * 2;
  70. #if defined(CONFIG_FSL_ESDHC)
  71. gd->arch.sdhc_clk = gd->bus_clk;
  72. #endif
  73. return 0;
  74. }
  75. ulong get_bus_freq(ulong dummy)
  76. {
  77. return gd->bus_clk;
  78. }
  79. ulong get_ddr_freq(ulong dummy)
  80. {
  81. return gd->mem_clk;
  82. }
  83. int get_serial_clock(void)
  84. {
  85. return gd->bus_clk / 2;
  86. }
  87. unsigned int mxc_get_clock(enum mxc_clock clk)
  88. {
  89. switch (clk) {
  90. case MXC_I2C_CLK:
  91. return get_bus_freq(0) / 2;
  92. case MXC_ESDHC_CLK:
  93. return get_bus_freq(0);
  94. case MXC_DSPI_CLK:
  95. return get_bus_freq(0) / 2;
  96. case MXC_UART_CLK:
  97. return get_bus_freq(0) / 2;
  98. default:
  99. printf("Unsupported clock\n");
  100. }
  101. return 0;
  102. }