xref: /openbmc/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c (revision 87a62bce)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2014 Freescale Semiconductor, Inc.
4  */
5 
6 #include <common.h>
7 #include <asm/io.h>
8 #include <asm/arch/immap_ls102xa.h>
9 #include <asm/arch/clock.h>
10 #include <fsl_ifc.h>
11 
12 DECLARE_GLOBAL_DATA_PTR;
13 
14 #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
15 #define CONFIG_SYS_FSL_NUM_CC_PLLS      2
16 #endif
17 
18 void get_sys_info(struct sys_info *sys_info)
19 {
20 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
21 	struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR);
22 	unsigned int cpu;
23 	const u8 core_cplx_pll[6] = {
24 		[0] = 0,	/* CC1 PPL / 1 */
25 		[1] = 0,	/* CC1 PPL / 2 */
26 		[4] = 1,	/* CC2 PPL / 1 */
27 		[5] = 1,	/* CC2 PPL / 2 */
28 	};
29 
30 	const u8 core_cplx_pll_div[6] = {
31 		[0] = 1,	/* CC1 PPL / 1 */
32 		[1] = 2,	/* CC1 PPL / 2 */
33 		[4] = 1,	/* CC2 PPL / 1 */
34 		[5] = 2,	/* CC2 PPL / 2 */
35 	};
36 
37 	uint i;
38 	uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
39 	uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
40 	unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
41 
42 	sys_info->freq_systembus = sysclk;
43 #ifdef CONFIG_DDR_CLK_FREQ
44 	sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
45 #else
46 	sys_info->freq_ddrbus = sysclk;
47 #endif
48 
49 	sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >>
50 		RCWSR0_SYS_PLL_RAT_SHIFT) & RCWSR0_SYS_PLL_RAT_MASK;
51 	sys_info->freq_ddrbus *= (in_be32(&gur->rcwsr[0]) >>
52 		RCWSR0_MEM_PLL_RAT_SHIFT) & RCWSR0_MEM_PLL_RAT_MASK;
53 
54 	for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
55 		ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f;
56 		if (ratio[i] > 4)
57 			freq_c_pll[i] = sysclk * ratio[i];
58 		else
59 			freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
60 	}
61 
62 	for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) {
63 		u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27)
64 				& 0xf;
65 		u32 cplx_pll = core_cplx_pll[c_pll_sel];
66 
67 		sys_info->freq_processor[cpu] =
68 			freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
69 	}
70 
71 #if defined(CONFIG_FSL_IFC)
72 	sys_info->freq_localbus = sys_info->freq_systembus;
73 #endif
74 }
75 
76 int get_clocks(void)
77 {
78 	struct sys_info sys_info;
79 
80 	get_sys_info(&sys_info);
81 	gd->cpu_clk = sys_info.freq_processor[0];
82 	gd->bus_clk = sys_info.freq_systembus;
83 	gd->mem_clk = sys_info.freq_ddrbus * 2;
84 
85 #if defined(CONFIG_FSL_ESDHC)
86 	gd->arch.sdhc_clk = gd->bus_clk;
87 #endif
88 
89 	return 0;
90 }
91 
92 ulong get_bus_freq(ulong dummy)
93 {
94 	return gd->bus_clk;
95 }
96 
97 ulong get_ddr_freq(ulong dummy)
98 {
99 	return gd->mem_clk;
100 }
101 
102 int get_serial_clock(void)
103 {
104 	return gd->bus_clk / 2;
105 }
106 
107 unsigned int mxc_get_clock(enum mxc_clock clk)
108 {
109 	switch (clk) {
110 	case MXC_I2C_CLK:
111 		return get_bus_freq(0) / 2;
112 	case MXC_ESDHC_CLK:
113 		return get_bus_freq(0);
114 	case MXC_DSPI_CLK:
115 		return get_bus_freq(0) / 2;
116 	case MXC_UART_CLK:
117 		return get_bus_freq(0) / 2;
118 	default:
119 		printf("Unsupported clock\n");
120 	}
121 	return 0;
122 }
123