]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
[u-boot] / arch / arm / cpu / armv8 / fsl-layerscape / fsl_lsch2_speed.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2015 Freescale Semiconductor, Inc.
4  */
5
6 #include <common.h>
7 #include <linux/compiler.h>
8 #include <asm/io.h>
9 #include <asm/processor.h>
10 #include <asm/arch/clock.h>
11 #include <asm/arch/soc.h>
12 #include <fsl_ifc.h>
13 #include "cpu.h"
14
15 DECLARE_GLOBAL_DATA_PTR;
16
17 #ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
18 #define CONFIG_SYS_FSL_NUM_CC_PLLS      2
19 #endif
20
21 void get_sys_info(struct sys_info *sys_info)
22 {
23         struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
24 #if (defined(CONFIG_FSL_ESDHC) &&\
25         defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)) ||\
26         defined(CONFIG_SYS_DPAA_FMAN)
27
28         u32 rcw_tmp;
29 #endif
30         struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR);
31         unsigned int cpu;
32         const u8 core_cplx_pll[8] = {
33                 [0] = 0,        /* CC1 PPL / 1 */
34                 [1] = 0,        /* CC1 PPL / 2 */
35                 [4] = 1,        /* CC2 PPL / 1 */
36                 [5] = 1,        /* CC2 PPL / 2 */
37         };
38
39         const u8 core_cplx_pll_div[8] = {
40                 [0] = 1,        /* CC1 PPL / 1 */
41                 [1] = 2,        /* CC1 PPL / 2 */
42                 [4] = 1,        /* CC2 PPL / 1 */
43                 [5] = 2,        /* CC2 PPL / 2 */
44         };
45
46         uint i, cluster;
47         uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
48         uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
49         unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
50         unsigned long cluster_clk;
51
52         sys_info->freq_systembus = sysclk;
53 #ifndef CONFIG_CLUSTER_CLK_FREQ
54 #define CONFIG_CLUSTER_CLK_FREQ CONFIG_SYS_CLK_FREQ
55 #endif
56         cluster_clk = CONFIG_CLUSTER_CLK_FREQ;
57
58 #ifdef CONFIG_DDR_CLK_FREQ
59         sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
60 #else
61         sys_info->freq_ddrbus = sysclk;
62 #endif
63
64         /* The freq_systembus is used to record frequency of platform PLL */
65         sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
66                         FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) &
67                         FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
68
69 #ifdef CONFIG_ARCH_LS1012A
70         sys_info->freq_ddrbus = 2 * sys_info->freq_systembus;
71 #else
72         sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
73                         FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) &
74                         FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
75 #endif
76
77         for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
78                 ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff;
79                 if (ratio[i] > 4)
80                         freq_c_pll[i] = cluster_clk * ratio[i];
81                 else
82                         freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
83         }
84
85         for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
86                 cluster = fsl_qoriq_core_to_cluster(cpu);
87                 u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
88                                 & 0xf;
89                 u32 cplx_pll = core_cplx_pll[c_pll_sel];
90
91                 sys_info->freq_processor[cpu] =
92                         freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
93         }
94
95 #define HWA_CGA_M1_CLK_SEL      0xe0000000
96 #define HWA_CGA_M1_CLK_SHIFT    29
97 #ifdef CONFIG_SYS_DPAA_FMAN
98         rcw_tmp = in_be32(&gur->rcwsr[7]);
99         switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) {
100         case 2:
101                 sys_info->freq_fman[0] = freq_c_pll[0] / 2;
102                 break;
103         case 3:
104                 sys_info->freq_fman[0] = freq_c_pll[0] / 3;
105                 break;
106         case 4:
107                 sys_info->freq_fman[0] = freq_c_pll[0] / 4;
108                 break;
109         case 5:
110                 sys_info->freq_fman[0] = sys_info->freq_systembus;
111                 break;
112         case 6:
113                 sys_info->freq_fman[0] = freq_c_pll[1] / 2;
114                 break;
115         case 7:
116                 sys_info->freq_fman[0] = freq_c_pll[1] / 3;
117                 break;
118         default:
119                 printf("Error: Unknown FMan1 clock select!\n");
120                 break;
121         }
122 #endif
123
124 #define HWA_CGA_M2_CLK_SEL      0x00000007
125 #define HWA_CGA_M2_CLK_SHIFT    0
126 #ifdef CONFIG_FSL_ESDHC
127 #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
128         rcw_tmp = in_be32(&gur->rcwsr[15]);
129         switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
130         case 1:
131                 sys_info->freq_sdhc = freq_c_pll[1];
132                 break;
133         case 2:
134                 sys_info->freq_sdhc = freq_c_pll[1] / 2;
135                 break;
136         case 3:
137                 sys_info->freq_sdhc = freq_c_pll[1] / 3;
138                 break;
139         case 6:
140                 sys_info->freq_sdhc = freq_c_pll[0] / 2;
141                 break;
142         default:
143                 printf("Error: Unknown ESDHC clock select!\n");
144                 break;
145         }
146 #else
147         sys_info->freq_sdhc = (sys_info->freq_systembus /
148                                 CONFIG_SYS_FSL_PCLK_DIV) /
149                                 CONFIG_SYS_FSL_SDHC_CLK_DIV;
150 #endif
151 #endif
152
153 #if defined(CONFIG_FSL_IFC)
154         sys_info->freq_localbus = sys_info->freq_systembus /
155                                                 CONFIG_SYS_FSL_IFC_CLK_DIV;
156 #endif
157 #ifdef CONFIG_SYS_DPAA_QBMAN
158         sys_info->freq_qman = (sys_info->freq_systembus /
159                                 CONFIG_SYS_FSL_PCLK_DIV) /
160                                 CONFIG_SYS_FSL_QMAN_CLK_DIV;
161 #endif
162 }
163
164 #ifdef CONFIG_SYS_DPAA_QBMAN
165 unsigned long get_qman_freq(void)
166 {
167         struct sys_info sys_info;
168
169         get_sys_info(&sys_info);
170
171         return sys_info.freq_qman;
172 }
173 #endif
174
175 int get_clocks(void)
176 {
177         struct sys_info sys_info;
178
179         get_sys_info(&sys_info);
180         gd->cpu_clk = sys_info.freq_processor[0];
181         gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
182         gd->mem_clk = sys_info.freq_ddrbus;
183
184 #ifdef CONFIG_FSL_ESDHC
185         gd->arch.sdhc_clk = sys_info.freq_sdhc;
186 #endif
187
188         if (gd->cpu_clk != 0)
189                 return 0;
190         else
191                 return 1;
192 }
193
194 /********************************************
195  * get_bus_freq
196  * return platform clock in Hz
197  *********************************************/
198 ulong get_bus_freq(ulong dummy)
199 {
200         if (!gd->bus_clk)
201                 get_clocks();
202
203         return gd->bus_clk;
204 }
205
206 ulong get_ddr_freq(ulong dummy)
207 {
208         if (!gd->mem_clk)
209                 get_clocks();
210
211         return gd->mem_clk;
212 }
213
214 #ifdef CONFIG_FSL_ESDHC
215 int get_sdhc_freq(ulong dummy)
216 {
217         if (!gd->arch.sdhc_clk)
218                 get_clocks();
219
220         return gd->arch.sdhc_clk;
221 }
222 #endif
223
224 int get_serial_clock(void)
225 {
226         return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
227 }
228
229 int get_i2c_freq(ulong dummy)
230 {
231         return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
232 }
233
234 int get_dspi_freq(ulong dummy)
235 {
236         return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
237 }
238
239 #ifdef CONFIG_FSL_LPUART
240 int get_uart_freq(ulong dummy)
241 {
242         return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
243 }
244 #endif
245
246 unsigned int mxc_get_clock(enum mxc_clock clk)
247 {
248         switch (clk) {
249         case MXC_I2C_CLK:
250                 return get_i2c_freq(0);
251 #if defined(CONFIG_FSL_ESDHC)
252         case MXC_ESDHC_CLK:
253                 return get_sdhc_freq(0);
254 #endif
255         case MXC_DSPI_CLK:
256                 return get_dspi_freq(0);
257 #ifdef CONFIG_FSL_LPUART
258         case MXC_UART_CLK:
259                 return get_uart_freq(0);
260 #endif
261         default:
262                 printf("Unsupported clock\n");
263         }
264         return 0;
265 }