xref: /rk3399_rockchip-uboot/arch/powerpc/cpu/mpc85xx/speed.c (revision b33bd8cd4b7627f64698c6f26739e0c4597bdfbc)
1a47a12beSStefan Roese /*
2beba93edSDipen Dudhat  * Copyright 2004, 2007-2011 Freescale Semiconductor, Inc.
3a47a12beSStefan Roese  *
4a47a12beSStefan Roese  * (C) Copyright 2003 Motorola Inc.
5a47a12beSStefan Roese  * Xianghua Xiao, (X.Xiao@motorola.com)
6a47a12beSStefan Roese  *
7a47a12beSStefan Roese  * (C) Copyright 2000
8a47a12beSStefan Roese  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
9a47a12beSStefan Roese  *
101a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
11a47a12beSStefan Roese  */
12a47a12beSStefan Roese 
13a47a12beSStefan Roese #include <common.h>
14a47a12beSStefan Roese #include <ppc_asm.tmpl>
15a52d2f81SHaiying Wang #include <linux/compiler.h>
16a47a12beSStefan Roese #include <asm/processor.h>
17a47a12beSStefan Roese #include <asm/io.h>
18a47a12beSStefan Roese 
19a47a12beSStefan Roese DECLARE_GLOBAL_DATA_PTR;
20a47a12beSStefan Roese 
21ce746fe0SPrabhakar Kushwaha 
22ce746fe0SPrabhakar Kushwaha #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
23ce746fe0SPrabhakar Kushwaha #define CONFIG_SYS_FSL_NUM_CC_PLLS	6
24ce746fe0SPrabhakar Kushwaha #endif
25a47a12beSStefan Roese /* --------------------------------------------------------------- */
26a47a12beSStefan Roese 
27997399faSPrabhakar Kushwaha void get_sys_info(sys_info_t *sys_info)
28a47a12beSStefan Roese {
29a47a12beSStefan Roese 	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
30800c73c4SKumar Gala #ifdef CONFIG_FSL_IFC
31800c73c4SKumar Gala 	struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
32800c73c4SKumar Gala 	u32 ccr;
33800c73c4SKumar Gala #endif
34a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET
35a47a12beSStefan Roese 	volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR);
36fbb9ecf7STimur Tabi 	unsigned int cpu;
37ce746fe0SPrabhakar Kushwaha #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
38ce746fe0SPrabhakar Kushwaha 	int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS;
39ce746fe0SPrabhakar Kushwaha #endif
40a47a12beSStefan Roese 
41a47a12beSStefan Roese 	const u8 core_cplx_PLL[16] = {
42a47a12beSStefan Roese 		[ 0] = 0,	/* CC1 PPL / 1 */
43a47a12beSStefan Roese 		[ 1] = 0,	/* CC1 PPL / 2 */
44a47a12beSStefan Roese 		[ 2] = 0,	/* CC1 PPL / 4 */
45a47a12beSStefan Roese 		[ 4] = 1,	/* CC2 PPL / 1 */
46a47a12beSStefan Roese 		[ 5] = 1,	/* CC2 PPL / 2 */
47a47a12beSStefan Roese 		[ 6] = 1,	/* CC2 PPL / 4 */
48a47a12beSStefan Roese 		[ 8] = 2,	/* CC3 PPL / 1 */
49a47a12beSStefan Roese 		[ 9] = 2,	/* CC3 PPL / 2 */
50a47a12beSStefan Roese 		[10] = 2,	/* CC3 PPL / 4 */
51a47a12beSStefan Roese 		[12] = 3,	/* CC4 PPL / 1 */
52a47a12beSStefan Roese 		[13] = 3,	/* CC4 PPL / 2 */
53a47a12beSStefan Roese 		[14] = 3,	/* CC4 PPL / 4 */
54a47a12beSStefan Roese 	};
55a47a12beSStefan Roese 
56997399faSPrabhakar Kushwaha 	const u8 core_cplx_pll_div[16] = {
57a47a12beSStefan Roese 		[ 0] = 1,	/* CC1 PPL / 1 */
58a47a12beSStefan Roese 		[ 1] = 2,	/* CC1 PPL / 2 */
59a47a12beSStefan Roese 		[ 2] = 4,	/* CC1 PPL / 4 */
60a47a12beSStefan Roese 		[ 4] = 1,	/* CC2 PPL / 1 */
61a47a12beSStefan Roese 		[ 5] = 2,	/* CC2 PPL / 2 */
62a47a12beSStefan Roese 		[ 6] = 4,	/* CC2 PPL / 4 */
63a47a12beSStefan Roese 		[ 8] = 1,	/* CC3 PPL / 1 */
64a47a12beSStefan Roese 		[ 9] = 2,	/* CC3 PPL / 2 */
65a47a12beSStefan Roese 		[10] = 4,	/* CC3 PPL / 4 */
66a47a12beSStefan Roese 		[12] = 1,	/* CC4 PPL / 1 */
67a47a12beSStefan Roese 		[13] = 2,	/* CC4 PPL / 2 */
68a47a12beSStefan Roese 		[14] = 4,	/* CC4 PPL / 4 */
69a47a12beSStefan Roese 	};
70ce746fe0SPrabhakar Kushwaha 	uint i, freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
71ce746fe0SPrabhakar Kushwaha #if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV)
72ce746fe0SPrabhakar Kushwaha 	uint rcw_tmp;
73ce746fe0SPrabhakar Kushwaha #endif
74ce746fe0SPrabhakar Kushwaha 	uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
75a47a12beSStefan Roese 	unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
76ab48ca1aSSrikanth Srinivasan 	uint mem_pll_rat;
77a47a12beSStefan Roese 
78997399faSPrabhakar Kushwaha 	sys_info->freq_systembus = sysclk;
79b135991aSPriyanka Jain #ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
800c12a159Svijay rai 	uint ddr_refclk_sel;
810c12a159Svijay rai 	unsigned int porsr1_sys_clk;
820c12a159Svijay rai 	porsr1_sys_clk = in_be32(&gur->porsr1) >> FSL_DCFG_PORSR1_SYSCLK_SHIFT
830c12a159Svijay rai 						& FSL_DCFG_PORSR1_SYSCLK_MASK;
840c12a159Svijay rai 	if (porsr1_sys_clk == FSL_DCFG_PORSR1_SYSCLK_DIFF)
850c12a159Svijay rai 		sys_info->diff_sysclk = 1;
860c12a159Svijay rai 	else
870c12a159Svijay rai 		sys_info->diff_sysclk = 0;
880c12a159Svijay rai 
89b135991aSPriyanka Jain 	/*
90b135991aSPriyanka Jain 	 * DDR_REFCLK_SEL rcw bit is used to determine if DDR PLLS
91b135991aSPriyanka Jain 	 * are driven by separate DDR Refclock or single source
92b135991aSPriyanka Jain 	 * differential clock.
93b135991aSPriyanka Jain 	 */
940c12a159Svijay rai 	ddr_refclk_sel = (in_be32(&gur->rcwsr[5]) >>
95b135991aSPriyanka Jain 		      FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT) &
96b135991aSPriyanka Jain 		      FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK;
97b135991aSPriyanka Jain 	/*
980c12a159Svijay rai 	 * For single source clocking, both ddrclock and sysclock
99b135991aSPriyanka Jain 	 * are driven by differential sysclock.
100b135991aSPriyanka Jain 	 */
1010c12a159Svijay rai 	if (ddr_refclk_sel == FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK)
102b135991aSPriyanka Jain 		sys_info->freq_ddrbus = CONFIG_SYS_CLK_FREQ;
1030c12a159Svijay rai 	else
104b135991aSPriyanka Jain #endif
10598ffa190SYork Sun #ifdef CONFIG_DDR_CLK_FREQ
106997399faSPrabhakar Kushwaha 		sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
10798ffa190SYork Sun #else
108997399faSPrabhakar Kushwaha 		sys_info->freq_ddrbus = sysclk;
10998ffa190SYork Sun #endif
110a47a12beSStefan Roese 
111997399faSPrabhakar Kushwaha 	sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f;
112f77329cfSYork Sun 	mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
113f77329cfSYork Sun 			FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT)
114f77329cfSYork Sun 			& FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
115c3678b09SYork Sun #ifdef CONFIG_SYS_FSL_ERRATUM_A007212
116c3678b09SYork Sun 	if (mem_pll_rat == 0) {
117c3678b09SYork Sun 		mem_pll_rat = (in_be32(&gur->rcwsr[0]) >>
118c3678b09SYork Sun 			FSL_CORENET_RCWSR0_MEM_PLL_RAT_RESV_SHIFT) &
119c3678b09SYork Sun 			FSL_CORENET_RCWSR0_MEM_PLL_RAT_MASK;
120c3678b09SYork Sun 	}
121c3678b09SYork Sun #endif
122e88f421eSZang Roy-R61911 	/* T4240/T4160 Rev2.0 MEM_PLL_RAT uses a value which is half of
123e88f421eSZang Roy-R61911 	 * T4240/T4160 Rev1.0. eg. It's 12 in Rev1.0, however, for Rev2.0
124e88f421eSZang Roy-R61911 	 * it uses 6.
125e88f421eSZang Roy-R61911 	 */
126e88f421eSZang Roy-R61911 #if defined(CONFIG_PPC_T4240) || defined(CONFIG_PPC_T4160)
127e88f421eSZang Roy-R61911 	if (SVR_MAJ(get_svr()) >= 2)
128e88f421eSZang Roy-R61911 		mem_pll_rat *= 2;
129e88f421eSZang Roy-R61911 #endif
130ab48ca1aSSrikanth Srinivasan 	if (mem_pll_rat > 2)
131997399faSPrabhakar Kushwaha 		sys_info->freq_ddrbus *= mem_pll_rat;
132ab48ca1aSSrikanth Srinivasan 	else
133997399faSPrabhakar Kushwaha 		sys_info->freq_ddrbus = sys_info->freq_systembus * mem_pll_rat;
134a47a12beSStefan Roese 
135ce746fe0SPrabhakar Kushwaha 	for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
136ce746fe0SPrabhakar Kushwaha 		ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f;
137ab48ca1aSSrikanth Srinivasan 		if (ratio[i] > 4)
138ce746fe0SPrabhakar Kushwaha 			freq_c_pll[i] = sysclk * ratio[i];
139ab48ca1aSSrikanth Srinivasan 		else
140ce746fe0SPrabhakar Kushwaha 			freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
141ab48ca1aSSrikanth Srinivasan 	}
1429a653a98SYork Sun #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
1439a653a98SYork Sun 	/*
144ce746fe0SPrabhakar Kushwaha 	 * As per CHASSIS2 architeture total 12 clusters are posible and
1459a653a98SYork Sun 	 * Each cluster has up to 4 cores, sharing the same PLL selection.
146ce746fe0SPrabhakar Kushwaha 	 * The cluster clock assignment is SoC defined.
147ce746fe0SPrabhakar Kushwaha 	 *
148ce746fe0SPrabhakar Kushwaha 	 * Total 4 clock groups are possible with 3 PLLs each.
149ce746fe0SPrabhakar Kushwaha 	 * as per array indices, clock group A has 0, 1, 2 numbered PLLs &
150ce746fe0SPrabhakar Kushwaha 	 * clock group B has 3, 4, 6 and so on.
151ce746fe0SPrabhakar Kushwaha 	 *
152ce746fe0SPrabhakar Kushwaha 	 * Clock group A having PLL1, PLL2, PLL3, feeding cores of any cluster
153ce746fe0SPrabhakar Kushwaha 	 * depends upon the SoC architeture. Same applies to other
154ce746fe0SPrabhakar Kushwaha 	 * clock groups and clusters.
155ce746fe0SPrabhakar Kushwaha 	 *
1569a653a98SYork Sun 	 */
1579a653a98SYork Sun 	for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
158f6981439SYork Sun 		int cluster = fsl_qoriq_core_to_cluster(cpu);
159f6981439SYork Sun 		u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
1609a653a98SYork Sun 				& 0xf;
1619a653a98SYork Sun 		u32 cplx_pll = core_cplx_PLL[c_pll_sel];
162ce746fe0SPrabhakar Kushwaha 		cplx_pll += cc_group[cluster] - 1;
163997399faSPrabhakar Kushwaha 		sys_info->freq_processor[cpu] =
164ce746fe0SPrabhakar Kushwaha 			 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
1659a653a98SYork Sun 	}
166*b33bd8cdSPrabhakar Kushwaha #if defined(CONFIG_PPC_B4860) || defined(CONFIG_PPC_B4420) || \
167*b33bd8cdSPrabhakar Kushwaha 	defined(CONFIG_PPC_T2080) || defined(CONFIG_PPC_T2081)
1680cb3325cSSandeep Singh #define FM1_CLK_SEL	0xe0000000
1690cb3325cSSandeep Singh #define FM1_CLK_SHIFT	29
1700cb3325cSSandeep Singh #else
1719a653a98SYork Sun #define PME_CLK_SEL	0xe0000000
1729a653a98SYork Sun #define PME_CLK_SHIFT	29
1739a653a98SYork Sun #define FM1_CLK_SEL	0x1c000000
1749a653a98SYork Sun #define FM1_CLK_SHIFT	26
1750cb3325cSSandeep Singh #endif
176ce746fe0SPrabhakar Kushwaha #if !defined(CONFIG_FM_PLAT_CLK_DIV) || !defined(CONFIG_PME_PLAT_CLK_DIV)
1779a653a98SYork Sun 	rcw_tmp = in_be32(&gur->rcwsr[7]);
178ce746fe0SPrabhakar Kushwaha #endif
1799a653a98SYork Sun 
1809a653a98SYork Sun #ifdef CONFIG_SYS_DPAA_PME
181ce746fe0SPrabhakar Kushwaha #ifndef CONFIG_PME_PLAT_CLK_DIV
1829a653a98SYork Sun 	switch ((rcw_tmp & PME_CLK_SEL) >> PME_CLK_SHIFT) {
1839a653a98SYork Sun 	case 1:
184ce746fe0SPrabhakar Kushwaha 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK];
1859a653a98SYork Sun 		break;
1869a653a98SYork Sun 	case 2:
187ce746fe0SPrabhakar Kushwaha 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 2;
1889a653a98SYork Sun 		break;
1899a653a98SYork Sun 	case 3:
190ce746fe0SPrabhakar Kushwaha 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 3;
1919a653a98SYork Sun 		break;
1929a653a98SYork Sun 	case 4:
193ce746fe0SPrabhakar Kushwaha 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK] / 4;
1949a653a98SYork Sun 		break;
1959a653a98SYork Sun 	case 6:
196ce746fe0SPrabhakar Kushwaha 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK + 1] / 2;
1979a653a98SYork Sun 		break;
1989a653a98SYork Sun 	case 7:
199ce746fe0SPrabhakar Kushwaha 		sys_info->freq_pme = freq_c_pll[CONFIG_SYS_PME_CLK + 1] / 3;
2009a653a98SYork Sun 		break;
2019a653a98SYork Sun 	default:
2029a653a98SYork Sun 		printf("Error: Unknown PME clock select!\n");
2039a653a98SYork Sun 	case 0:
204997399faSPrabhakar Kushwaha 		sys_info->freq_pme = sys_info->freq_systembus / 2;
2059a653a98SYork Sun 		break;
2069a653a98SYork Sun 
2079a653a98SYork Sun 	}
208ce746fe0SPrabhakar Kushwaha #else
209ce746fe0SPrabhakar Kushwaha 	sys_info->freq_pme = sys_info->freq_systembus / CONFIG_SYS_PME_CLK;
210ce746fe0SPrabhakar Kushwaha 
211ce746fe0SPrabhakar Kushwaha #endif
2129a653a98SYork Sun #endif
2139a653a98SYork Sun 
214990e1a8cSHaiying Wang #ifdef CONFIG_SYS_DPAA_QBMAN
215997399faSPrabhakar Kushwaha 	sys_info->freq_qman = sys_info->freq_systembus / 2;
216990e1a8cSHaiying Wang #endif
217990e1a8cSHaiying Wang 
2189a653a98SYork Sun #ifdef CONFIG_SYS_DPAA_FMAN
219ce746fe0SPrabhakar Kushwaha #ifndef CONFIG_FM_PLAT_CLK_DIV
2209a653a98SYork Sun 	switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) {
2219a653a98SYork Sun 	case 1:
222ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK];
2239a653a98SYork Sun 		break;
2249a653a98SYork Sun 	case 2:
225ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 2;
2269a653a98SYork Sun 		break;
2279a653a98SYork Sun 	case 3:
228ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 3;
2299a653a98SYork Sun 		break;
2309a653a98SYork Sun 	case 4:
231ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK] / 4;
2329a653a98SYork Sun 		break;
2330cb3325cSSandeep Singh 	case 5:
234997399faSPrabhakar Kushwaha 		sys_info->freq_fman[0] = sys_info->freq_systembus;
2350cb3325cSSandeep Singh 		break;
2369a653a98SYork Sun 	case 6:
237ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK + 1] / 2;
2389a653a98SYork Sun 		break;
2399a653a98SYork Sun 	case 7:
240ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[0] = freq_c_pll[CONFIG_SYS_FM1_CLK + 1] / 3;
2419a653a98SYork Sun 		break;
2429a653a98SYork Sun 	default:
2439a653a98SYork Sun 		printf("Error: Unknown FMan1 clock select!\n");
2449a653a98SYork Sun 	case 0:
245997399faSPrabhakar Kushwaha 		sys_info->freq_fman[0] = sys_info->freq_systembus / 2;
2469a653a98SYork Sun 		break;
2479a653a98SYork Sun 	}
2489a653a98SYork Sun #if (CONFIG_SYS_NUM_FMAN) == 2
249ce746fe0SPrabhakar Kushwaha #ifdef CONFIG_SYS_FM2_CLK
2509a653a98SYork Sun #define FM2_CLK_SEL	0x00000038
2519a653a98SYork Sun #define FM2_CLK_SHIFT	3
2529a653a98SYork Sun 	rcw_tmp = in_be32(&gur->rcwsr[15]);
2539a653a98SYork Sun 	switch ((rcw_tmp & FM2_CLK_SEL) >> FM2_CLK_SHIFT) {
2549a653a98SYork Sun 	case 1:
255ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1];
2569a653a98SYork Sun 		break;
2579a653a98SYork Sun 	case 2:
258ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 2;
2599a653a98SYork Sun 		break;
2609a653a98SYork Sun 	case 3:
261ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 3;
2629a653a98SYork Sun 		break;
2639a653a98SYork Sun 	case 4:
264ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 4;
2659a653a98SYork Sun 		break;
266c1015c67SShaohui Xie 	case 5:
267c1015c67SShaohui Xie 		sys_info->freq_fman[1] = sys_info->freq_systembus;
268c1015c67SShaohui Xie 		break;
2699a653a98SYork Sun 	case 6:
270ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 2;
2719a653a98SYork Sun 		break;
2729a653a98SYork Sun 	case 7:
273ce746fe0SPrabhakar Kushwaha 		sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 3;
2749a653a98SYork Sun 		break;
2759a653a98SYork Sun 	default:
2769a653a98SYork Sun 		printf("Error: Unknown FMan2 clock select!\n");
2779a653a98SYork Sun 	case 0:
278997399faSPrabhakar Kushwaha 		sys_info->freq_fman[1] = sys_info->freq_systembus / 2;
2799a653a98SYork Sun 		break;
2809a653a98SYork Sun 	}
281ce746fe0SPrabhakar Kushwaha #endif
2829a653a98SYork Sun #endif	/* CONFIG_SYS_NUM_FMAN == 2 */
283ce746fe0SPrabhakar Kushwaha #else
284ce746fe0SPrabhakar Kushwaha 	sys_info->freq_fman[0] = sys_info->freq_systembus / CONFIG_SYS_FM1_CLK;
285ce746fe0SPrabhakar Kushwaha #endif
286ce746fe0SPrabhakar Kushwaha #endif
2879a653a98SYork Sun 
2889a653a98SYork Sun #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
2899a653a98SYork Sun 
290fbb9ecf7STimur Tabi 	for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
291f6981439SYork Sun 		u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27)
292f6981439SYork Sun 				& 0xf;
293a47a12beSStefan Roese 		u32 cplx_pll = core_cplx_PLL[c_pll_sel];
294a47a12beSStefan Roese 
295997399faSPrabhakar Kushwaha 		sys_info->freq_processor[cpu] =
296ce746fe0SPrabhakar Kushwaha 			 freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
297a47a12beSStefan Roese 	}
298a47a12beSStefan Roese #define PME_CLK_SEL	0x80000000
299a47a12beSStefan Roese #define FM1_CLK_SEL	0x40000000
300a47a12beSStefan Roese #define FM2_CLK_SEL	0x20000000
301b5c8753fSKumar Gala #define HWA_ASYNC_DIV	0x04000000
302b5c8753fSKumar Gala #if (CONFIG_SYS_FSL_NUM_CC_PLLS == 2)
303b5c8753fSKumar Gala #define HWA_CC_PLL	1
3044905443fSTimur Tabi #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 3)
3054905443fSTimur Tabi #define HWA_CC_PLL	2
306b5c8753fSKumar Gala #elif (CONFIG_SYS_FSL_NUM_CC_PLLS == 4)
307b5c8753fSKumar Gala #define HWA_CC_PLL	2
308b5c8753fSKumar Gala #else
309b5c8753fSKumar Gala #error CONFIG_SYS_FSL_NUM_CC_PLLS not set or unknown case
310b5c8753fSKumar Gala #endif
311a47a12beSStefan Roese 	rcw_tmp = in_be32(&gur->rcwsr[7]);
312a47a12beSStefan Roese 
313a47a12beSStefan Roese #ifdef CONFIG_SYS_DPAA_PME
314b5c8753fSKumar Gala 	if (rcw_tmp & PME_CLK_SEL) {
315b5c8753fSKumar Gala 		if (rcw_tmp & HWA_ASYNC_DIV)
316ce746fe0SPrabhakar Kushwaha 			sys_info->freq_pme = freq_c_pll[HWA_CC_PLL] / 4;
317a47a12beSStefan Roese 		else
318ce746fe0SPrabhakar Kushwaha 			sys_info->freq_pme = freq_c_pll[HWA_CC_PLL] / 2;
319b5c8753fSKumar Gala 	} else {
320997399faSPrabhakar Kushwaha 		sys_info->freq_pme = sys_info->freq_systembus / 2;
321b5c8753fSKumar Gala 	}
322a47a12beSStefan Roese #endif
323a47a12beSStefan Roese 
324a47a12beSStefan Roese #ifdef CONFIG_SYS_DPAA_FMAN
325b5c8753fSKumar Gala 	if (rcw_tmp & FM1_CLK_SEL) {
326b5c8753fSKumar Gala 		if (rcw_tmp & HWA_ASYNC_DIV)
327ce746fe0SPrabhakar Kushwaha 			sys_info->freq_fman[0] = freq_c_pll[HWA_CC_PLL] / 4;
328a47a12beSStefan Roese 		else
329ce746fe0SPrabhakar Kushwaha 			sys_info->freq_fman[0] = freq_c_pll[HWA_CC_PLL] / 2;
330b5c8753fSKumar Gala 	} else {
331997399faSPrabhakar Kushwaha 		sys_info->freq_fman[0] = sys_info->freq_systembus / 2;
332b5c8753fSKumar Gala 	}
333a47a12beSStefan Roese #if (CONFIG_SYS_NUM_FMAN) == 2
334b5c8753fSKumar Gala 	if (rcw_tmp & FM2_CLK_SEL) {
335b5c8753fSKumar Gala 		if (rcw_tmp & HWA_ASYNC_DIV)
336ce746fe0SPrabhakar Kushwaha 			sys_info->freq_fman[1] = freq_c_pll[HWA_CC_PLL] / 4;
337a47a12beSStefan Roese 		else
338ce746fe0SPrabhakar Kushwaha 			sys_info->freq_fman[1] = freq_c_pll[HWA_CC_PLL] / 2;
339b5c8753fSKumar Gala 	} else {
340997399faSPrabhakar Kushwaha 		sys_info->freq_fman[1] = sys_info->freq_systembus / 2;
341b5c8753fSKumar Gala 	}
342a47a12beSStefan Roese #endif
343a47a12beSStefan Roese #endif
344a47a12beSStefan Roese 
3453e83fc9bSShaohui Xie #ifdef CONFIG_SYS_DPAA_QBMAN
346997399faSPrabhakar Kushwaha 	sys_info->freq_qman = sys_info->freq_systembus / 2;
3473e83fc9bSShaohui Xie #endif
3483e83fc9bSShaohui Xie 
3499a653a98SYork Sun #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
3509a653a98SYork Sun 
3512a44efebSZhao Qiang #ifdef CONFIG_U_QE
3522a44efebSZhao Qiang 	sys_info->freq_qe =  sys_info->freq_systembus / 2;
3532a44efebSZhao Qiang #endif
3542a44efebSZhao Qiang 
3559a653a98SYork Sun #else /* CONFIG_FSL_CORENET */
356997399faSPrabhakar Kushwaha 	uint plat_ratio, e500_ratio, half_freq_systembus;
357a47a12beSStefan Roese 	int i;
358a47a12beSStefan Roese #ifdef CONFIG_QE
359a52d2f81SHaiying Wang 	__maybe_unused u32 qe_ratio;
360a47a12beSStefan Roese #endif
361a47a12beSStefan Roese 
362a47a12beSStefan Roese 	plat_ratio = (gur->porpllsr) & 0x0000003e;
363a47a12beSStefan Roese 	plat_ratio >>= 1;
364997399faSPrabhakar Kushwaha 	sys_info->freq_systembus = plat_ratio * CONFIG_SYS_CLK_FREQ;
365a47a12beSStefan Roese 
366a47a12beSStefan Roese 	/* Divide before multiply to avoid integer
367a47a12beSStefan Roese 	 * overflow for processor speeds above 2GHz */
368997399faSPrabhakar Kushwaha 	half_freq_systembus = sys_info->freq_systembus/2;
369a47a12beSStefan Roese 	for (i = 0; i < cpu_numcores(); i++) {
370a47a12beSStefan Roese 		e500_ratio = ((gur->porpllsr) >> (i * 8 + 16)) & 0x3f;
371997399faSPrabhakar Kushwaha 		sys_info->freq_processor[i] = e500_ratio * half_freq_systembus;
372a47a12beSStefan Roese 	}
373a47a12beSStefan Roese 
374997399faSPrabhakar Kushwaha 	/* Note: freq_ddrbus is the MCLK frequency, not the data rate. */
375997399faSPrabhakar Kushwaha 	sys_info->freq_ddrbus = sys_info->freq_systembus;
376a47a12beSStefan Roese 
377a47a12beSStefan Roese #ifdef CONFIG_DDR_CLK_FREQ
378a47a12beSStefan Roese 	{
379a47a12beSStefan Roese 		u32 ddr_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO)
380a47a12beSStefan Roese 			>> MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
381a47a12beSStefan Roese 		if (ddr_ratio != 0x7)
382997399faSPrabhakar Kushwaha 			sys_info->freq_ddrbus = ddr_ratio * CONFIG_DDR_CLK_FREQ;
383a47a12beSStefan Roese 	}
384a47a12beSStefan Roese #endif
385a47a12beSStefan Roese 
386a47a12beSStefan Roese #ifdef CONFIG_QE
387be7bebeaSYork Sun #if defined(CONFIG_P1012) || defined(CONFIG_P1021) || defined(CONFIG_P1025)
388997399faSPrabhakar Kushwaha 	sys_info->freq_qe =  sys_info->freq_systembus;
389a52d2f81SHaiying Wang #else
390a47a12beSStefan Roese 	qe_ratio = ((gur->porpllsr) & MPC85xx_PORPLLSR_QE_RATIO)
391a47a12beSStefan Roese 			>> MPC85xx_PORPLLSR_QE_RATIO_SHIFT;
392997399faSPrabhakar Kushwaha 	sys_info->freq_qe = qe_ratio * CONFIG_SYS_CLK_FREQ;
393a47a12beSStefan Roese #endif
394a52d2f81SHaiying Wang #endif
395a47a12beSStefan Roese 
39624995d82SHaiying Wang #ifdef CONFIG_SYS_DPAA_FMAN
397997399faSPrabhakar Kushwaha 		sys_info->freq_fman[0] = sys_info->freq_systembus;
39824995d82SHaiying Wang #endif
39924995d82SHaiying Wang 
40024995d82SHaiying Wang #endif /* CONFIG_FSL_CORENET */
40124995d82SHaiying Wang 
402beba93edSDipen Dudhat #if defined(CONFIG_FSL_LBC)
4039a653a98SYork Sun 	uint lcrr_div;
404a47a12beSStefan Roese #if defined(CONFIG_SYS_LBC_LCRR)
405a47a12beSStefan Roese 	/* We will program LCRR to this value later */
406a47a12beSStefan Roese 	lcrr_div = CONFIG_SYS_LBC_LCRR & LCRR_CLKDIV;
407a47a12beSStefan Roese #else
408f51cdaf1SBecky Bruce 	lcrr_div = in_be32(&(LBC_BASE_ADDR)->lcrr) & LCRR_CLKDIV;
409a47a12beSStefan Roese #endif
410a47a12beSStefan Roese 	if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) {
411a47a12beSStefan Roese #if defined(CONFIG_FSL_CORENET)
412a47a12beSStefan Roese 		/* If this is corenet based SoC, bit-representation
413a47a12beSStefan Roese 		 * for four times the clock divider values.
414a47a12beSStefan Roese 		 */
415a47a12beSStefan Roese 		lcrr_div *= 4;
416a47a12beSStefan Roese #elif !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && \
417a47a12beSStefan Roese     !defined(CONFIG_MPC8555) && !defined(CONFIG_MPC8560)
418a47a12beSStefan Roese 		/*
419a47a12beSStefan Roese 		 * Yes, the entire PQ38 family use the same
420a47a12beSStefan Roese 		 * bit-representation for twice the clock divider values.
421a47a12beSStefan Roese 		 */
422a47a12beSStefan Roese 		lcrr_div *= 2;
423a47a12beSStefan Roese #endif
424997399faSPrabhakar Kushwaha 		sys_info->freq_localbus = sys_info->freq_systembus / lcrr_div;
425a47a12beSStefan Roese 	} else {
426a47a12beSStefan Roese 		/* In case anyone cares what the unknown value is */
427997399faSPrabhakar Kushwaha 		sys_info->freq_localbus = lcrr_div;
428a47a12beSStefan Roese 	}
429beba93edSDipen Dudhat #endif
430800c73c4SKumar Gala 
431800c73c4SKumar Gala #if defined(CONFIG_FSL_IFC)
432800c73c4SKumar Gala 	ccr = in_be32(&ifc_regs->ifc_ccr);
433800c73c4SKumar Gala 	ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
434800c73c4SKumar Gala 
435997399faSPrabhakar Kushwaha 	sys_info->freq_localbus = sys_info->freq_systembus / ccr;
436800c73c4SKumar Gala #endif
437a47a12beSStefan Roese }
438a47a12beSStefan Roese 
439a47a12beSStefan Roese 
440a47a12beSStefan Roese int get_clocks (void)
441a47a12beSStefan Roese {
442a47a12beSStefan Roese 	sys_info_t sys_info;
443a47a12beSStefan Roese #ifdef CONFIG_MPC8544
444a47a12beSStefan Roese 	volatile ccsr_gur_t *gur = (void *) CONFIG_SYS_MPC85xx_GUTS_ADDR;
445a47a12beSStefan Roese #endif
446a47a12beSStefan Roese #if defined(CONFIG_CPM2)
447a47a12beSStefan Roese 	volatile ccsr_cpm_t *cpm = (ccsr_cpm_t *)CONFIG_SYS_MPC85xx_CPM_ADDR;
448a47a12beSStefan Roese 	uint sccr, dfbrg;
449a47a12beSStefan Roese 
450a47a12beSStefan Roese 	/* set VCO = 4 * BRG */
451a47a12beSStefan Roese 	cpm->im_cpm_intctl.sccr &= 0xfffffffc;
452a47a12beSStefan Roese 	sccr = cpm->im_cpm_intctl.sccr;
453a47a12beSStefan Roese 	dfbrg = (sccr & SCCR_DFBRG_MSK) >> SCCR_DFBRG_SHIFT;
454a47a12beSStefan Roese #endif
455a47a12beSStefan Roese 	get_sys_info (&sys_info);
456997399faSPrabhakar Kushwaha 	gd->cpu_clk = sys_info.freq_processor[0];
457997399faSPrabhakar Kushwaha 	gd->bus_clk = sys_info.freq_systembus;
458997399faSPrabhakar Kushwaha 	gd->mem_clk = sys_info.freq_ddrbus;
459997399faSPrabhakar Kushwaha 	gd->arch.lbc_clk = sys_info.freq_localbus;
460a47a12beSStefan Roese 
461a47a12beSStefan Roese #ifdef CONFIG_QE
462997399faSPrabhakar Kushwaha 	gd->arch.qe_clk = sys_info.freq_qe;
46345bae2e3SSimon Glass 	gd->arch.brg_clk = gd->arch.qe_clk / 2;
464a47a12beSStefan Roese #endif
465a47a12beSStefan Roese 	/*
466a47a12beSStefan Roese 	 * The base clock for I2C depends on the actual SOC.  Unfortunately,
467a47a12beSStefan Roese 	 * there is no pattern that can be used to determine the frequency, so
468a47a12beSStefan Roese 	 * the only choice is to look up the actual SOC number and use the value
469a47a12beSStefan Roese 	 * for that SOC. This information is taken from application note
470a47a12beSStefan Roese 	 * AN2919.
471a47a12beSStefan Roese 	 */
472a47a12beSStefan Roese #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
473f62b1238STang Yuantian 	defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) || \
474f62b1238STang Yuantian 	defined(CONFIG_P1022)
475997399faSPrabhakar Kushwaha 	gd->arch.i2c1_clk = sys_info.freq_systembus;
476a47a12beSStefan Roese #elif defined(CONFIG_MPC8544)
477a47a12beSStefan Roese 	/*
478a47a12beSStefan Roese 	 * On the 8544, the I2C clock is the same as the SEC clock.  This can be
479a47a12beSStefan Roese 	 * either CCB/2 or CCB/3, depending on the value of cfg_sec_freq. See
480a47a12beSStefan Roese 	 * 4.4.3.3 of the 8544 RM.  Note that this might actually work for all
481a47a12beSStefan Roese 	 * 85xx, but only the 8544 has cfg_sec_freq, so it's unknown if the
482a47a12beSStefan Roese 	 * PORDEVSR2_SEC_CFG bit is 0 on all 85xx boards that are not an 8544.
483a47a12beSStefan Roese 	 */
484a47a12beSStefan Roese 	if (gur->pordevsr2 & MPC85xx_PORDEVSR2_SEC_CFG)
485997399faSPrabhakar Kushwaha 		gd->arch.i2c1_clk = sys_info.freq_systembus / 3;
486a47a12beSStefan Roese 	else
487997399faSPrabhakar Kushwaha 		gd->arch.i2c1_clk = sys_info.freq_systembus / 2;
488a47a12beSStefan Roese #else
489a47a12beSStefan Roese 	/* Most 85xx SOCs use CCB/2, so this is the default behavior. */
490997399faSPrabhakar Kushwaha 	gd->arch.i2c1_clk = sys_info.freq_systembus / 2;
491a47a12beSStefan Roese #endif
492609e6ec3SSimon Glass 	gd->arch.i2c2_clk = gd->arch.i2c1_clk;
493a47a12beSStefan Roese 
494a47a12beSStefan Roese #if defined(CONFIG_FSL_ESDHC)
4957d640e9bSPriyanka Jain #if defined(CONFIG_MPC8569) || defined(CONFIG_P1010) ||\
4967d640e9bSPriyanka Jain        defined(CONFIG_P1014)
497e9adeca3SSimon Glass 	gd->arch.sdhc_clk = gd->bus_clk;
498a47a12beSStefan Roese #else
499e9adeca3SSimon Glass 	gd->arch.sdhc_clk = gd->bus_clk / 2;
500a47a12beSStefan Roese #endif
501a47a12beSStefan Roese #endif /* defined(CONFIG_FSL_ESDHC) */
502a47a12beSStefan Roese 
503a47a12beSStefan Roese #if defined(CONFIG_CPM2)
504997399faSPrabhakar Kushwaha 	gd->arch.vco_out = 2*sys_info.freq_systembus;
505748cd059SSimon Glass 	gd->arch.cpm_clk = gd->arch.vco_out / 2;
506748cd059SSimon Glass 	gd->arch.scc_clk = gd->arch.vco_out / 4;
507748cd059SSimon Glass 	gd->arch.brg_clk = gd->arch.vco_out / (1 << (2 * (dfbrg + 1)));
508a47a12beSStefan Roese #endif
509a47a12beSStefan Roese 
510a47a12beSStefan Roese 	if(gd->cpu_clk != 0) return (0);
511a47a12beSStefan Roese 	else return (1);
512a47a12beSStefan Roese }
513a47a12beSStefan Roese 
514a47a12beSStefan Roese 
515a47a12beSStefan Roese /********************************************
516a47a12beSStefan Roese  * get_bus_freq
517a47a12beSStefan Roese  * return system bus freq in Hz
518a47a12beSStefan Roese  *********************************************/
519a47a12beSStefan Roese ulong get_bus_freq (ulong dummy)
520a47a12beSStefan Roese {
521a47a12beSStefan Roese 	return gd->bus_clk;
522a47a12beSStefan Roese }
523a47a12beSStefan Roese 
524a47a12beSStefan Roese /********************************************
525a47a12beSStefan Roese  * get_ddr_freq
526a47a12beSStefan Roese  * return ddr bus freq in Hz
527a47a12beSStefan Roese  *********************************************/
528a47a12beSStefan Roese ulong get_ddr_freq (ulong dummy)
529a47a12beSStefan Roese {
530a47a12beSStefan Roese 	return gd->mem_clk;
531a47a12beSStefan Roese }
532