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