xref: /rk3399_rockchip-uboot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c (revision c83a824e62277162ad35f52879b2316902c0eff5)
18281c58fSMingkai Hu /*
28281c58fSMingkai Hu  * Copyright 2015 Freescale Semiconductor, Inc.
38281c58fSMingkai Hu  *
48281c58fSMingkai Hu  * SPDX-License-Identifier:	GPL-2.0+
58281c58fSMingkai Hu  */
68281c58fSMingkai Hu 
78281c58fSMingkai Hu #include <common.h>
88281c58fSMingkai Hu #include <linux/compiler.h>
98281c58fSMingkai Hu #include <asm/io.h>
108281c58fSMingkai Hu #include <asm/processor.h>
118281c58fSMingkai Hu #include <asm/arch/clock.h>
128281c58fSMingkai Hu #include <asm/arch/soc.h>
138281c58fSMingkai Hu #include <fsl_ifc.h>
14f3acaf43SHou Zhiqiang #include "cpu.h"
158281c58fSMingkai Hu 
168281c58fSMingkai Hu DECLARE_GLOBAL_DATA_PTR;
178281c58fSMingkai Hu 
188281c58fSMingkai Hu #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
198281c58fSMingkai Hu #define CONFIG_SYS_FSL_NUM_CC_PLLS      2
208281c58fSMingkai Hu #endif
218281c58fSMingkai Hu 
get_sys_info(struct sys_info * sys_info)228281c58fSMingkai Hu void get_sys_info(struct sys_info *sys_info)
238281c58fSMingkai Hu {
248281c58fSMingkai Hu 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
25d9d9c977SPrabhakar Kushwaha #if (defined(CONFIG_FSL_ESDHC) &&\
26d9d9c977SPrabhakar Kushwaha 	defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)) ||\
27d9d9c977SPrabhakar Kushwaha 	defined(CONFIG_SYS_DPAA_FMAN)
28d9d9c977SPrabhakar Kushwaha 
29e8297341SShaohui Xie 	u32 rcw_tmp;
30e8297341SShaohui Xie #endif
318281c58fSMingkai Hu 	struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR);
328281c58fSMingkai Hu 	unsigned int cpu;
338281c58fSMingkai Hu 	const u8 core_cplx_pll[8] = {
348281c58fSMingkai Hu 		[0] = 0,	/* CC1 PPL / 1 */
358281c58fSMingkai Hu 		[1] = 0,	/* CC1 PPL / 2 */
368281c58fSMingkai Hu 		[4] = 1,	/* CC2 PPL / 1 */
378281c58fSMingkai Hu 		[5] = 1,	/* CC2 PPL / 2 */
388281c58fSMingkai Hu 	};
398281c58fSMingkai Hu 
408281c58fSMingkai Hu 	const u8 core_cplx_pll_div[8] = {
418281c58fSMingkai Hu 		[0] = 1,	/* CC1 PPL / 1 */
428281c58fSMingkai Hu 		[1] = 2,	/* CC1 PPL / 2 */
438281c58fSMingkai Hu 		[4] = 1,	/* CC2 PPL / 1 */
448281c58fSMingkai Hu 		[5] = 2,	/* CC2 PPL / 2 */
458281c58fSMingkai Hu 	};
468281c58fSMingkai Hu 
47f3acaf43SHou Zhiqiang 	uint i, cluster;
488281c58fSMingkai Hu 	uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
498281c58fSMingkai Hu 	uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
508281c58fSMingkai Hu 	unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
51904110c7SHou Zhiqiang 	unsigned long cluster_clk;
528281c58fSMingkai Hu 
538281c58fSMingkai Hu 	sys_info->freq_systembus = sysclk;
54904110c7SHou Zhiqiang #ifndef CONFIG_CLUSTER_CLK_FREQ
55904110c7SHou Zhiqiang #define CONFIG_CLUSTER_CLK_FREQ	CONFIG_SYS_CLK_FREQ
56904110c7SHou Zhiqiang #endif
57904110c7SHou Zhiqiang 	cluster_clk = CONFIG_CLUSTER_CLK_FREQ;
58904110c7SHou Zhiqiang 
598281c58fSMingkai Hu #ifdef CONFIG_DDR_CLK_FREQ
608281c58fSMingkai Hu 	sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
618281c58fSMingkai Hu #else
628281c58fSMingkai Hu 	sys_info->freq_ddrbus = sysclk;
638281c58fSMingkai Hu #endif
648281c58fSMingkai Hu 
65904110c7SHou Zhiqiang 	/* The freq_systembus is used to record frequency of platform PLL */
668281c58fSMingkai Hu 	sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
678281c58fSMingkai Hu 			FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) &
688281c58fSMingkai Hu 			FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
69904110c7SHou Zhiqiang 
70904110c7SHou Zhiqiang #ifdef CONFIG_ARCH_LS1012A
71904110c7SHou Zhiqiang 	sys_info->freq_ddrbus = 2 * sys_info->freq_systembus;
72904110c7SHou Zhiqiang #else
738281c58fSMingkai Hu 	sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
748281c58fSMingkai Hu 			FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) &
758281c58fSMingkai Hu 			FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
76b7f2bbffSPrabhakar Kushwaha #endif
778281c58fSMingkai Hu 
788281c58fSMingkai Hu 	for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
798281c58fSMingkai Hu 		ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff;
808281c58fSMingkai Hu 		if (ratio[i] > 4)
81904110c7SHou Zhiqiang 			freq_c_pll[i] = cluster_clk * ratio[i];
828281c58fSMingkai Hu 		else
838281c58fSMingkai Hu 			freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
848281c58fSMingkai Hu 	}
858281c58fSMingkai Hu 
86f3acaf43SHou Zhiqiang 	for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
87f3acaf43SHou Zhiqiang 		cluster = fsl_qoriq_core_to_cluster(cpu);
88f3acaf43SHou Zhiqiang 		u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
898281c58fSMingkai Hu 				& 0xf;
908281c58fSMingkai Hu 		u32 cplx_pll = core_cplx_pll[c_pll_sel];
918281c58fSMingkai Hu 
928281c58fSMingkai Hu 		sys_info->freq_processor[cpu] =
938281c58fSMingkai Hu 			freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
948281c58fSMingkai Hu 	}
958281c58fSMingkai Hu 
968281c58fSMingkai Hu #define HWA_CGA_M1_CLK_SEL	0xe0000000
978281c58fSMingkai Hu #define HWA_CGA_M1_CLK_SHIFT	29
98e8297341SShaohui Xie #ifdef CONFIG_SYS_DPAA_FMAN
99e8297341SShaohui Xie 	rcw_tmp = in_be32(&gur->rcwsr[7]);
100e8297341SShaohui Xie 	switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) {
101e8297341SShaohui Xie 	case 2:
102e8297341SShaohui Xie 		sys_info->freq_fman[0] = freq_c_pll[0] / 2;
103e8297341SShaohui Xie 		break;
104e8297341SShaohui Xie 	case 3:
105e8297341SShaohui Xie 		sys_info->freq_fman[0] = freq_c_pll[0] / 3;
106e8297341SShaohui Xie 		break;
107b528b937SMingkai Hu 	case 4:
108b528b937SMingkai Hu 		sys_info->freq_fman[0] = freq_c_pll[0] / 4;
109b528b937SMingkai Hu 		break;
110b528b937SMingkai Hu 	case 5:
111b528b937SMingkai Hu 		sys_info->freq_fman[0] = sys_info->freq_systembus;
112b528b937SMingkai Hu 		break;
113e8297341SShaohui Xie 	case 6:
114e8297341SShaohui Xie 		sys_info->freq_fman[0] = freq_c_pll[1] / 2;
115e8297341SShaohui Xie 		break;
116e8297341SShaohui Xie 	case 7:
117e8297341SShaohui Xie 		sys_info->freq_fman[0] = freq_c_pll[1] / 3;
118e8297341SShaohui Xie 		break;
119e8297341SShaohui Xie 	default:
120e8297341SShaohui Xie 		printf("Error: Unknown FMan1 clock select!\n");
121e8297341SShaohui Xie 		break;
122e8297341SShaohui Xie 	}
123e8297341SShaohui Xie #endif
1248281c58fSMingkai Hu 
1258281c58fSMingkai Hu #define HWA_CGA_M2_CLK_SEL	0x00000007
1268281c58fSMingkai Hu #define HWA_CGA_M2_CLK_SHIFT	0
1278ef0d5c4SYangbo Lu #ifdef CONFIG_FSL_ESDHC
128e477f4bdSYangbo Lu #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
1298ef0d5c4SYangbo Lu 	rcw_tmp = in_be32(&gur->rcwsr[15]);
130b528b937SMingkai Hu 	switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
131b528b937SMingkai Hu 	case 1:
132b528b937SMingkai Hu 		sys_info->freq_sdhc = freq_c_pll[1];
133b528b937SMingkai Hu 		break;
134b528b937SMingkai Hu 	case 2:
135b528b937SMingkai Hu 		sys_info->freq_sdhc = freq_c_pll[1] / 2;
136b528b937SMingkai Hu 		break;
137b528b937SMingkai Hu 	case 3:
138b528b937SMingkai Hu 		sys_info->freq_sdhc = freq_c_pll[1] / 3;
139b528b937SMingkai Hu 		break;
140b528b937SMingkai Hu 	case 6:
141b528b937SMingkai Hu 		sys_info->freq_sdhc = freq_c_pll[0] / 2;
142b528b937SMingkai Hu 		break;
143b528b937SMingkai Hu 	default:
144b528b937SMingkai Hu 		printf("Error: Unknown ESDHC clock select!\n");
145b528b937SMingkai Hu 		break;
146b528b937SMingkai Hu 	}
147e477f4bdSYangbo Lu #else
148904110c7SHou Zhiqiang 	sys_info->freq_sdhc = (sys_info->freq_systembus /
149904110c7SHou Zhiqiang 				CONFIG_SYS_FSL_PCLK_DIV) /
150904110c7SHou Zhiqiang 				CONFIG_SYS_FSL_SDHC_CLK_DIV;
151e477f4bdSYangbo Lu #endif
1528ef0d5c4SYangbo Lu #endif
1538281c58fSMingkai Hu 
1548281c58fSMingkai Hu #if defined(CONFIG_FSL_IFC)
155*8e63ed51SPrabhakar Kushwaha 	sys_info->freq_localbus = sys_info->freq_systembus /
156*8e63ed51SPrabhakar Kushwaha 						CONFIG_SYS_FSL_IFC_CLK_DIV;
1578281c58fSMingkai Hu #endif
1588281c58fSMingkai Hu }
1598281c58fSMingkai Hu 
get_clocks(void)1608281c58fSMingkai Hu int get_clocks(void)
1618281c58fSMingkai Hu {
1628281c58fSMingkai Hu 	struct sys_info sys_info;
1638281c58fSMingkai Hu 
1648281c58fSMingkai Hu 	get_sys_info(&sys_info);
1658281c58fSMingkai Hu 	gd->cpu_clk = sys_info.freq_processor[0];
166904110c7SHou Zhiqiang 	gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
1678281c58fSMingkai Hu 	gd->mem_clk = sys_info.freq_ddrbus;
1688281c58fSMingkai Hu 
1698ef0d5c4SYangbo Lu #ifdef CONFIG_FSL_ESDHC
1708ef0d5c4SYangbo Lu 	gd->arch.sdhc_clk = sys_info.freq_sdhc;
1718ef0d5c4SYangbo Lu #endif
1728ef0d5c4SYangbo Lu 
1738281c58fSMingkai Hu 	if (gd->cpu_clk != 0)
1748281c58fSMingkai Hu 		return 0;
1758281c58fSMingkai Hu 	else
1768281c58fSMingkai Hu 		return 1;
1778281c58fSMingkai Hu }
1788281c58fSMingkai Hu 
179904110c7SHou Zhiqiang /********************************************
180904110c7SHou Zhiqiang  * get_bus_freq
181904110c7SHou Zhiqiang  * return platform clock in Hz
182904110c7SHou Zhiqiang  *********************************************/
get_bus_freq(ulong dummy)1838281c58fSMingkai Hu ulong get_bus_freq(ulong dummy)
1848281c58fSMingkai Hu {
185904110c7SHou Zhiqiang 	if (!gd->bus_clk)
186904110c7SHou Zhiqiang 		get_clocks();
187904110c7SHou Zhiqiang 
1888281c58fSMingkai Hu 	return gd->bus_clk;
1898281c58fSMingkai Hu }
1908281c58fSMingkai Hu 
get_ddr_freq(ulong dummy)1918281c58fSMingkai Hu ulong get_ddr_freq(ulong dummy)
1928281c58fSMingkai Hu {
193904110c7SHou Zhiqiang 	if (!gd->mem_clk)
194904110c7SHou Zhiqiang 		get_clocks();
195904110c7SHou Zhiqiang 
1968281c58fSMingkai Hu 	return gd->mem_clk;
1978281c58fSMingkai Hu }
1988281c58fSMingkai Hu 
1998ef0d5c4SYangbo Lu #ifdef CONFIG_FSL_ESDHC
get_sdhc_freq(ulong dummy)2008ef0d5c4SYangbo Lu int get_sdhc_freq(ulong dummy)
2018ef0d5c4SYangbo Lu {
202904110c7SHou Zhiqiang 	if (!gd->arch.sdhc_clk)
203904110c7SHou Zhiqiang 		get_clocks();
204904110c7SHou Zhiqiang 
2058ef0d5c4SYangbo Lu 	return gd->arch.sdhc_clk;
2068ef0d5c4SYangbo Lu }
2078ef0d5c4SYangbo Lu #endif
2088ef0d5c4SYangbo Lu 
get_serial_clock(void)2098281c58fSMingkai Hu int get_serial_clock(void)
2108281c58fSMingkai Hu {
211904110c7SHou Zhiqiang 	return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
2128281c58fSMingkai Hu }
2138281c58fSMingkai Hu 
get_i2c_freq(ulong dummy)214904110c7SHou Zhiqiang int get_i2c_freq(ulong dummy)
215904110c7SHou Zhiqiang {
216904110c7SHou Zhiqiang 	return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
217904110c7SHou Zhiqiang }
218904110c7SHou Zhiqiang 
get_dspi_freq(ulong dummy)219904110c7SHou Zhiqiang int get_dspi_freq(ulong dummy)
220904110c7SHou Zhiqiang {
221904110c7SHou Zhiqiang 	return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
222904110c7SHou Zhiqiang }
223904110c7SHou Zhiqiang 
224904110c7SHou Zhiqiang #ifdef CONFIG_FSL_LPUART
get_uart_freq(ulong dummy)225904110c7SHou Zhiqiang int get_uart_freq(ulong dummy)
226904110c7SHou Zhiqiang {
227904110c7SHou Zhiqiang 	return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
228904110c7SHou Zhiqiang }
229904110c7SHou Zhiqiang #endif
230904110c7SHou Zhiqiang 
mxc_get_clock(enum mxc_clock clk)2318281c58fSMingkai Hu unsigned int mxc_get_clock(enum mxc_clock clk)
2328281c58fSMingkai Hu {
2338281c58fSMingkai Hu 	switch (clk) {
2348281c58fSMingkai Hu 	case MXC_I2C_CLK:
235904110c7SHou Zhiqiang 		return get_i2c_freq(0);
2368ef0d5c4SYangbo Lu #if defined(CONFIG_FSL_ESDHC)
2378ef0d5c4SYangbo Lu 	case MXC_ESDHC_CLK:
2388ef0d5c4SYangbo Lu 		return get_sdhc_freq(0);
2398ef0d5c4SYangbo Lu #endif
2408281c58fSMingkai Hu 	case MXC_DSPI_CLK:
241904110c7SHou Zhiqiang 		return get_dspi_freq(0);
242904110c7SHou Zhiqiang #ifdef CONFIG_FSL_LPUART
2438281c58fSMingkai Hu 	case MXC_UART_CLK:
244904110c7SHou Zhiqiang 		return get_uart_freq(0);
245904110c7SHou Zhiqiang #endif
2468281c58fSMingkai Hu 	default:
2478281c58fSMingkai Hu 		printf("Unsupported clock\n");
2488281c58fSMingkai Hu 	}
2498281c58fSMingkai Hu 	return 0;
2508281c58fSMingkai Hu }
251