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