1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2015 Freescale Semiconductor, Inc.
8 #include <clock_legacy.h>
10 #include <asm/global_data.h>
11 #include <linux/compiler.h>
13 #include <asm/processor.h>
14 #include <asm/arch/clock.h>
15 #include <asm/arch/soc.h>
19 DECLARE_GLOBAL_DATA_PTR;
21 void get_sys_info(struct sys_info *sys_info)
23 struct ccsr_gur __iomem *gur = (void *)(CFG_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.
27 __maybe_unused u32 rcw_tmp;
28 struct ccsr_clk *clk = (void *)(CFG_SYS_FSL_CLK_ADDR);
30 const u8 core_cplx_pll[8] = {
31 [0] = 0, /* CC1 PPL / 1 */
32 [1] = 0, /* CC1 PPL / 2 */
33 [4] = 1, /* CC2 PPL / 1 */
34 [5] = 1, /* CC2 PPL / 2 */
37 const u8 core_cplx_pll_div[8] = {
38 [0] = 1, /* CC1 PPL / 1 */
39 [1] = 2, /* CC1 PPL / 2 */
40 [4] = 1, /* CC2 PPL / 1 */
41 [5] = 2, /* CC2 PPL / 2 */
45 uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
46 uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
47 unsigned long sysclk = get_board_sys_clk();
48 unsigned long cluster_clk;
50 sys_info->freq_systembus = sysclk;
51 #ifdef CONFIG_CLUSTER_CLK_FREQ
52 cluster_clk = CONFIG_CLUSTER_CLK_FREQ;
54 cluster_clk = get_board_sys_clk();
57 #if defined(CONFIG_DYNAMIC_DDR_CLK_FREQ) || defined(CONFIG_STATIC_DDR_CLK_FREQ)
58 sys_info->freq_ddrbus = get_board_ddr_clk();
60 sys_info->freq_ddrbus = sysclk;
63 /* The freq_systembus is used to record frequency of platform PLL */
64 sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
65 FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) &
66 FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
68 #ifdef CONFIG_ARCH_LS1012A
69 sys_info->freq_ddrbus = 2 * sys_info->freq_systembus;
71 sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
72 FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) &
73 FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
76 for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
77 ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff;
79 freq_c_pll[i] = cluster_clk * ratio[i];
81 freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
84 for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
85 cluster = fsl_qoriq_core_to_cluster(cpu);
86 u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
88 u32 cplx_pll = core_cplx_pll[c_pll_sel];
90 sys_info->freq_processor[cpu] =
91 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
94 #define HWA_CGA_M1_CLK_SEL 0xe0000000
95 #define HWA_CGA_M1_CLK_SHIFT 29
96 #if defined(CONFIG_SYS_DPAA_FMAN) && !defined(CONFIG_SPL_BUILD)
97 rcw_tmp = in_be32(&gur->rcwsr[7]);
98 switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) {
100 sys_info->freq_fman[0] = freq_c_pll[0] / 2;
103 sys_info->freq_fman[0] = freq_c_pll[0] / 3;
106 sys_info->freq_fman[0] = freq_c_pll[0] / 4;
109 sys_info->freq_fman[0] = sys_info->freq_systembus;
112 sys_info->freq_fman[0] = freq_c_pll[1] / 2;
115 sys_info->freq_fman[0] = freq_c_pll[1] / 3;
118 printf("Error: Unknown FMan1 clock select!\n");
123 #define HWA_CGA_M2_CLK_SEL 0x00000007
124 #define HWA_CGA_M2_CLK_SHIFT 0
125 #if defined(CONFIG_ARCH_LS1046A) || defined(CONFIG_ARCH_LS1043A)
126 rcw_tmp = in_be32(&gur->rcwsr[15]);
127 switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
129 sys_info->freq_cga_m2 = freq_c_pll[1];
131 #if defined(CONFIG_ARCH_LS1046A)
133 sys_info->freq_cga_m2 = freq_c_pll[1] / 2;
137 sys_info->freq_cga_m2 = freq_c_pll[1] / 3;
139 #if defined(CONFIG_ARCH_LS1046A)
141 sys_info->freq_cga_m2 = freq_c_pll[0] / 2;
145 printf("Error: Unknown cluster group A mux 2 clock select!\n");
150 #if defined(CONFIG_FSL_IFC)
151 sys_info->freq_localbus = sys_info->freq_systembus /
152 CONFIG_SYS_FSL_IFC_CLK_DIV;
154 #ifdef CONFIG_SYS_DPAA_QBMAN
155 sys_info->freq_qman = (sys_info->freq_systembus /
156 CONFIG_SYS_FSL_PCLK_DIV) /
157 CONFIG_SYS_FSL_QMAN_CLK_DIV;
161 #ifdef CONFIG_SYS_DPAA_QBMAN
162 unsigned long get_qman_freq(void)
164 struct sys_info sys_info;
166 get_sys_info(&sys_info);
168 return sys_info.freq_qman;
174 struct sys_info sys_info;
175 #ifdef CONFIG_FSL_ESDHC
178 get_sys_info(&sys_info);
179 gd->cpu_clk = sys_info.freq_processor[0];
180 gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
181 gd->mem_clk = sys_info.freq_ddrbus;
182 #ifdef CONFIG_FSL_ESDHC
183 #if defined(CONFIG_ARCH_LS1012A)
184 clock = sys_info.freq_systembus;
185 #elif defined(CONFIG_ARCH_LS1043A) || defined(CONFIG_ARCH_LS1046A)
186 clock = sys_info.freq_cga_m2;
188 gd->arch.sdhc_per_clk = clock / CONFIG_SYS_FSL_SDHC_CLK_DIV;
189 gd->arch.sdhc_clk = gd->bus_clk / CONFIG_SYS_FSL_SDHC_CLK_DIV;
191 if (gd->cpu_clk != 0)
197 /********************************************
199 * return platform clock in Hz
200 *********************************************/
201 ulong get_bus_freq(ulong dummy)
209 ulong get_ddr_freq(ulong dummy)
217 int get_serial_clock(void)
219 return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
222 int get_i2c_freq(ulong dummy)
224 return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
227 int get_dspi_freq(ulong dummy)
229 return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
232 #ifdef CONFIG_FSL_LPUART
233 int get_uart_freq(ulong dummy)
235 return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
239 unsigned int mxc_get_clock(enum mxc_clock clk)
243 return get_i2c_freq(0);
245 return get_dspi_freq(0);
246 #ifdef CONFIG_FSL_LPUART
248 return get_uart_freq(0);
251 printf("Unsupported clock\n");