8386678c468afdc9caa3561b6eddb2cc5e62d06a
[oweals/u-boot.git] / 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 #endif
160 }
161
162 #ifdef CONFIG_SYS_DPAA_QBMAN
163 unsigned long get_qman_freq(void)
164 {
165         struct sys_info sys_info;
166
167         get_sys_info(&sys_info);
168
169         return sys_info.freq_qman;
170 }
171 #endif
172
173 int get_clocks(void)
174 {
175         struct sys_info sys_info;
176
177         get_sys_info(&sys_info);
178         gd->cpu_clk = sys_info.freq_processor[0];
179         gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
180         gd->mem_clk = sys_info.freq_ddrbus;
181
182 #ifdef CONFIG_FSL_ESDHC
183         gd->arch.sdhc_clk = sys_info.freq_sdhc;
184 #endif
185
186         if (gd->cpu_clk != 0)
187                 return 0;
188         else
189                 return 1;
190 }
191
192 /********************************************
193  * get_bus_freq
194  * return platform clock in Hz
195  *********************************************/
196 ulong get_bus_freq(ulong dummy)
197 {
198         if (!gd->bus_clk)
199                 get_clocks();
200
201         return gd->bus_clk;
202 }
203
204 ulong get_ddr_freq(ulong dummy)
205 {
206         if (!gd->mem_clk)
207                 get_clocks();
208
209         return gd->mem_clk;
210 }
211
212 #ifdef CONFIG_FSL_ESDHC
213 int get_sdhc_freq(ulong dummy)
214 {
215         if (!gd->arch.sdhc_clk)
216                 get_clocks();
217
218         return gd->arch.sdhc_clk;
219 }
220 #endif
221
222 int get_serial_clock(void)
223 {
224         return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
225 }
226
227 int get_i2c_freq(ulong dummy)
228 {
229         return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
230 }
231
232 int get_dspi_freq(ulong dummy)
233 {
234         return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
235 }
236
237 #ifdef CONFIG_FSL_LPUART
238 int get_uart_freq(ulong dummy)
239 {
240         return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
241 }
242 #endif
243
244 unsigned int mxc_get_clock(enum mxc_clock clk)
245 {
246         switch (clk) {
247         case MXC_I2C_CLK:
248                 return get_i2c_freq(0);
249 #if defined(CONFIG_FSL_ESDHC)
250         case MXC_ESDHC_CLK:
251                 return get_sdhc_freq(0);
252 #endif
253         case MXC_DSPI_CLK:
254                 return get_dspi_freq(0);
255 #ifdef CONFIG_FSL_LPUART
256         case MXC_UART_CLK:
257                 return get_uart_freq(0);
258 #endif
259         default:
260                 printf("Unsupported clock\n");
261         }
262         return 0;
263 }