xref: /openbmc/u-boot/arch/powerpc/cpu/mpc85xx/speed.c (revision 90101386)
1 /*
2  * Copyright 2004, 2007-2011 Freescale Semiconductor, Inc.
3  *
4  * (C) Copyright 2003 Motorola Inc.
5  * Xianghua Xiao, (X.Xiao@motorola.com)
6  *
7  * (C) Copyright 2000
8  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
9  *
10  * SPDX-License-Identifier:	GPL-2.0+
11  */
12 
13 #include <common.h>
14 #include <ppc_asm.tmpl>
15 #include <linux/compiler.h>
16 #include <asm/processor.h>
17 #include <asm/io.h>
18 
19 DECLARE_GLOBAL_DATA_PTR;
20 
21 
22 #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
23 #define CONFIG_SYS_FSL_NUM_CC_PLLS	6
24 #endif
25 /* --------------------------------------------------------------- */
26 
27 void get_sys_info(sys_info_t *sys_info)
28 {
29 	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
30 #ifdef CONFIG_FSL_IFC
31 	struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
32 	u32 ccr;
33 #endif
34 #ifdef CONFIG_FSL_CORENET
35 	volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR);
36 	unsigned int cpu;
37 #ifdef CONFIG_HETROGENOUS_CLUSTERS
38 	unsigned int dsp_cpu;
39 	uint rcw_tmp1, rcw_tmp2;
40 #endif
41 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
42 	int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS;
43 #endif
44 	__maybe_unused u32 svr;
45 
46 	const u8 core_cplx_PLL[16] = {
47 		[ 0] = 0,	/* CC1 PPL / 1 */
48 		[ 1] = 0,	/* CC1 PPL / 2 */
49 		[ 2] = 0,	/* CC1 PPL / 4 */
50 		[ 4] = 1,	/* CC2 PPL / 1 */
51 		[ 5] = 1,	/* CC2 PPL / 2 */
52 		[ 6] = 1,	/* CC2 PPL / 4 */
53 		[ 8] = 2,	/* CC3 PPL / 1 */
54 		[ 9] = 2,	/* CC3 PPL / 2 */
55 		[10] = 2,	/* CC3 PPL / 4 */
56 		[12] = 3,	/* CC4 PPL / 1 */
57 		[13] = 3,	/* CC4 PPL / 2 */
58 		[14] = 3,	/* CC4 PPL / 4 */
59 	};
60 
61 	const u8 core_cplx_pll_div[16] = {
62 		[ 0] = 1,	/* CC1 PPL / 1 */
63 		[ 1] = 2,	/* CC1 PPL / 2 */
64 		[ 2] = 4,	/* CC1 PPL / 4 */
65 		[ 4] = 1,	/* CC2 PPL / 1 */
66 		[ 5] = 2,	/* CC2 PPL / 2 */
67 		[ 6] = 4,	/* CC2 PPL / 4 */
68 		[ 8] = 1,	/* CC3 PPL / 1 */
69 		[ 9] = 2,	/* CC3 PPL / 2 */
70 		[10] = 4,	/* CC3 PPL / 4 */
71 		[12] = 1,	/* CC4 PPL / 1 */
72 		[13] = 2,	/* CC4 PPL / 2 */
73 		[14] = 4,	/* CC4 PPL / 4 */
74 	};
75 	uint i, freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
76 #if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV) || \
77 	defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)
78 	uint rcw_tmp;
79 #endif
80 	uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
81 	unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
82 	uint mem_pll_rat;
83 
84 	sys_info->freq_systembus = sysclk;
85 #ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
86 	uint ddr_refclk_sel;
87 	unsigned int porsr1_sys_clk;
88 	porsr1_sys_clk = in_be32(&gur->porsr1) >> FSL_DCFG_PORSR1_SYSCLK_SHIFT
89 						& FSL_DCFG_PORSR1_SYSCLK_MASK;
90 	if (porsr1_sys_clk == FSL_DCFG_PORSR1_SYSCLK_DIFF)
91 		sys_info->diff_sysclk = 1;
92 	else
93 		sys_info->diff_sysclk = 0;
94 
95 	/*
96 	 * DDR_REFCLK_SEL rcw bit is used to determine if DDR PLLS
97 	 * are driven by separate DDR Refclock or single source
98 	 * differential clock.
99 	 */
100 	ddr_refclk_sel = (in_be32(&gur->rcwsr[5]) >>
101 		      FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT) &
102 		      FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK;
103 	/*
104 	 * For single source clocking, both ddrclock and sysclock
105 	 * are driven by differential sysclock.
106 	 */
107 	if (ddr_refclk_sel == FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK)
108 		sys_info->freq_ddrbus = CONFIG_SYS_CLK_FREQ;
109 	else
110 #endif
111 #ifdef CONFIG_DDR_CLK_FREQ
112 		sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
113 #else
114 		sys_info->freq_ddrbus = sysclk;
115 #endif
116 
117 	sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f;
118 	mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
119 			FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT)
120 			& FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
121 #ifdef CONFIG_SYS_FSL_ERRATUM_A007212
122 	if (mem_pll_rat == 0) {
123 		mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
124 			FSL_CORENET_RCWSR0_MEM_PLL_RAT_RESV_SHIFT) &
125 			FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
126 	}
127 #endif
128 	/* T4240/T4160 Rev2.0 MEM_PLL_RAT uses a value which is half of
129 	 * T4240/T4160 Rev1.0. eg. It's 12 in Rev1.0, however, for Rev2.0
130 	 * it uses 6.
131 	 * T2080 rev 1.1 and later also use half mem_pll comparing with rev 1.0
132 	 */
133 #if defined(CONFIG_ARCH_T4240) || defined(CONFIG_ARCH_T4160) || \
134 	defined(CONFIG_ARCH_T2080) || defined(CONFIG_ARCH_T2081)
135 	svr = get_svr();
136 	switch (SVR_SOC_VER(svr)) {
137 	case SVR_T4240:
138 	case SVR_T4160:
139 	case SVR_T4120:
140 	case SVR_T4080:
141 		if (SVR_MAJ(svr) >= 2)
142 			mem_pll_rat *= 2;
143 		break;
144 	case SVR_T2080:
145 	case SVR_T2081:
146 		if ((SVR_MAJ(svr) > 1) || (SVR_MIN(svr) >= 1))
147 			mem_pll_rat *= 2;
148 		break;
149 	default:
150 		break;
151 	}
152 #endif
153 	if (mem_pll_rat > 2)
154 		sys_info->freq_ddrbus *= mem_pll_rat;
155 	else
156 		sys_info->freq_ddrbus = sys_info->freq_systembus * mem_pll_rat;
157 
158 	for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
159 		ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f;
160 		if (ratio[i] > 4)
161 			freq_c_pll[i] = sysclk * ratio[i];
162 		else
163 			freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
164 	}
165 
166 #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
167 	/*
168 	 * As per CHASSIS2 architeture total 12 clusters are posible and
169 	 * Each cluster has up to 4 cores, sharing the same PLL selection.
170 	 * The cluster clock assignment is SoC defined.
171 	 *
172 	 * Total 4 clock groups are possible with 3 PLLs each.
173 	 * as per array indices, clock group A has 0, 1, 2 numbered PLLs &
174 	 * clock group B has 3, 4, 6 and so on.
175 	 *
176 	 * Clock group A having PLL1, PLL2, PLL3, feeding cores of any cluster
177 	 * depends upon the SoC architeture. Same applies to other
178 	 * clock groups and clusters.
179 	 *
180 	 */
181 	for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
182 		int cluster = fsl_qoriq_core_to_cluster(cpu);
183 		u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
184 				& 0xf;
185 		u32 cplx_pll = core_cplx_PLL[c_pll_sel];
186 		cplx_pll += cc_group[cluster] - 1;
187 		sys_info->freq_processor[cpu] =
188 			 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
189 	}
190 
191 #ifdef CONFIG_HETROGENOUS_CLUSTERS
192 	for_each_cpu(i, dsp_cpu, cpu_num_dspcores(), cpu_dsp_mask()) {
193 		int dsp_cluster = fsl_qoriq_dsp_core_to_cluster(dsp_cpu);
194 		u32 c_pll_sel = (in_be32
195 				(&clk->clkcsr[dsp_cluster].clkcncsr) >> 27)
196 				& 0xf;
197 		u32 cplx_pll = core_cplx_PLL[c_pll_sel];
198 		cplx_pll += cc_group[dsp_cluster] - 1;
199 		sys_info->freq_processor_dsp[dsp_cpu] =
200 			 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
201 	}
202 #endif
203 
204 #if defined(CONFIG_ARCH_B4860) || defined(CONFIG_ARCH_B4420) || \
205 	defined(CONFIG_ARCH_T2080) || defined(CONFIG_ARCH_T2081)
206 #define FM1_CLK_SEL	0xe0000000
207 #define FM1_CLK_SHIFT	29
208 #elif defined(CONFIG_ARCH_T1024) || defined(CONFIG_ARCH_T1023)
209 #define FM1_CLK_SEL	0x00000007
210 #define FM1_CLK_SHIFT	0
211 #else
212 #define PME_CLK_SEL	0xe0000000
213 #define PME_CLK_SHIFT	29
214 #define FM1_CLK_SEL	0x1c000000
215 #define FM1_CLK_SHIFT	26
216 #endif
217 #if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV)
218 #if defined(CONFIG_ARCH_T1024) || defined(CONFIG_ARCH_T1023)
219 	rcw_tmp = in_be32(&gur->rcwsr[15]) - 4;
220 #else
221 	rcw_tmp = in_be32(&gur->rcwsr[7]);
222 #endif
223 #endif
224 
225 #ifdef CONFIG_SYS_DPAA_PME
226 #ifndef CONFIG_PME_PLAT_CLK_DIV
227 	switch ((rcw_tmp & PME_CLK_SEL) >> PME_CLK_SHIFT) {
228 	case 1:
229 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK];
230 		break;
231 	case 2:
232 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 2;
233 		break;
234 	case 3:
235 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 3;
236 		break;
237 	case 4:
238 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 4;
239 		break;
240 	case 6:
241 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK + 1] / 2;
242 		break;
243 	case 7:
244 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK + 1] / 3;
245 		break;
246 	default:
247 		printf("Error: Unknown PME clock select!\n");
248 	case 0:
249 		sys_info->freq_pme = sys_info->freq_systembus / 2;
250 		break;
251 
252 	}
253 #else
254 	sys_info->freq_pme = sys_info->freq_systembus / CONFIG_SYS_PME_CLK;
255 
256 #endif
257 #endif
258 
259 #ifdef CONFIG_SYS_DPAA_QBMAN
260 #ifndef CONFIG_QBMAN_CLK_DIV
261 #define CONFIG_QBMAN_CLK_DIV	2
262 #endif
263 	sys_info->freq_qman = sys_info->freq_systembus / CONFIG_QBMAN_CLK_DIV;
264 #endif
265 
266 #if defined(CONFIG_SYS_MAPLE)
267 #define CPRI_CLK_SEL		0x1C000000
268 #define CPRI_CLK_SHIFT		26
269 #define CPRI_ALT_CLK_SEL	0x00007000
270 #define CPRI_ALT_CLK_SHIFT	12
271 
272 	rcw_tmp1 = in_be32(&gur->rcwsr[7]);	/* Reading RCW bits: 224-255*/
273 	rcw_tmp2 = in_be32(&gur->rcwsr[15]);	/* Reading RCW bits: 480-511*/
274 	/* For MAPLE and CPRI frequency */
275 	switch ((rcw_tmp1 & CPRI_CLK_SEL) >> CPRI_CLK_SHIFT) {
276 	case 1:
277 		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK];
278 		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK];
279 		break;
280 	case 2:
281 		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
282 		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
283 		break;
284 	case 3:
285 		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
286 		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
287 		break;
288 	case 4:
289 		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
290 		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
291 		break;
292 	case 5:
293 		if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
294 					>> CPRI_ALT_CLK_SHIFT) == 6) {
295 			sys_info->freq_maple =
296 				freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
297 			sys_info->freq_cpri =
298 				freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
299 		}
300 		if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
301 					>> CPRI_ALT_CLK_SHIFT) == 7) {
302 			sys_info->freq_maple =
303 				freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
304 			sys_info->freq_cpri =
305 				freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
306 		}
307 		break;
308 	case 6:
309 		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
310 		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
311 		break;
312 	case 7:
313 		sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
314 		sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
315 		break;
316 	default:
317 		printf("Error: Unknown MAPLE/CPRI clock select!\n");
318 	}
319 
320 	/* For MAPLE ULB and eTVPE frequencies */
321 #define ULB_CLK_SEL		0x00000038
322 #define ULB_CLK_SHIFT		3
323 #define ETVPE_CLK_SEL		0x00000007
324 #define ETVPE_CLK_SHIFT		0
325 
326 	switch ((rcw_tmp2 & ULB_CLK_SEL) >> ULB_CLK_SHIFT) {
327 	case 1:
328 		sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK];
329 		break;
330 	case 2:
331 		sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 2;
332 		break;
333 	case 3:
334 		sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 3;
335 		break;
336 	case 4:
337 		sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 4;
338 		break;
339 	case 5:
340 		sys_info->freq_maple_ulb = sys_info->freq_systembus;
341 		break;
342 	case 6:
343 		sys_info->freq_maple_ulb =
344 			freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 2;
345 		break;
346 	case 7:
347 		sys_info->freq_maple_ulb =
348 			freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 3;
349 		break;
350 	default:
351 		printf("Error: Unknown MAPLE ULB clock select!\n");
352 	}
353 
354 	switch ((rcw_tmp2 & ETVPE_CLK_SEL) >> ETVPE_CLK_SHIFT) {
355 	case 1:
356 		sys_info->freq_maple_etvpe = freq_c_pll[CONFIG_SYS_ETVPE_CLK];
357 		break;
358 	case 2:
359 		sys_info->freq_maple_etvpe =
360 			freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 2;
361 		break;
362 	case 3:
363 		sys_info->freq_maple_etvpe =
364 			freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 3;
365 		break;
366 	case 4:
367 		sys_info->freq_maple_etvpe =
368 			freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 4;
369 		break;
370 	case 5:
371 		sys_info->freq_maple_etvpe = sys_info->freq_systembus;
372 		break;
373 	case 6:
374 		sys_info->freq_maple_etvpe =
375 			freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 2;
376 		break;
377 	case 7:
378 		sys_info->freq_maple_etvpe =
379 			freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 3;
380 		break;
381 	default:
382 		printf("Error: Unknown MAPLE eTVPE clock select!\n");
383 	}
384 
385 #endif
386 
387 #ifdef CONFIG_SYS_DPAA_FMAN
388 #ifndef CONFIG_FM_PLAT_CLK_DIV
389 	switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) {
390 	case 1:
391 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK];
392 		break;
393 	case 2:
394 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 2;
395 		break;
396 	case 3:
397 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 3;
398 		break;
399 	case 4:
400 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 4;
401 		break;
402 	case 5:
403 		sys_info->freq_fman[0] = sys_info->freq_systembus;
404 		break;
405 	case 6:
406 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK + 1] / 2;
407 		break;
408 	case 7:
409 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK + 1] / 3;
410 		break;
411 	default:
412 		printf("Error: Unknown FMan1 clock select!\n");
413 	case 0:
414 		sys_info->freq_fman[0] = sys_info->freq_systembus / 2;
415 		break;
416 	}
417 #if (CONFIG_SYS_NUM_FMAN) == 2
418 #ifdef CONFIG_SYS_FM2_CLK
419 #define FM2_CLK_SEL	0x00000038
420 #define FM2_CLK_SHIFT	3
421 	rcw_tmp = in_be32(&gur->rcwsr[15]);
422 	switch ((rcw_tmp & FM2_CLK_SEL) >> FM2_CLK_SHIFT) {
423 	case 1:
424 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1];
425 		break;
426 	case 2:
427 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 2;
428 		break;
429 	case 3:
430 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 3;
431 		break;
432 	case 4:
433 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 4;
434 		break;
435 	case 5:
436 		sys_info->freq_fman[1] = sys_info->freq_systembus;
437 		break;
438 	case 6:
439 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 2;
440 		break;
441 	case 7:
442 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 3;
443 		break;
444 	default:
445 		printf("Error: Unknown FMan2 clock select!\n");
446 	case 0:
447 		sys_info->freq_fman[1] = sys_info->freq_systembus / 2;
448 		break;
449 	}
450 #endif
451 #endif	/* CONFIG_SYS_NUM_FMAN == 2 */
452 #else
453 	sys_info->freq_fman[0] = sys_info->freq_systembus / CONFIG_SYS_FM1_CLK;
454 #endif
455 #endif
456 
457 #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
458 #if defined(CONFIG_ARCH_T2080)
459 #define ESDHC_CLK_SEL	0x00000007
460 #define ESDHC_CLK_SHIFT	0
461 #define ESDHC_CLK_RCWSR	15
462 #else	/* Support T1040 T1024 by now */
463 #define ESDHC_CLK_SEL	0xe0000000
464 #define ESDHC_CLK_SHIFT	29
465 #define ESDHC_CLK_RCWSR	7
466 #endif
467 	rcw_tmp = in_be32(&gur->rcwsr[ESDHC_CLK_RCWSR]);
468 	switch ((rcw_tmp & ESDHC_CLK_SEL) >> ESDHC_CLK_SHIFT) {
469 	case 1:
470 		sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK];
471 		break;
472 	case 2:
473 		sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 2;
474 		break;
475 	case 3:
476 		sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 3;
477 		break;
478 #if defined(CONFIG_SYS_SDHC_CLK_2_PLL)
479 	case 4:
480 		sys_info->freq_sdhc = freq_c_pll[CONFIG_SYS_SDHC_CLK] / 4;
481 		break;
482 #if defined(CONFIG_ARCH_T2080)
483 	case 5:
484 		sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK];
485 		break;
486 #endif
487 	case 6:
488 		sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK] / 2;
489 		break;
490 	case 7:
491 		sys_info->freq_sdhc = freq_c_pll[1 - CONFIG_SYS_SDHC_CLK] / 3;
492 		break;
493 #endif
494 	default:
495 		sys_info->freq_sdhc = 0;
496 		printf("Error: Unknown SDHC peripheral clock select!\n");
497 	}
498 #endif
499 #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
500 
501 	for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
502 		u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27)
503 				& 0xf;
504 		u32 cplx_pll = core_cplx_PLL[c_pll_sel];
505 
506 		sys_info->freq_processor[cpu] =
507 			 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
508 	}
509 #define PME_CLK_SEL	0x80000000
510 #define FM1_CLK_SEL	0x40000000
511 #define FM2_CLK_SEL	0x20000000
512 #define HWA_ASYNC_DIV	0x04000000
513 #if (CONFIG_SYS_FSL_NUM_CC_PLLS == 2)
514 #define HWA_CC_PLL	1
515 #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 3)
516 #define HWA_CC_PLL	2
517 #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 4)
518 #define HWA_CC_PLL	2
519 #else
520 #error CONFIG_SYS_FSL_NUM_CC_PLLS not set or unknown case
521 #endif
522 	rcw_tmp = in_be32(&gur->rcwsr[7]);
523 
524 #ifdef CONFIG_SYS_DPAA_PME
525 	if (rcw_tmp & PME_CLK_SEL) {
526 		if (rcw_tmp & HWA_ASYNC_DIV)
527 			sys_info->freq_pme = freq_c_pll[HWA_CC_PLL] / 4;
528 		else
529 			sys_info->freq_pme = freq_c_pll[HWA_CC_PLL] / 2;
530 	} else {
531 		sys_info->freq_pme = sys_info->freq_systembus / 2;
532 	}
533 #endif
534 
535 #ifdef CONFIG_SYS_DPAA_FMAN
536 	if (rcw_tmp & FM1_CLK_SEL) {
537 		if (rcw_tmp & HWA_ASYNC_DIV)
538 			sys_info->freq_fman[0] = freq_c_pll[HWA_CC_PLL] / 4;
539 		else
540 			sys_info->freq_fman[0] = freq_c_pll[HWA_CC_PLL] / 2;
541 	} else {
542 		sys_info->freq_fman[0] = sys_info->freq_systembus / 2;
543 	}
544 #if (CONFIG_SYS_NUM_FMAN) == 2
545 	if (rcw_tmp & FM2_CLK_SEL) {
546 		if (rcw_tmp & HWA_ASYNC_DIV)
547 			sys_info->freq_fman[1] = freq_c_pll[HWA_CC_PLL] / 4;
548 		else
549 			sys_info->freq_fman[1] = freq_c_pll[HWA_CC_PLL] / 2;
550 	} else {
551 		sys_info->freq_fman[1] = sys_info->freq_systembus / 2;
552 	}
553 #endif
554 #endif
555 
556 #ifdef CONFIG_SYS_DPAA_QBMAN
557 	sys_info->freq_qman = sys_info->freq_systembus / 2;
558 #endif
559 
560 #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
561 
562 #ifdef CONFIG_U_QE
563 	sys_info->freq_qe =  sys_info->freq_systembus / 2;
564 #endif
565 
566 #else /* CONFIG_FSL_CORENET */
567 	uint plat_ratio, e500_ratio, half_freq_systembus;
568 	int i;
569 #ifdef CONFIG_QE
570 	__maybe_unused u32 qe_ratio;
571 #endif
572 
573 	plat_ratio = (gur->porpllsr) & 0x0000003e;
574 	plat_ratio >>= 1;
575 	sys_info->freq_systembus = plat_ratio * CONFIG_SYS_CLK_FREQ;
576 
577 	/* Divide before multiply to avoid integer
578 	 * overflow for processor speeds above 2GHz */
579 	half_freq_systembus = sys_info->freq_systembus/2;
580 	for (i = 0; i < cpu_numcores(); i++) {
581 		e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f;
582 		sys_info->freq_processor[i] = e500_ratio * half_freq_systembus;
583 	}
584 
585 	/* Note: freq_ddrbus is the MCLK frequency, not the data rate. */
586 	sys_info->freq_ddrbus = sys_info->freq_systembus;
587 
588 #ifdef CONFIG_DDR_CLK_FREQ
589 	{
590 		u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO)
591 			>> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
592 		if (ddr_ratio != 0x7)
593 			sys_info->freq_ddrbus = ddr_ratio * CONFIG_DDR_CLK_FREQ;
594 	}
595 #endif
596 
597 #ifdef CONFIG_QE
598 #if defined(CONFIG_ARCH_P1021) || defined(CONFIG_ARCH_P1025)
599 	sys_info->freq_qe =  sys_info->freq_systembus;
600 #else
601 	qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO)
602 			>> MPC85xx_PORPLLSR_QE_RATIO_SHIFT;
603 	sys_info->freq_qe = qe_ratio * CONFIG_SYS_CLK_FREQ;
604 #endif
605 #endif
606 
607 #ifdef CONFIG_SYS_DPAA_FMAN
608 		sys_info->freq_fman[0] = sys_info->freq_systembus;
609 #endif
610 
611 #endif /* CONFIG_FSL_CORENET */
612 
613 #if defined(CONFIG_FSL_LBC)
614 	uint lcrr_div;
615 #if defined(CONFIG_SYS_LBC_LCRR)
616 	/* We will program LCRR to this value later */
617 	lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV;
618 #else
619 	lcrr_div = in_be32(&(LBC_BASE_ADDR)->lcrr) & LCRR_CLKDIV;
620 #endif
621 	if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) {
622 #if defined(CONFIG_FSL_CORENET)
623 		/* If this is corenet based SoC, bit-representation
624 		 * for four times the clock divider values.
625 		 */
626 		lcrr_div *= 4;
627 #elif !defined(CONFIG_ARCH_MPC8540) && !defined(CONFIG_ARCH_MPC8541) && \
628 	!defined(CONFIG_ARCH_MPC8555) && !defined(CONFIG_ARCH_MPC8560)
629 		/*
630 		 * Yes, the entire PQ38 family use the same
631 		 * bit-representation for twice the clock divider values.
632 		 */
633 		lcrr_div *= 2;
634 #endif
635 		sys_info->freq_localbus = sys_info->freq_systembus / lcrr_div;
636 	} else {
637 		/* In case anyone cares what the unknown value is */
638 		sys_info->freq_localbus = lcrr_div;
639 	}
640 #endif
641 
642 #if defined(CONFIG_FSL_IFC)
643 	ccr = ifc_in32(&ifc_regs.gregs->ifc_ccr);
644 	ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
645 
646 	sys_info->freq_localbus = sys_info->freq_systembus / ccr;
647 #endif
648 }
649 
650 
651 int get_clocks (void)
652 {
653 	sys_info_t sys_info;
654 #ifdef CONFIG_ARCH_MPC8544
655 	volatile ccsr_gur_t *gur = (void *) CONFIG_SYS_MPC85xx_GUTS_ADDR;
656 #endif
657 #if defined(CONFIG_CPM2)
658 	volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR;
659 	uint sccr, dfbrg;
660 
661 	/* set VCO = 4 * BRG */
662 	cpm->im_cpm_intctl.sccr &= 0xfffffffc;
663 	sccr = cpm->im_cpm_intctl.sccr;
664 	dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT;
665 #endif
666 	get_sys_info (&sys_info);
667 	gd->cpu_clk = sys_info.freq_processor[0];
668 	gd->bus_clk = sys_info.freq_systembus;
669 	gd->mem_clk = sys_info.freq_ddrbus;
670 	gd->arch.lbc_clk = sys_info.freq_localbus;
671 
672 #ifdef CONFIG_QE
673 	gd->arch.qe_clk = sys_info.freq_qe;
674 	gd->arch.brg_clk = gd->arch.qe_clk / 2;
675 #endif
676 	/*
677 	 * The base clock for I2C depends on the actual SOC.  Unfortunately,
678 	 * there is no pattern that can be used to determine the frequency, so
679 	 * the only choice is to look up the actual SOC number and use the value
680 	 * for that SOC. This information is taken from application note
681 	 * AN2919.
682 	 */
683 #if defined(CONFIG_ARCH_MPC8540) || defined(CONFIG_ARCH_MPC8541) || \
684 	defined(CONFIG_ARCH_MPC8560) || defined(CONFIG_ARCH_MPC8555) || \
685 	defined(CONFIG_ARCH_P1022)
686 	gd->arch.i2c1_clk = sys_info.freq_systembus;
687 #elif defined(CONFIG_ARCH_MPC8544)
688 	/*
689 	 * On the 8544, the I2C clock is the same as the SEC clock.  This can be
690 	 * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See
691 	 * 4.4.3.3 of the 8544 RM.  Note that this might actually work for all
692 	 * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the
693 	 * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544.
694 	 */
695 	if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG)
696 		gd->arch.i2c1_clk = sys_info.freq_systembus / 3;
697 	else
698 		gd->arch.i2c1_clk = sys_info.freq_systembus / 2;
699 #else
700 	/* Most 85xx SOCs use CCB/2, so this is the default behavior. */
701 	gd->arch.i2c1_clk = sys_info.freq_systembus / 2;
702 #endif
703 	gd->arch.i2c2_clk = gd->arch.i2c1_clk;
704 
705 #if defined(CONFIG_FSL_ESDHC)
706 #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
707 	gd->arch.sdhc_clk = sys_info.freq_sdhc / 2;
708 #else
709 #if defined(CONFIG_ARCH_MPC8569) || defined(CONFIG_ARCH_P1010)
710 	gd->arch.sdhc_clk = gd->bus_clk;
711 #else
712 	gd->arch.sdhc_clk = gd->bus_clk / 2;
713 #endif
714 #endif
715 #endif /* defined(CONFIG_FSL_ESDHC) */
716 
717 #if defined(CONFIG_CPM2)
718 	gd->arch.vco_out = 2*sys_info.freq_systembus;
719 	gd->arch.cpm_clk = gd->arch.vco_out / 2;
720 	gd->arch.scc_clk = gd->arch.vco_out / 4;
721 	gd->arch.brg_clk = gd->arch.vco_out / (1 << (2 * (dfbrg + 1)));
722 #endif
723 
724 	if(gd->cpu_clk != 0) return (0);
725 	else return (1);
726 }
727 
728 
729 /********************************************
730  * get_bus_freq
731  * return system bus freq in Hz
732  *********************************************/
733 ulong get_bus_freq (ulong dummy)
734 {
735 	return gd->bus_clk;
736 }
737 
738 /********************************************
739  * get_ddr_freq
740  * return ddr bus freq in Hz
741  *********************************************/
742 ulong get_ddr_freq (ulong dummy)
743 {
744 	return gd->mem_clk;
745 }
746