fsl_lsch2_speed.c 6.0 KB

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