]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
18bacc20 | 2 | /* |
19a8dbdc | 3 | * Copyright 2009-2012 Freescale Semiconductor, Inc. |
18bacc20 | 4 | * |
a47a12be SR |
5 | * This file is derived from arch/powerpc/cpu/mpc85xx/cpu.c and |
6 | * arch/powerpc/cpu/mpc86xx/cpu.c. Basically this file contains | |
8d1f2682 | 7 | * cpu specific common code for 85xx/86xx processors. |
18bacc20 PA |
8 | */ |
9 | ||
10 | #include <config.h> | |
11 | #include <common.h> | |
12 | #include <command.h> | |
b5981474 | 13 | #include <cpu_func.h> |
90526e9f | 14 | #include <net.h> |
18bacc20 | 15 | #include <tsec.h> |
c916d7c9 | 16 | #include <fm_eth.h> |
18bacc20 PA |
17 | #include <netdev.h> |
18 | #include <asm/cache.h> | |
19 | #include <asm/io.h> | |
7e40e4be | 20 | #include <vsc9953.h> |
18bacc20 PA |
21 | |
22 | DECLARE_GLOBAL_DATA_PTR; | |
23 | ||
2ed2e912 | 24 | static struct cpu_type cpu_type_list[] = { |
18bacc20 | 25 | #if defined(CONFIG_MPC85xx) |
0e870980 | 26 | CPU_TYPE_ENTRY(8533, 8533, 1), |
0e870980 | 27 | CPU_TYPE_ENTRY(8535, 8535, 1), |
0e870980 | 28 | CPU_TYPE_ENTRY(8536, 8536, 1), |
0e870980 PA |
29 | CPU_TYPE_ENTRY(8540, 8540, 1), |
30 | CPU_TYPE_ENTRY(8541, 8541, 1), | |
0e870980 | 31 | CPU_TYPE_ENTRY(8543, 8543, 1), |
0e870980 | 32 | CPU_TYPE_ENTRY(8544, 8544, 1), |
0e870980 | 33 | CPU_TYPE_ENTRY(8545, 8545, 1), |
48f6a5c3 | 34 | CPU_TYPE_ENTRY(8547, 8547, 1), |
0e870980 | 35 | CPU_TYPE_ENTRY(8548, 8548, 1), |
0e870980 | 36 | CPU_TYPE_ENTRY(8555, 8555, 1), |
0e870980 PA |
37 | CPU_TYPE_ENTRY(8560, 8560, 1), |
38 | CPU_TYPE_ENTRY(8567, 8567, 1), | |
0e870980 | 39 | CPU_TYPE_ENTRY(8568, 8568, 1), |
0e870980 | 40 | CPU_TYPE_ENTRY(8569, 8569, 1), |
0e870980 | 41 | CPU_TYPE_ENTRY(8572, 8572, 2), |
b8cdd014 | 42 | CPU_TYPE_ENTRY(P1010, P1010, 1), |
a713ba92 | 43 | CPU_TYPE_ENTRY(P1011, P1011, 1), |
21608275 | 44 | CPU_TYPE_ENTRY(P1012, P1012, 1), |
21608275 | 45 | CPU_TYPE_ENTRY(P1013, P1013, 1), |
b5debec5 | 46 | CPU_TYPE_ENTRY(P1014, P1014, 1), |
67a719da | 47 | CPU_TYPE_ENTRY(P1017, P1017, 1), |
87c7661b | 48 | CPU_TYPE_ENTRY(P1020, P1020, 2), |
21608275 | 49 | CPU_TYPE_ENTRY(P1021, P1021, 2), |
21608275 | 50 | CPU_TYPE_ENTRY(P1022, P1022, 2), |
67a719da | 51 | CPU_TYPE_ENTRY(P1023, P1023, 2), |
093cffbe | 52 | CPU_TYPE_ENTRY(P1024, P1024, 2), |
093cffbe | 53 | CPU_TYPE_ENTRY(P1025, P1025, 2), |
a713ba92 | 54 | CPU_TYPE_ENTRY(P2010, P2010, 1), |
a713ba92 | 55 | CPU_TYPE_ENTRY(P2020, P2020, 2), |
f193e3da | 56 | CPU_TYPE_ENTRY(P2040, P2040, 4), |
1f97987a | 57 | CPU_TYPE_ENTRY(P2041, P2041, 4), |
c26de2d8 | 58 | CPU_TYPE_ENTRY(P3041, P3041, 4), |
7e4259bb | 59 | CPU_TYPE_ENTRY(P4040, P4040, 4), |
7e4259bb | 60 | CPU_TYPE_ENTRY(P4080, P4080, 8), |
19dbcc96 | 61 | CPU_TYPE_ENTRY(P5010, P5010, 1), |
19dbcc96 | 62 | CPU_TYPE_ENTRY(P5020, P5020, 2), |
4905443f TT |
63 | CPU_TYPE_ENTRY(P5021, P5021, 2), |
64 | CPU_TYPE_ENTRY(P5040, P5040, 4), | |
9e758758 YS |
65 | CPU_TYPE_ENTRY(T4240, T4240, 0), |
66 | CPU_TYPE_ENTRY(T4120, T4120, 0), | |
b6240846 | 67 | CPU_TYPE_ENTRY(T4160, T4160, 0), |
5122dfae | 68 | CPU_TYPE_ENTRY(T4080, T4080, 4), |
d2404141 YS |
69 | CPU_TYPE_ENTRY(B4860, B4860, 0), |
70 | CPU_TYPE_ENTRY(G4860, G4860, 0), | |
d2404141 | 71 | CPU_TYPE_ENTRY(B4440, B4440, 0), |
9c3fdd88 | 72 | CPU_TYPE_ENTRY(B4460, B4460, 0), |
d2404141 YS |
73 | CPU_TYPE_ENTRY(G4440, G4440, 0), |
74 | CPU_TYPE_ENTRY(B4420, B4420, 0), | |
75 | CPU_TYPE_ENTRY(B4220, B4220, 0), | |
5f208d11 YS |
76 | CPU_TYPE_ENTRY(T1040, T1040, 0), |
77 | CPU_TYPE_ENTRY(T1041, T1041, 0), | |
78 | CPU_TYPE_ENTRY(T1042, T1042, 0), | |
79 | CPU_TYPE_ENTRY(T1020, T1020, 0), | |
80 | CPU_TYPE_ENTRY(T1021, T1021, 0), | |
81 | CPU_TYPE_ENTRY(T1022, T1022, 0), | |
f6050790 SL |
82 | CPU_TYPE_ENTRY(T1024, T1024, 0), |
83 | CPU_TYPE_ENTRY(T1023, T1023, 0), | |
84 | CPU_TYPE_ENTRY(T1014, T1014, 0), | |
85 | CPU_TYPE_ENTRY(T1013, T1013, 0), | |
629d6b32 SL |
86 | CPU_TYPE_ENTRY(T2080, T2080, 0), |
87 | CPU_TYPE_ENTRY(T2081, T2081, 0), | |
19a8dbdc | 88 | CPU_TYPE_ENTRY(BSC9130, 9130, 1), |
19a8dbdc | 89 | CPU_TYPE_ENTRY(BSC9131, 9131, 1), |
35fe948e PK |
90 | CPU_TYPE_ENTRY(BSC9132, 9132, 2), |
91 | CPU_TYPE_ENTRY(BSC9232, 9232, 2), | |
3b75e982 MH |
92 | CPU_TYPE_ENTRY(C291, C291, 1), |
93 | CPU_TYPE_ENTRY(C292, C292, 1), | |
94 | CPU_TYPE_ENTRY(C293, C293, 1), | |
18bacc20 | 95 | #elif defined(CONFIG_MPC86xx) |
0e870980 PA |
96 | CPU_TYPE_ENTRY(8610, 8610, 1), |
97 | CPU_TYPE_ENTRY(8641, 8641, 2), | |
98 | CPU_TYPE_ENTRY(8641D, 8641D, 2), | |
18bacc20 PA |
99 | #endif |
100 | }; | |
101 | ||
123bd96d | 102 | #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 |
f6981439 YS |
103 | static inline u32 init_type(u32 cluster, int init_id) |
104 | { | |
105 | ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
106 | u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK; | |
107 | u32 type = in_be32(&gur->tp_ityp[idx]); | |
108 | ||
109 | if (type & TP_ITYP_AV) | |
110 | return type; | |
111 | ||
112 | return 0; | |
113 | } | |
114 | ||
123bd96d YS |
115 | u32 compute_ppc_cpumask(void) |
116 | { | |
f6981439 | 117 | ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
123bd96d | 118 | int i = 0, count = 0; |
f6981439 | 119 | u32 cluster, type, mask = 0; |
123bd96d YS |
120 | |
121 | do { | |
122 | int j; | |
f6981439 YS |
123 | cluster = in_be32(&gur->tp_cluster[i].lower); |
124 | for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { | |
125 | type = init_type(cluster, j); | |
126 | if (type) { | |
123bd96d YS |
127 | if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_PPC) |
128 | mask |= 1 << count; | |
f6981439 | 129 | count++; |
123bd96d | 130 | } |
123bd96d | 131 | } |
f6981439 | 132 | i++; |
123bd96d YS |
133 | } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); |
134 | ||
135 | return mask; | |
136 | } | |
f6981439 | 137 | |
b8bf0adc SL |
138 | #ifdef CONFIG_HETROGENOUS_CLUSTERS |
139 | u32 compute_dsp_cpumask(void) | |
140 | { | |
141 | ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
142 | int i = CONFIG_DSP_CLUSTER_START, count = 0; | |
143 | u32 cluster, type, dsp_mask = 0; | |
144 | ||
145 | do { | |
146 | int j; | |
147 | cluster = in_be32(&gur->tp_cluster[i].lower); | |
148 | for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { | |
149 | type = init_type(cluster, j); | |
150 | if (type) { | |
151 | if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_SC) | |
152 | dsp_mask |= 1 << count; | |
153 | count++; | |
154 | } | |
155 | } | |
156 | i++; | |
157 | } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); | |
158 | ||
159 | return dsp_mask; | |
160 | } | |
161 | ||
162 | int fsl_qoriq_dsp_core_to_cluster(unsigned int core) | |
163 | { | |
164 | ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
165 | int count = 0, i = CONFIG_DSP_CLUSTER_START; | |
166 | u32 cluster; | |
167 | ||
168 | do { | |
169 | int j; | |
170 | cluster = in_be32(&gur->tp_cluster[i].lower); | |
171 | for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { | |
172 | if (init_type(cluster, j)) { | |
173 | if (count == core) | |
174 | return i; | |
175 | count++; | |
176 | } | |
177 | } | |
178 | i++; | |
179 | } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); | |
180 | ||
181 | return -1; /* cannot identify the cluster */ | |
182 | } | |
183 | #endif | |
184 | ||
f6981439 YS |
185 | int fsl_qoriq_core_to_cluster(unsigned int core) |
186 | { | |
187 | ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
188 | int i = 0, count = 0; | |
189 | u32 cluster; | |
190 | ||
191 | do { | |
192 | int j; | |
193 | cluster = in_be32(&gur->tp_cluster[i].lower); | |
194 | for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { | |
195 | if (init_type(cluster, j)) { | |
196 | if (count == core) | |
197 | return i; | |
198 | count++; | |
199 | } | |
200 | } | |
201 | i++; | |
202 | } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); | |
203 | ||
204 | return -1; /* cannot identify the cluster */ | |
205 | } | |
206 | ||
123bd96d YS |
207 | #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ |
208 | /* | |
209 | * Before chassis genenration 2, the cpumask should be hard-coded. | |
210 | * In case of cpu type unknown or cpumask unset, use 1 as fail save. | |
211 | */ | |
212 | #define compute_ppc_cpumask() 1 | |
f6981439 | 213 | #define fsl_qoriq_core_to_cluster(x) x |
123bd96d YS |
214 | #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ |
215 | ||
2ed2e912 | 216 | static struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 0); |
58442dc0 | 217 | |
18bacc20 PA |
218 | struct cpu_type *identify_cpu(u32 ver) |
219 | { | |
220 | int i; | |
221 | for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) { | |
222 | if (cpu_type_list[i].soc_ver == ver) | |
223 | return &cpu_type_list[i]; | |
224 | } | |
58442dc0 | 225 | return &cpu_type_unknown; |
18bacc20 PA |
226 | } |
227 | ||
fbb9ecf7 TT |
228 | #define MPC8xxx_PICFRR_NCPU_MASK 0x00001f00 |
229 | #define MPC8xxx_PICFRR_NCPU_SHIFT 8 | |
230 | ||
231 | /* | |
232 | * Return a 32-bit mask indicating which cores are present on this SOC. | |
233 | */ | |
b539534d | 234 | __weak u32 cpu_mask(void) |
fbb9ecf7 TT |
235 | { |
236 | ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; | |
67ac13b1 | 237 | struct cpu_type *cpu = gd->arch.cpu; |
fbb9ecf7 TT |
238 | |
239 | /* better to query feature reporting register than just assume 1 */ | |
240 | if (cpu == &cpu_type_unknown) | |
241 | return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> | |
242 | MPC8xxx_PICFRR_NCPU_SHIFT) + 1; | |
243 | ||
123bd96d YS |
244 | if (cpu->num_cores == 0) |
245 | return compute_ppc_cpumask(); | |
246 | ||
fbb9ecf7 TT |
247 | return cpu->mask; |
248 | } | |
249 | ||
b8bf0adc SL |
250 | #ifdef CONFIG_HETROGENOUS_CLUSTERS |
251 | __weak u32 cpu_dsp_mask(void) | |
252 | { | |
253 | ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; | |
254 | struct cpu_type *cpu = gd->arch.cpu; | |
255 | ||
256 | /* better to query feature reporting register than just assume 1 */ | |
257 | if (cpu == &cpu_type_unknown) | |
258 | return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> | |
259 | MPC8xxx_PICFRR_NCPU_SHIFT) + 1; | |
260 | ||
261 | if (cpu->dsp_num_cores == 0) | |
262 | return compute_dsp_cpumask(); | |
263 | ||
264 | return cpu->dsp_mask; | |
265 | } | |
266 | ||
fbb9ecf7 | 267 | /* |
b8bf0adc SL |
268 | * Return the number of SC/DSP cores on this SOC. |
269 | */ | |
270 | __weak int cpu_num_dspcores(void) | |
271 | { | |
272 | struct cpu_type *cpu = gd->arch.cpu; | |
273 | ||
274 | /* | |
275 | * Report # of cores in terms of the cpu_mask if we haven't | |
276 | * figured out how many there are yet | |
277 | */ | |
278 | if (cpu->dsp_num_cores == 0) | |
279 | return hweight32(cpu_dsp_mask()); | |
280 | ||
281 | return cpu->dsp_num_cores; | |
282 | } | |
283 | #endif | |
284 | ||
285 | /* | |
286 | * Return the number of PPC cores on this SOC. | |
fbb9ecf7 | 287 | */ |
b539534d | 288 | __weak int cpu_numcores(void) |
2ed2e912 | 289 | { |
67ac13b1 | 290 | struct cpu_type *cpu = gd->arch.cpu; |
a37c36f4 | 291 | |
123bd96d YS |
292 | /* |
293 | * Report # of cores in terms of the cpu_mask if we haven't | |
294 | * figured out how many there are yet | |
295 | */ | |
296 | if (cpu->num_cores == 0) | |
297 | return hweight32(cpu_mask()); | |
a37c36f4 | 298 | |
0e870980 PA |
299 | return cpu->num_cores; |
300 | } | |
301 | ||
b8bf0adc | 302 | |
fbb9ecf7 TT |
303 | /* |
304 | * Check if the given core ID is valid | |
305 | * | |
306 | * Returns zero if it isn't, 1 if it is. | |
307 | */ | |
308 | int is_core_valid(unsigned int core) | |
309 | { | |
123bd96d | 310 | return !!((1 << core) & cpu_mask()); |
fbb9ecf7 TT |
311 | } |
312 | ||
cbcbf71b | 313 | int arch_cpu_init(void) |
0e870980 PA |
314 | { |
315 | uint svr; | |
316 | uint ver; | |
317 | ||
318 | svr = get_svr(); | |
319 | ver = SVR_SOC_VER(svr); | |
320 | ||
67ac13b1 | 321 | gd->arch.cpu = identify_cpu(ver); |
0e870980 | 322 | |
0e870980 PA |
323 | return 0; |
324 | } | |
325 | ||
123bd96d YS |
326 | /* Once in memory, compute mask & # cores once and save them off */ |
327 | int fixup_cpu(void) | |
328 | { | |
67ac13b1 | 329 | struct cpu_type *cpu = gd->arch.cpu; |
123bd96d YS |
330 | |
331 | if (cpu->num_cores == 0) { | |
332 | cpu->mask = cpu_mask(); | |
333 | cpu->num_cores = cpu_numcores(); | |
334 | } | |
335 | ||
b8bf0adc SL |
336 | #ifdef CONFIG_HETROGENOUS_CLUSTERS |
337 | if (cpu->dsp_num_cores == 0) { | |
338 | cpu->dsp_mask = cpu_dsp_mask(); | |
339 | cpu->dsp_num_cores = cpu_num_dspcores(); | |
340 | } | |
341 | #endif | |
123bd96d YS |
342 | return 0; |
343 | } | |
344 | ||
18bacc20 PA |
345 | /* |
346 | * Initializes on-chip ethernet controllers. | |
347 | * to override, implement board_eth_init() | |
348 | */ | |
349 | int cpu_eth_init(bd_t *bis) | |
350 | { | |
351 | #if defined(CONFIG_ETHER_ON_FCC) | |
352 | fec_initialize(bis); | |
353 | #endif | |
354 | ||
355 | #if defined(CONFIG_UEC_ETH) | |
356 | uec_standard_init(bis); | |
357 | #endif | |
358 | ||
359 | #if defined(CONFIG_TSEC_ENET) || defined(CONFIG_MPC85XX_FEC) | |
360 | tsec_standard_init(bis); | |
361 | #endif | |
362 | ||
c916d7c9 KG |
363 | #ifdef CONFIG_FMAN_ENET |
364 | fm_standard_init(bis); | |
365 | #endif | |
7e40e4be CC |
366 | |
367 | #ifdef CONFIG_VSC9953 | |
368 | vsc9953_init(bis); | |
369 | #endif | |
18bacc20 PA |
370 | return 0; |
371 | } |