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