fsl_lsch2_speed.c 5.8 KB

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