fsl_lsch2_speed.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2015 Freescale Semiconductor, Inc.
  4. * Copyright 2019 NXP.
  5. */
  6. #include <common.h>
  7. #include <clock_legacy.h>
  8. #include <cpu_func.h>
  9. #include <linux/compiler.h>
  10. #include <asm/io.h>
  11. #include <asm/processor.h>
  12. #include <asm/arch/clock.h>
  13. #include <asm/arch/soc.h>
  14. #include <fsl_ifc.h>
  15. #include "cpu.h"
  16. DECLARE_GLOBAL_DATA_PTR;
  17. #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
  18. #define CONFIG_SYS_FSL_NUM_CC_PLLS 2
  19. #endif
  20. void get_sys_info(struct sys_info *sys_info)
  21. {
  22. struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  23. /* rcw_tmp is needed to get FMAN clock, or to get cluster group A
  24. * mux 2 clock for LS1043A/LS1046A.
  25. */
  26. #if defined(CONFIG_SYS_DPAA_FMAN) || \
  27. defined(CONFIG_TARGET_LS1046ARDB) || \
  28. defined(CONFIG_TARGET_LS1043ARDB)
  29. u32 rcw_tmp;
  30. #endif
  31. struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR);
  32. unsigned int cpu;
  33. const u8 core_cplx_pll[8] = {
  34. [0] = 0, /* CC1 PPL / 1 */
  35. [1] = 0, /* CC1 PPL / 2 */
  36. [4] = 1, /* CC2 PPL / 1 */
  37. [5] = 1, /* CC2 PPL / 2 */
  38. };
  39. const u8 core_cplx_pll_div[8] = {
  40. [0] = 1, /* CC1 PPL / 1 */
  41. [1] = 2, /* CC1 PPL / 2 */
  42. [4] = 1, /* CC2 PPL / 1 */
  43. [5] = 2, /* CC2 PPL / 2 */
  44. };
  45. uint i, cluster;
  46. uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
  47. uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
  48. unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
  49. unsigned long cluster_clk;
  50. sys_info->freq_systembus = sysclk;
  51. #ifndef CONFIG_CLUSTER_CLK_FREQ
  52. #define CONFIG_CLUSTER_CLK_FREQ CONFIG_SYS_CLK_FREQ
  53. #endif
  54. cluster_clk = CONFIG_CLUSTER_CLK_FREQ;
  55. #ifdef CONFIG_DDR_CLK_FREQ
  56. sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
  57. #else
  58. sys_info->freq_ddrbus = sysclk;
  59. #endif
  60. /* The freq_systembus is used to record frequency of platform PLL */
  61. sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
  62. FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) &
  63. FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
  64. #ifdef CONFIG_ARCH_LS1012A
  65. sys_info->freq_ddrbus = 2 * sys_info->freq_systembus;
  66. #else
  67. sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
  68. FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) &
  69. FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
  70. #endif
  71. for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
  72. ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff;
  73. if (ratio[i] > 4)
  74. freq_c_pll[i] = cluster_clk * ratio[i];
  75. else
  76. freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
  77. }
  78. for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
  79. cluster = fsl_qoriq_core_to_cluster(cpu);
  80. u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
  81. & 0xf;
  82. u32 cplx_pll = core_cplx_pll[c_pll_sel];
  83. sys_info->freq_processor[cpu] =
  84. freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
  85. }
  86. #define HWA_CGA_M1_CLK_SEL 0xe0000000
  87. #define HWA_CGA_M1_CLK_SHIFT 29
  88. #ifdef CONFIG_SYS_DPAA_FMAN
  89. rcw_tmp = in_be32(&gur->rcwsr[7]);
  90. switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) {
  91. case 2:
  92. sys_info->freq_fman[0] = freq_c_pll[0] / 2;
  93. break;
  94. case 3:
  95. sys_info->freq_fman[0] = freq_c_pll[0] / 3;
  96. break;
  97. case 4:
  98. sys_info->freq_fman[0] = freq_c_pll[0] / 4;
  99. break;
  100. case 5:
  101. sys_info->freq_fman[0] = sys_info->freq_systembus;
  102. break;
  103. case 6:
  104. sys_info->freq_fman[0] = freq_c_pll[1] / 2;
  105. break;
  106. case 7:
  107. sys_info->freq_fman[0] = freq_c_pll[1] / 3;
  108. break;
  109. default:
  110. printf("Error: Unknown FMan1 clock select!\n");
  111. break;
  112. }
  113. #endif
  114. #define HWA_CGA_M2_CLK_SEL 0x00000007
  115. #define HWA_CGA_M2_CLK_SHIFT 0
  116. #if defined(CONFIG_TARGET_LS1046ARDB) || defined(CONFIG_TARGET_LS1043ARDB)
  117. rcw_tmp = in_be32(&gur->rcwsr[15]);
  118. switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
  119. case 1:
  120. sys_info->freq_cga_m2 = freq_c_pll[1];
  121. break;
  122. #if defined(CONFIG_TARGET_LS1046ARDB)
  123. case 2:
  124. sys_info->freq_cga_m2 = freq_c_pll[1] / 2;
  125. break;
  126. #endif
  127. case 3:
  128. sys_info->freq_cga_m2 = freq_c_pll[1] / 3;
  129. break;
  130. #if defined(CONFIG_TARGET_LS1046ARDB)
  131. case 6:
  132. sys_info->freq_cga_m2 = freq_c_pll[0] / 2;
  133. break;
  134. #endif
  135. default:
  136. printf("Error: Unknown cluster group A mux 2 clock select!\n");
  137. break;
  138. }
  139. #endif
  140. #if defined(CONFIG_FSL_IFC)
  141. sys_info->freq_localbus = sys_info->freq_systembus /
  142. CONFIG_SYS_FSL_IFC_CLK_DIV;
  143. #endif
  144. #ifdef CONFIG_SYS_DPAA_QBMAN
  145. sys_info->freq_qman = (sys_info->freq_systembus /
  146. CONFIG_SYS_FSL_PCLK_DIV) /
  147. CONFIG_SYS_FSL_QMAN_CLK_DIV;
  148. #endif
  149. }
  150. #ifdef CONFIG_SYS_DPAA_QBMAN
  151. unsigned long get_qman_freq(void)
  152. {
  153. struct sys_info sys_info;
  154. get_sys_info(&sys_info);
  155. return sys_info.freq_qman;
  156. }
  157. #endif
  158. int get_clocks(void)
  159. {
  160. struct sys_info sys_info;
  161. #ifdef CONFIG_FSL_ESDHC
  162. u32 clock = 0;
  163. #endif
  164. get_sys_info(&sys_info);
  165. gd->cpu_clk = sys_info.freq_processor[0];
  166. gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
  167. gd->mem_clk = sys_info.freq_ddrbus;
  168. #ifdef CONFIG_FSL_ESDHC
  169. #if defined(CONFIG_ARCH_LS1012A)
  170. clock = sys_info.freq_systembus;
  171. #elif defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
  172. clock = sys_info.freq_cga_m2;
  173. #endif
  174. gd->arch.sdhc_per_clk = clock / CONFIG_SYS_FSL_SDHC_CLK_DIV;
  175. gd->arch.sdhc_clk = gd->bus_clk / CONFIG_SYS_FSL_SDHC_CLK_DIV;
  176. #endif
  177. if (gd->cpu_clk != 0)
  178. return 0;
  179. else
  180. return 1;
  181. }
  182. /********************************************
  183. * get_bus_freq
  184. * return platform clock in Hz
  185. *********************************************/
  186. ulong get_bus_freq(ulong dummy)
  187. {
  188. if (!gd->bus_clk)
  189. get_clocks();
  190. return gd->bus_clk;
  191. }
  192. ulong get_ddr_freq(ulong dummy)
  193. {
  194. if (!gd->mem_clk)
  195. get_clocks();
  196. return gd->mem_clk;
  197. }
  198. int get_serial_clock(void)
  199. {
  200. return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
  201. }
  202. int get_i2c_freq(ulong dummy)
  203. {
  204. return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
  205. }
  206. int get_dspi_freq(ulong dummy)
  207. {
  208. return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
  209. }
  210. #ifdef CONFIG_FSL_LPUART
  211. int get_uart_freq(ulong dummy)
  212. {
  213. return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
  214. }
  215. #endif
  216. unsigned int mxc_get_clock(enum mxc_clock clk)
  217. {
  218. switch (clk) {
  219. case MXC_I2C_CLK:
  220. return get_i2c_freq(0);
  221. case MXC_DSPI_CLK:
  222. return get_dspi_freq(0);
  223. #ifdef CONFIG_FSL_LPUART
  224. case MXC_UART_CLK:
  225. return get_uart_freq(0);
  226. #endif
  227. default:
  228. printf("Unsupported clock\n");
  229. }
  230. return 0;
  231. }