]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
8281c58f MH |
2 | /* |
3 | * Copyright 2015 Freescale Semiconductor, Inc. | |
0dd74ec2 | 4 | * Copyright 2019 NXP. |
8281c58f MH |
5 | */ |
6 | ||
d678a59d | 7 | #include <common.h> |
d96c2604 | 8 | #include <clock_legacy.h> |
b5981474 | 9 | #include <cpu_func.h> |
401d1c4f | 10 | #include <asm/global_data.h> |
8281c58f MH |
11 | #include <linux/compiler.h> |
12 | #include <asm/io.h> | |
13 | #include <asm/processor.h> | |
14 | #include <asm/arch/clock.h> | |
15 | #include <asm/arch/soc.h> | |
16 | #include <fsl_ifc.h> | |
f3acaf43 | 17 | #include "cpu.h" |
8281c58f MH |
18 | |
19 | DECLARE_GLOBAL_DATA_PTR; | |
20 | ||
8281c58f MH |
21 | void get_sys_info(struct sys_info *sys_info) |
22 | { | |
6cc04547 | 23 | struct ccsr_gur __iomem *gur = (void *)(CFG_SYS_FSL_GUTS_ADDR); |
24cb6f22 YZ |
24 | /* rcw_tmp is needed to get FMAN clock, or to get cluster group A |
25 | * mux 2 clock for LS1043A/LS1046A. | |
26 | */ | |
2db82bf2 | 27 | __maybe_unused u32 rcw_tmp; |
6cc04547 | 28 | struct ccsr_clk *clk = (void *)(CFG_SYS_FSL_CLK_ADDR); |
8281c58f MH |
29 | unsigned int cpu; |
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 */ | |
35 | }; | |
36 | ||
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 */ | |
42 | }; | |
43 | ||
f3acaf43 | 44 | uint i, cluster; |
8281c58f MH |
45 | uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS]; |
46 | uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS]; | |
2f8a6db5 | 47 | unsigned long sysclk = get_board_sys_clk(); |
904110c7 | 48 | unsigned long cluster_clk; |
8281c58f MH |
49 | |
50 | sys_info->freq_systembus = sysclk; | |
80c75ce0 | 51 | #ifdef CONFIG_CLUSTER_CLK_FREQ |
904110c7 | 52 | cluster_clk = CONFIG_CLUSTER_CLK_FREQ; |
80c75ce0 TR |
53 | #else |
54 | cluster_clk = get_board_sys_clk(); | |
55 | #endif | |
904110c7 | 56 | |
efb5dab7 TR |
57 | #if defined(CONFIG_DYNAMIC_DDR_CLK_FREQ) || defined(CONFIG_STATIC_DDR_CLK_FREQ) |
58 | sys_info->freq_ddrbus = get_board_ddr_clk(); | |
8281c58f MH |
59 | #else |
60 | sys_info->freq_ddrbus = sysclk; | |
61 | #endif | |
62 | ||
904110c7 | 63 | /* The freq_systembus is used to record frequency of platform PLL */ |
8281c58f MH |
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; | |
904110c7 HZ |
67 | |
68 | #ifdef CONFIG_ARCH_LS1012A | |
69 | sys_info->freq_ddrbus = 2 * sys_info->freq_systembus; | |
70 | #else | |
8281c58f MH |
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; | |
b7f2bbff | 74 | #endif |
8281c58f MH |
75 | |
76 | for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) { | |
77 | ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff; | |
78 | if (ratio[i] > 4) | |
904110c7 | 79 | freq_c_pll[i] = cluster_clk * ratio[i]; |
8281c58f MH |
80 | else |
81 | freq_c_pll[i] = sys_info->freq_systembus * ratio[i]; | |
82 | } | |
83 | ||
f3acaf43 HZ |
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) | |
8281c58f MH |
87 | & 0xf; |
88 | u32 cplx_pll = core_cplx_pll[c_pll_sel]; | |
89 | ||
90 | sys_info->freq_processor[cpu] = | |
91 | freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; | |
92 | } | |
93 | ||
94 | #define HWA_CGA_M1_CLK_SEL 0xe0000000 | |
95 | #define HWA_CGA_M1_CLK_SHIFT 29 | |
2db82bf2 | 96 | #if defined(CONFIG_SYS_DPAA_FMAN) && !defined(CONFIG_SPL_BUILD) |
e8297341 SX |
97 | rcw_tmp = in_be32(&gur->rcwsr[7]); |
98 | switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) { | |
99 | case 2: | |
100 | sys_info->freq_fman[0] = freq_c_pll[0] / 2; | |
101 | break; | |
102 | case 3: | |
103 | sys_info->freq_fman[0] = freq_c_pll[0] / 3; | |
104 | break; | |
b528b937 MH |
105 | case 4: |
106 | sys_info->freq_fman[0] = freq_c_pll[0] / 4; | |
107 | break; | |
108 | case 5: | |
109 | sys_info->freq_fman[0] = sys_info->freq_systembus; | |
110 | break; | |
e8297341 SX |
111 | case 6: |
112 | sys_info->freq_fman[0] = freq_c_pll[1] / 2; | |
113 | break; | |
114 | case 7: | |
115 | sys_info->freq_fman[0] = freq_c_pll[1] / 3; | |
116 | break; | |
117 | default: | |
118 | printf("Error: Unknown FMan1 clock select!\n"); | |
119 | break; | |
120 | } | |
121 | #endif | |
8281c58f MH |
122 | |
123 | #define HWA_CGA_M2_CLK_SEL 0x00000007 | |
124 | #define HWA_CGA_M2_CLK_SHIFT 0 | |
bcb3dae3 | 125 | #if defined(CONFIG_ARCH_LS1046A) || defined(CONFIG_ARCH_LS1043A) |
8ef0d5c4 | 126 | rcw_tmp = in_be32(&gur->rcwsr[15]); |
b528b937 MH |
127 | switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) { |
128 | case 1: | |
24cb6f22 | 129 | sys_info->freq_cga_m2 = freq_c_pll[1]; |
b528b937 | 130 | break; |
bcb3dae3 | 131 | #if defined(CONFIG_ARCH_LS1046A) |
b528b937 | 132 | case 2: |
24cb6f22 | 133 | sys_info->freq_cga_m2 = freq_c_pll[1] / 2; |
b528b937 | 134 | break; |
24cb6f22 | 135 | #endif |
b528b937 | 136 | case 3: |
24cb6f22 | 137 | sys_info->freq_cga_m2 = freq_c_pll[1] / 3; |
b528b937 | 138 | break; |
bcb3dae3 | 139 | #if defined(CONFIG_ARCH_LS1046A) |
b528b937 | 140 | case 6: |
24cb6f22 | 141 | sys_info->freq_cga_m2 = freq_c_pll[0] / 2; |
b528b937 | 142 | break; |
24cb6f22 | 143 | #endif |
b528b937 | 144 | default: |
f1bce084 | 145 | printf("Error: Unknown cluster group A mux 2 clock select!\n"); |
b528b937 MH |
146 | break; |
147 | } | |
e477f4bd | 148 | #endif |
8281c58f MH |
149 | |
150 | #if defined(CONFIG_FSL_IFC) | |
8e63ed51 PK |
151 | sys_info->freq_localbus = sys_info->freq_systembus / |
152 | CONFIG_SYS_FSL_IFC_CLK_DIV; | |
8281c58f | 153 | #endif |
44262327 | 154 | #ifdef CONFIG_SYS_DPAA_QBMAN |
945fad57 HZ |
155 | sys_info->freq_qman = (sys_info->freq_systembus / |
156 | CONFIG_SYS_FSL_PCLK_DIV) / | |
157 | CONFIG_SYS_FSL_QMAN_CLK_DIV; | |
44262327 | 158 | #endif |
8281c58f MH |
159 | } |
160 | ||
44262327 AM |
161 | #ifdef CONFIG_SYS_DPAA_QBMAN |
162 | unsigned long get_qman_freq(void) | |
163 | { | |
164 | struct sys_info sys_info; | |
165 | ||
166 | get_sys_info(&sys_info); | |
167 | ||
168 | return sys_info.freq_qman; | |
169 | } | |
170 | #endif | |
171 | ||
8281c58f MH |
172 | int get_clocks(void) |
173 | { | |
174 | struct sys_info sys_info; | |
f1bce084 YL |
175 | #ifdef CONFIG_FSL_ESDHC |
176 | u32 clock = 0; | |
177 | #endif | |
8281c58f MH |
178 | get_sys_info(&sys_info); |
179 | gd->cpu_clk = sys_info.freq_processor[0]; | |
904110c7 | 180 | gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV; |
8281c58f | 181 | gd->mem_clk = sys_info.freq_ddrbus; |
8ef0d5c4 | 182 | #ifdef CONFIG_FSL_ESDHC |
f1bce084 YL |
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; | |
24cb6f22 | 187 | #endif |
f1bce084 YL |
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; | |
8ef0d5c4 | 190 | #endif |
8281c58f MH |
191 | if (gd->cpu_clk != 0) |
192 | return 0; | |
193 | else | |
194 | return 1; | |
195 | } | |
196 | ||
904110c7 HZ |
197 | /******************************************** |
198 | * get_bus_freq | |
199 | * return platform clock in Hz | |
200 | *********************************************/ | |
8281c58f MH |
201 | ulong get_bus_freq(ulong dummy) |
202 | { | |
904110c7 HZ |
203 | if (!gd->bus_clk) |
204 | get_clocks(); | |
205 | ||
8281c58f MH |
206 | return gd->bus_clk; |
207 | } | |
208 | ||
209 | ulong get_ddr_freq(ulong dummy) | |
210 | { | |
904110c7 HZ |
211 | if (!gd->mem_clk) |
212 | get_clocks(); | |
213 | ||
8281c58f MH |
214 | return gd->mem_clk; |
215 | } | |
216 | ||
217 | int get_serial_clock(void) | |
218 | { | |
904110c7 HZ |
219 | return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV; |
220 | } | |
221 | ||
222 | int get_i2c_freq(ulong dummy) | |
223 | { | |
224 | return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV; | |
225 | } | |
226 | ||
227 | int get_dspi_freq(ulong dummy) | |
228 | { | |
229 | return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV; | |
8281c58f MH |
230 | } |
231 | ||
904110c7 HZ |
232 | #ifdef CONFIG_FSL_LPUART |
233 | int get_uart_freq(ulong dummy) | |
234 | { | |
235 | return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV; | |
236 | } | |
237 | #endif | |
238 | ||
8281c58f MH |
239 | unsigned int mxc_get_clock(enum mxc_clock clk) |
240 | { | |
241 | switch (clk) { | |
242 | case MXC_I2C_CLK: | |
904110c7 | 243 | return get_i2c_freq(0); |
8281c58f | 244 | case MXC_DSPI_CLK: |
904110c7 HZ |
245 | return get_dspi_freq(0); |
246 | #ifdef CONFIG_FSL_LPUART | |
8281c58f | 247 | case MXC_UART_CLK: |
904110c7 HZ |
248 | return get_uart_freq(0); |
249 | #endif | |
8281c58f MH |
250 | default: |
251 | printf("Unsupported clock\n"); | |
252 | } | |
253 | return 0; | |
254 | } |