xref: /openbmc/u-boot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c (revision c590e62d3b6f6dd72eae1183614f919e3fd7ffcb)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
28281c58fSMingkai Hu /*
38281c58fSMingkai Hu  * Copyright 2015 Freescale Semiconductor, Inc.
48281c58fSMingkai Hu  */
58281c58fSMingkai Hu 
68281c58fSMingkai Hu #include <common.h>
78281c58fSMingkai Hu #include <linux/compiler.h>
88281c58fSMingkai Hu #include <asm/io.h>
98281c58fSMingkai Hu #include <asm/processor.h>
108281c58fSMingkai Hu #include <asm/arch/clock.h>
118281c58fSMingkai Hu #include <asm/arch/soc.h>
128281c58fSMingkai Hu #include <fsl_ifc.h>
13f3acaf43SHou Zhiqiang #include "cpu.h"
148281c58fSMingkai Hu 
158281c58fSMingkai Hu DECLARE_GLOBAL_DATA_PTR;
168281c58fSMingkai Hu 
178281c58fSMingkai Hu #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
188281c58fSMingkai Hu #define CONFIG_SYS_FSL_NUM_CC_PLLS      2
198281c58fSMingkai Hu #endif
208281c58fSMingkai Hu 
get_sys_info(struct sys_info * sys_info)218281c58fSMingkai Hu void get_sys_info(struct sys_info *sys_info)
228281c58fSMingkai Hu {
238281c58fSMingkai Hu 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
24d9d9c977SPrabhakar Kushwaha #if (defined(CONFIG_FSL_ESDHC) &&\
25d9d9c977SPrabhakar Kushwaha 	defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)) ||\
26d9d9c977SPrabhakar Kushwaha 	defined(CONFIG_SYS_DPAA_FMAN)
27d9d9c977SPrabhakar Kushwaha 
28e8297341SShaohui Xie 	u32 rcw_tmp;
29e8297341SShaohui Xie #endif
308281c58fSMingkai Hu 	struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR);
318281c58fSMingkai Hu 	unsigned int cpu;
328281c58fSMingkai Hu 	const u8 core_cplx_pll[8] = {
338281c58fSMingkai Hu 		[0] = 0,	/* CC1 PPL / 1 */
348281c58fSMingkai Hu 		[1] = 0,	/* CC1 PPL / 2 */
358281c58fSMingkai Hu 		[4] = 1,	/* CC2 PPL / 1 */
368281c58fSMingkai Hu 		[5] = 1,	/* CC2 PPL / 2 */
378281c58fSMingkai Hu 	};
388281c58fSMingkai Hu 
398281c58fSMingkai Hu 	const u8 core_cplx_pll_div[8] = {
408281c58fSMingkai Hu 		[0] = 1,	/* CC1 PPL / 1 */
418281c58fSMingkai Hu 		[1] = 2,	/* CC1 PPL / 2 */
428281c58fSMingkai Hu 		[4] = 1,	/* CC2 PPL / 1 */
438281c58fSMingkai Hu 		[5] = 2,	/* CC2 PPL / 2 */
448281c58fSMingkai Hu 	};
458281c58fSMingkai Hu 
46f3acaf43SHou Zhiqiang 	uint i, cluster;
478281c58fSMingkai Hu 	uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
488281c58fSMingkai Hu 	uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
498281c58fSMingkai Hu 	unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
50904110c7SHou Zhiqiang 	unsigned long cluster_clk;
518281c58fSMingkai Hu 
528281c58fSMingkai Hu 	sys_info->freq_systembus = sysclk;
53904110c7SHou Zhiqiang #ifndef CONFIG_CLUSTER_CLK_FREQ
54904110c7SHou Zhiqiang #define CONFIG_CLUSTER_CLK_FREQ	CONFIG_SYS_CLK_FREQ
55904110c7SHou Zhiqiang #endif
56904110c7SHou Zhiqiang 	cluster_clk = CONFIG_CLUSTER_CLK_FREQ;
57904110c7SHou Zhiqiang 
588281c58fSMingkai Hu #ifdef CONFIG_DDR_CLK_FREQ
598281c58fSMingkai Hu 	sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
608281c58fSMingkai Hu #else
618281c58fSMingkai Hu 	sys_info->freq_ddrbus = sysclk;
628281c58fSMingkai Hu #endif
638281c58fSMingkai Hu 
64904110c7SHou Zhiqiang 	/* The freq_systembus is used to record frequency of platform PLL */
658281c58fSMingkai Hu 	sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
668281c58fSMingkai Hu 			FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) &
678281c58fSMingkai Hu 			FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
68904110c7SHou Zhiqiang 
69904110c7SHou Zhiqiang #ifdef CONFIG_ARCH_LS1012A
70904110c7SHou Zhiqiang 	sys_info->freq_ddrbus = 2 * sys_info->freq_systembus;
71904110c7SHou Zhiqiang #else
728281c58fSMingkai Hu 	sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
738281c58fSMingkai Hu 			FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) &
748281c58fSMingkai Hu 			FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
75b7f2bbffSPrabhakar Kushwaha #endif
768281c58fSMingkai Hu 
778281c58fSMingkai Hu 	for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
788281c58fSMingkai Hu 		ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff;
798281c58fSMingkai Hu 		if (ratio[i] > 4)
80904110c7SHou Zhiqiang 			freq_c_pll[i] = cluster_clk * ratio[i];
818281c58fSMingkai Hu 		else
828281c58fSMingkai Hu 			freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
838281c58fSMingkai Hu 	}
848281c58fSMingkai Hu 
85f3acaf43SHou Zhiqiang 	for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
86f3acaf43SHou Zhiqiang 		cluster = fsl_qoriq_core_to_cluster(cpu);
87f3acaf43SHou Zhiqiang 		u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
888281c58fSMingkai Hu 				& 0xf;
898281c58fSMingkai Hu 		u32 cplx_pll = core_cplx_pll[c_pll_sel];
908281c58fSMingkai Hu 
918281c58fSMingkai Hu 		sys_info->freq_processor[cpu] =
928281c58fSMingkai Hu 			freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
938281c58fSMingkai Hu 	}
948281c58fSMingkai Hu 
958281c58fSMingkai Hu #define HWA_CGA_M1_CLK_SEL	0xe0000000
968281c58fSMingkai Hu #define HWA_CGA_M1_CLK_SHIFT	29
97e8297341SShaohui Xie #ifdef CONFIG_SYS_DPAA_FMAN
98e8297341SShaohui Xie 	rcw_tmp = in_be32(&gur->rcwsr[7]);
99e8297341SShaohui Xie 	switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) {
100e8297341SShaohui Xie 	case 2:
101e8297341SShaohui Xie 		sys_info->freq_fman[0] = freq_c_pll[0] / 2;
102e8297341SShaohui Xie 		break;
103e8297341SShaohui Xie 	case 3:
104e8297341SShaohui Xie 		sys_info->freq_fman[0] = freq_c_pll[0] / 3;
105e8297341SShaohui Xie 		break;
106b528b937SMingkai Hu 	case 4:
107b528b937SMingkai Hu 		sys_info->freq_fman[0] = freq_c_pll[0] / 4;
108b528b937SMingkai Hu 		break;
109b528b937SMingkai Hu 	case 5:
110b528b937SMingkai Hu 		sys_info->freq_fman[0] = sys_info->freq_systembus;
111b528b937SMingkai Hu 		break;
112e8297341SShaohui Xie 	case 6:
113e8297341SShaohui Xie 		sys_info->freq_fman[0] = freq_c_pll[1] / 2;
114e8297341SShaohui Xie 		break;
115e8297341SShaohui Xie 	case 7:
116e8297341SShaohui Xie 		sys_info->freq_fman[0] = freq_c_pll[1] / 3;
117e8297341SShaohui Xie 		break;
118e8297341SShaohui Xie 	default:
119e8297341SShaohui Xie 		printf("Error: Unknown FMan1 clock select!\n");
120e8297341SShaohui Xie 		break;
121e8297341SShaohui Xie 	}
122e8297341SShaohui Xie #endif
1238281c58fSMingkai Hu 
1248281c58fSMingkai Hu #define HWA_CGA_M2_CLK_SEL	0x00000007
1258281c58fSMingkai Hu #define HWA_CGA_M2_CLK_SHIFT	0
1268ef0d5c4SYangbo Lu #ifdef CONFIG_FSL_ESDHC
127e477f4bdSYangbo Lu #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
1288ef0d5c4SYangbo Lu 	rcw_tmp = in_be32(&gur->rcwsr[15]);
129b528b937SMingkai Hu 	switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
130b528b937SMingkai Hu 	case 1:
131b528b937SMingkai Hu 		sys_info->freq_sdhc = freq_c_pll[1];
132b528b937SMingkai Hu 		break;
133b528b937SMingkai Hu 	case 2:
134b528b937SMingkai Hu 		sys_info->freq_sdhc = freq_c_pll[1] / 2;
135b528b937SMingkai Hu 		break;
136b528b937SMingkai Hu 	case 3:
137b528b937SMingkai Hu 		sys_info->freq_sdhc = freq_c_pll[1] / 3;
138b528b937SMingkai Hu 		break;
139b528b937SMingkai Hu 	case 6:
140b528b937SMingkai Hu 		sys_info->freq_sdhc = freq_c_pll[0] / 2;
141b528b937SMingkai Hu 		break;
142b528b937SMingkai Hu 	default:
143b528b937SMingkai Hu 		printf("Error: Unknown ESDHC clock select!\n");
144b528b937SMingkai Hu 		break;
145b528b937SMingkai Hu 	}
146e477f4bdSYangbo Lu #else
147904110c7SHou Zhiqiang 	sys_info->freq_sdhc = (sys_info->freq_systembus /
148904110c7SHou Zhiqiang 				CONFIG_SYS_FSL_PCLK_DIV) /
149904110c7SHou Zhiqiang 				CONFIG_SYS_FSL_SDHC_CLK_DIV;
150e477f4bdSYangbo Lu #endif
1518ef0d5c4SYangbo Lu #endif
1528281c58fSMingkai Hu 
1538281c58fSMingkai Hu #if defined(CONFIG_FSL_IFC)
1548e63ed51SPrabhakar Kushwaha 	sys_info->freq_localbus = sys_info->freq_systembus /
1558e63ed51SPrabhakar Kushwaha 						CONFIG_SYS_FSL_IFC_CLK_DIV;
1568281c58fSMingkai Hu #endif
15744262327SAhmed Mansour #ifdef CONFIG_SYS_DPAA_QBMAN
158*945fad57SHou Zhiqiang 	sys_info->freq_qman = (sys_info->freq_systembus /
159*945fad57SHou Zhiqiang 				CONFIG_SYS_FSL_PCLK_DIV) /
160*945fad57SHou Zhiqiang 				CONFIG_SYS_FSL_QMAN_CLK_DIV;
16144262327SAhmed Mansour #endif
1628281c58fSMingkai Hu }
1638281c58fSMingkai Hu 
16444262327SAhmed Mansour #ifdef CONFIG_SYS_DPAA_QBMAN
get_qman_freq(void)16544262327SAhmed Mansour unsigned long get_qman_freq(void)
16644262327SAhmed Mansour {
16744262327SAhmed Mansour 	struct sys_info sys_info;
16844262327SAhmed Mansour 
16944262327SAhmed Mansour 	get_sys_info(&sys_info);
17044262327SAhmed Mansour 
17144262327SAhmed Mansour 	return sys_info.freq_qman;
17244262327SAhmed Mansour }
17344262327SAhmed Mansour #endif
17444262327SAhmed Mansour 
get_clocks(void)1758281c58fSMingkai Hu int get_clocks(void)
1768281c58fSMingkai Hu {
1778281c58fSMingkai Hu 	struct sys_info sys_info;
1788281c58fSMingkai Hu 
1798281c58fSMingkai Hu 	get_sys_info(&sys_info);
1808281c58fSMingkai Hu 	gd->cpu_clk = sys_info.freq_processor[0];
181904110c7SHou Zhiqiang 	gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
1828281c58fSMingkai Hu 	gd->mem_clk = sys_info.freq_ddrbus;
1838281c58fSMingkai Hu 
1848ef0d5c4SYangbo Lu #ifdef CONFIG_FSL_ESDHC
1858ef0d5c4SYangbo Lu 	gd->arch.sdhc_clk = sys_info.freq_sdhc;
1868ef0d5c4SYangbo Lu #endif
1878ef0d5c4SYangbo Lu 
1888281c58fSMingkai Hu 	if (gd->cpu_clk != 0)
1898281c58fSMingkai Hu 		return 0;
1908281c58fSMingkai Hu 	else
1918281c58fSMingkai Hu 		return 1;
1928281c58fSMingkai Hu }
1938281c58fSMingkai Hu 
194904110c7SHou Zhiqiang /********************************************
195904110c7SHou Zhiqiang  * get_bus_freq
196904110c7SHou Zhiqiang  * return platform clock in Hz
197904110c7SHou Zhiqiang  *********************************************/
get_bus_freq(ulong dummy)1988281c58fSMingkai Hu ulong get_bus_freq(ulong dummy)
1998281c58fSMingkai Hu {
200904110c7SHou Zhiqiang 	if (!gd->bus_clk)
201904110c7SHou Zhiqiang 		get_clocks();
202904110c7SHou Zhiqiang 
2038281c58fSMingkai Hu 	return gd->bus_clk;
2048281c58fSMingkai Hu }
2058281c58fSMingkai Hu 
get_ddr_freq(ulong dummy)2068281c58fSMingkai Hu ulong get_ddr_freq(ulong dummy)
2078281c58fSMingkai Hu {
208904110c7SHou Zhiqiang 	if (!gd->mem_clk)
209904110c7SHou Zhiqiang 		get_clocks();
210904110c7SHou Zhiqiang 
2118281c58fSMingkai Hu 	return gd->mem_clk;
2128281c58fSMingkai Hu }
2138281c58fSMingkai Hu 
2148ef0d5c4SYangbo Lu #ifdef CONFIG_FSL_ESDHC
get_sdhc_freq(ulong dummy)2158ef0d5c4SYangbo Lu int get_sdhc_freq(ulong dummy)
2168ef0d5c4SYangbo Lu {
217904110c7SHou Zhiqiang 	if (!gd->arch.sdhc_clk)
218904110c7SHou Zhiqiang 		get_clocks();
219904110c7SHou Zhiqiang 
2208ef0d5c4SYangbo Lu 	return gd->arch.sdhc_clk;
2218ef0d5c4SYangbo Lu }
2228ef0d5c4SYangbo Lu #endif
2238ef0d5c4SYangbo Lu 
get_serial_clock(void)2248281c58fSMingkai Hu int get_serial_clock(void)
2258281c58fSMingkai Hu {
226904110c7SHou Zhiqiang 	return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
2278281c58fSMingkai Hu }
2288281c58fSMingkai Hu 
get_i2c_freq(ulong dummy)229904110c7SHou Zhiqiang int get_i2c_freq(ulong dummy)
230904110c7SHou Zhiqiang {
231904110c7SHou Zhiqiang 	return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
232904110c7SHou Zhiqiang }
233904110c7SHou Zhiqiang 
get_dspi_freq(ulong dummy)234904110c7SHou Zhiqiang int get_dspi_freq(ulong dummy)
235904110c7SHou Zhiqiang {
236904110c7SHou Zhiqiang 	return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
237904110c7SHou Zhiqiang }
238904110c7SHou Zhiqiang 
239904110c7SHou Zhiqiang #ifdef CONFIG_FSL_LPUART
get_uart_freq(ulong dummy)240904110c7SHou Zhiqiang int get_uart_freq(ulong dummy)
241904110c7SHou Zhiqiang {
242904110c7SHou Zhiqiang 	return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
243904110c7SHou Zhiqiang }
244904110c7SHou Zhiqiang #endif
245904110c7SHou Zhiqiang 
mxc_get_clock(enum mxc_clock clk)2468281c58fSMingkai Hu unsigned int mxc_get_clock(enum mxc_clock clk)
2478281c58fSMingkai Hu {
2488281c58fSMingkai Hu 	switch (clk) {
2498281c58fSMingkai Hu 	case MXC_I2C_CLK:
250904110c7SHou Zhiqiang 		return get_i2c_freq(0);
2518ef0d5c4SYangbo Lu #if defined(CONFIG_FSL_ESDHC)
2528ef0d5c4SYangbo Lu 	case MXC_ESDHC_CLK:
2538ef0d5c4SYangbo Lu 		return get_sdhc_freq(0);
2548ef0d5c4SYangbo Lu #endif
2558281c58fSMingkai Hu 	case MXC_DSPI_CLK:
256904110c7SHou Zhiqiang 		return get_dspi_freq(0);
257904110c7SHou Zhiqiang #ifdef CONFIG_FSL_LPUART
2588281c58fSMingkai Hu 	case MXC_UART_CLK:
259904110c7SHou Zhiqiang 		return get_uart_freq(0);
260904110c7SHou Zhiqiang #endif
2618281c58fSMingkai Hu 	default:
2628281c58fSMingkai Hu 		printf("Unsupported clock\n");
2638281c58fSMingkai Hu 	}
2648281c58fSMingkai Hu 	return 0;
2658281c58fSMingkai Hu }
266