]>
Commit | Line | Data |
---|---|---|
18bacc20 | 1 | /* |
19a8dbdc | 2 | * Copyright 2009-2012 Freescale Semiconductor, Inc. |
18bacc20 | 3 | * |
a47a12be SR |
4 | * This file is derived from arch/powerpc/cpu/mpc85xx/cpu.c and |
5 | * arch/powerpc/cpu/mpc86xx/cpu.c. Basically this file contains | |
8d1f2682 | 6 | * cpu specific common code for 85xx/86xx processors. |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
18bacc20 PA |
8 | */ |
9 | ||
10 | #include <config.h> | |
11 | #include <common.h> | |
12 | #include <command.h> | |
13 | #include <tsec.h> | |
c916d7c9 | 14 | #include <fm_eth.h> |
18bacc20 PA |
15 | #include <netdev.h> |
16 | #include <asm/cache.h> | |
17 | #include <asm/io.h> | |
18 | ||
19 | DECLARE_GLOBAL_DATA_PTR; | |
20 | ||
2ed2e912 | 21 | static struct cpu_type cpu_type_list[] = { |
18bacc20 | 22 | #if defined(CONFIG_MPC85xx) |
0e870980 | 23 | CPU_TYPE_ENTRY(8533, 8533, 1), |
0e870980 | 24 | CPU_TYPE_ENTRY(8535, 8535, 1), |
0e870980 | 25 | CPU_TYPE_ENTRY(8536, 8536, 1), |
0e870980 PA |
26 | CPU_TYPE_ENTRY(8540, 8540, 1), |
27 | CPU_TYPE_ENTRY(8541, 8541, 1), | |
0e870980 | 28 | CPU_TYPE_ENTRY(8543, 8543, 1), |
0e870980 | 29 | CPU_TYPE_ENTRY(8544, 8544, 1), |
0e870980 | 30 | CPU_TYPE_ENTRY(8545, 8545, 1), |
48f6a5c3 | 31 | CPU_TYPE_ENTRY(8547, 8547, 1), |
0e870980 | 32 | CPU_TYPE_ENTRY(8548, 8548, 1), |
0e870980 | 33 | CPU_TYPE_ENTRY(8555, 8555, 1), |
0e870980 PA |
34 | CPU_TYPE_ENTRY(8560, 8560, 1), |
35 | CPU_TYPE_ENTRY(8567, 8567, 1), | |
0e870980 | 36 | CPU_TYPE_ENTRY(8568, 8568, 1), |
0e870980 | 37 | CPU_TYPE_ENTRY(8569, 8569, 1), |
0e870980 | 38 | CPU_TYPE_ENTRY(8572, 8572, 2), |
b8cdd014 | 39 | CPU_TYPE_ENTRY(P1010, P1010, 1), |
a713ba92 | 40 | CPU_TYPE_ENTRY(P1011, P1011, 1), |
21608275 | 41 | CPU_TYPE_ENTRY(P1012, P1012, 1), |
21608275 | 42 | CPU_TYPE_ENTRY(P1013, P1013, 1), |
b5debec5 | 43 | CPU_TYPE_ENTRY(P1014, P1014, 1), |
67a719da | 44 | CPU_TYPE_ENTRY(P1017, P1017, 1), |
87c7661b | 45 | CPU_TYPE_ENTRY(P1020, P1020, 2), |
21608275 | 46 | CPU_TYPE_ENTRY(P1021, P1021, 2), |
21608275 | 47 | CPU_TYPE_ENTRY(P1022, P1022, 2), |
67a719da | 48 | CPU_TYPE_ENTRY(P1023, P1023, 2), |
093cffbe | 49 | CPU_TYPE_ENTRY(P1024, P1024, 2), |
093cffbe | 50 | CPU_TYPE_ENTRY(P1025, P1025, 2), |
a713ba92 | 51 | CPU_TYPE_ENTRY(P2010, P2010, 1), |
a713ba92 | 52 | CPU_TYPE_ENTRY(P2020, P2020, 2), |
f193e3da | 53 | CPU_TYPE_ENTRY(P2040, P2040, 4), |
1f97987a | 54 | CPU_TYPE_ENTRY(P2041, P2041, 4), |
c26de2d8 | 55 | CPU_TYPE_ENTRY(P3041, P3041, 4), |
7e4259bb | 56 | CPU_TYPE_ENTRY(P4040, P4040, 4), |
7e4259bb | 57 | CPU_TYPE_ENTRY(P4080, P4080, 8), |
19dbcc96 | 58 | CPU_TYPE_ENTRY(P5010, P5010, 1), |
19dbcc96 | 59 | CPU_TYPE_ENTRY(P5020, P5020, 2), |
4905443f TT |
60 | CPU_TYPE_ENTRY(P5021, P5021, 2), |
61 | CPU_TYPE_ENTRY(P5040, P5040, 4), | |
9e758758 YS |
62 | CPU_TYPE_ENTRY(T4240, T4240, 0), |
63 | CPU_TYPE_ENTRY(T4120, T4120, 0), | |
b6240846 | 64 | CPU_TYPE_ENTRY(T4160, T4160, 0), |
d2404141 YS |
65 | CPU_TYPE_ENTRY(B4860, B4860, 0), |
66 | CPU_TYPE_ENTRY(G4860, G4860, 0), | |
67 | CPU_TYPE_ENTRY(G4060, G4060, 0), | |
68 | CPU_TYPE_ENTRY(B4440, B4440, 0), | |
69 | CPU_TYPE_ENTRY(G4440, G4440, 0), | |
70 | CPU_TYPE_ENTRY(B4420, B4420, 0), | |
71 | CPU_TYPE_ENTRY(B4220, B4220, 0), | |
5f208d11 YS |
72 | CPU_TYPE_ENTRY(T1040, T1040, 0), |
73 | CPU_TYPE_ENTRY(T1041, T1041, 0), | |
74 | CPU_TYPE_ENTRY(T1042, T1042, 0), | |
75 | CPU_TYPE_ENTRY(T1020, T1020, 0), | |
76 | CPU_TYPE_ENTRY(T1021, T1021, 0), | |
77 | CPU_TYPE_ENTRY(T1022, T1022, 0), | |
19a8dbdc | 78 | CPU_TYPE_ENTRY(BSC9130, 9130, 1), |
19a8dbdc | 79 | CPU_TYPE_ENTRY(BSC9131, 9131, 1), |
35fe948e PK |
80 | CPU_TYPE_ENTRY(BSC9132, 9132, 2), |
81 | CPU_TYPE_ENTRY(BSC9232, 9232, 2), | |
18bacc20 | 82 | #elif defined(CONFIG_MPC86xx) |
0e870980 PA |
83 | CPU_TYPE_ENTRY(8610, 8610, 1), |
84 | CPU_TYPE_ENTRY(8641, 8641, 2), | |
85 | CPU_TYPE_ENTRY(8641D, 8641D, 2), | |
18bacc20 PA |
86 | #endif |
87 | }; | |
88 | ||
123bd96d | 89 | #ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 |
f6981439 YS |
90 | static inline u32 init_type(u32 cluster, int init_id) |
91 | { | |
92 | ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
93 | u32 idx = (cluster >> (init_id * 8)) & TP_CLUSTER_INIT_MASK; | |
94 | u32 type = in_be32(&gur->tp_ityp[idx]); | |
95 | ||
96 | if (type & TP_ITYP_AV) | |
97 | return type; | |
98 | ||
99 | return 0; | |
100 | } | |
101 | ||
123bd96d YS |
102 | u32 compute_ppc_cpumask(void) |
103 | { | |
f6981439 | 104 | ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
123bd96d | 105 | int i = 0, count = 0; |
f6981439 | 106 | u32 cluster, type, mask = 0; |
123bd96d YS |
107 | |
108 | do { | |
109 | int j; | |
f6981439 YS |
110 | cluster = in_be32(&gur->tp_cluster[i].lower); |
111 | for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { | |
112 | type = init_type(cluster, j); | |
113 | if (type) { | |
123bd96d YS |
114 | if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_PPC) |
115 | mask |= 1 << count; | |
f6981439 | 116 | count++; |
123bd96d | 117 | } |
123bd96d | 118 | } |
f6981439 | 119 | i++; |
123bd96d YS |
120 | } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); |
121 | ||
122 | return mask; | |
123 | } | |
f6981439 YS |
124 | |
125 | int fsl_qoriq_core_to_cluster(unsigned int core) | |
126 | { | |
127 | ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
128 | int i = 0, count = 0; | |
129 | u32 cluster; | |
130 | ||
131 | do { | |
132 | int j; | |
133 | cluster = in_be32(&gur->tp_cluster[i].lower); | |
134 | for (j = 0; j < TP_INIT_PER_CLUSTER; j++) { | |
135 | if (init_type(cluster, j)) { | |
136 | if (count == core) | |
137 | return i; | |
138 | count++; | |
139 | } | |
140 | } | |
141 | i++; | |
142 | } while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC); | |
143 | ||
144 | return -1; /* cannot identify the cluster */ | |
145 | } | |
146 | ||
123bd96d YS |
147 | #else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ |
148 | /* | |
149 | * Before chassis genenration 2, the cpumask should be hard-coded. | |
150 | * In case of cpu type unknown or cpumask unset, use 1 as fail save. | |
151 | */ | |
152 | #define compute_ppc_cpumask() 1 | |
f6981439 | 153 | #define fsl_qoriq_core_to_cluster(x) x |
123bd96d YS |
154 | #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ |
155 | ||
2ed2e912 | 156 | static struct cpu_type cpu_type_unknown = CPU_TYPE_ENTRY(Unknown, Unknown, 0); |
58442dc0 | 157 | |
18bacc20 PA |
158 | struct cpu_type *identify_cpu(u32 ver) |
159 | { | |
160 | int i; | |
161 | for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++) { | |
162 | if (cpu_type_list[i].soc_ver == ver) | |
163 | return &cpu_type_list[i]; | |
164 | } | |
58442dc0 | 165 | return &cpu_type_unknown; |
18bacc20 PA |
166 | } |
167 | ||
fbb9ecf7 TT |
168 | #define MPC8xxx_PICFRR_NCPU_MASK 0x00001f00 |
169 | #define MPC8xxx_PICFRR_NCPU_SHIFT 8 | |
170 | ||
171 | /* | |
172 | * Return a 32-bit mask indicating which cores are present on this SOC. | |
173 | */ | |
2ed2e912 | 174 | u32 cpu_mask(void) |
fbb9ecf7 TT |
175 | { |
176 | ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR; | |
67ac13b1 | 177 | struct cpu_type *cpu = gd->arch.cpu; |
fbb9ecf7 TT |
178 | |
179 | /* better to query feature reporting register than just assume 1 */ | |
180 | if (cpu == &cpu_type_unknown) | |
181 | return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >> | |
182 | MPC8xxx_PICFRR_NCPU_SHIFT) + 1; | |
183 | ||
123bd96d YS |
184 | if (cpu->num_cores == 0) |
185 | return compute_ppc_cpumask(); | |
186 | ||
fbb9ecf7 TT |
187 | return cpu->mask; |
188 | } | |
189 | ||
190 | /* | |
191 | * Return the number of cores on this SOC. | |
192 | */ | |
2ed2e912 KP |
193 | int cpu_numcores(void) |
194 | { | |
67ac13b1 | 195 | struct cpu_type *cpu = gd->arch.cpu; |
a37c36f4 | 196 | |
123bd96d YS |
197 | /* |
198 | * Report # of cores in terms of the cpu_mask if we haven't | |
199 | * figured out how many there are yet | |
200 | */ | |
201 | if (cpu->num_cores == 0) | |
202 | return hweight32(cpu_mask()); | |
a37c36f4 | 203 | |
0e870980 PA |
204 | return cpu->num_cores; |
205 | } | |
206 | ||
fbb9ecf7 TT |
207 | /* |
208 | * Check if the given core ID is valid | |
209 | * | |
210 | * Returns zero if it isn't, 1 if it is. | |
211 | */ | |
212 | int is_core_valid(unsigned int core) | |
213 | { | |
123bd96d | 214 | return !!((1 << core) & cpu_mask()); |
fbb9ecf7 TT |
215 | } |
216 | ||
0e870980 PA |
217 | int probecpu (void) |
218 | { | |
219 | uint svr; | |
220 | uint ver; | |
221 | ||
222 | svr = get_svr(); | |
223 | ver = SVR_SOC_VER(svr); | |
224 | ||
67ac13b1 | 225 | gd->arch.cpu = identify_cpu(ver); |
0e870980 | 226 | |
0e870980 PA |
227 | return 0; |
228 | } | |
229 | ||
123bd96d YS |
230 | /* Once in memory, compute mask & # cores once and save them off */ |
231 | int fixup_cpu(void) | |
232 | { | |
67ac13b1 | 233 | struct cpu_type *cpu = gd->arch.cpu; |
123bd96d YS |
234 | |
235 | if (cpu->num_cores == 0) { | |
236 | cpu->mask = cpu_mask(); | |
237 | cpu->num_cores = cpu_numcores(); | |
238 | } | |
239 | ||
240 | return 0; | |
241 | } | |
242 | ||
18bacc20 PA |
243 | /* |
244 | * Initializes on-chip ethernet controllers. | |
245 | * to override, implement board_eth_init() | |
246 | */ | |
247 | int cpu_eth_init(bd_t *bis) | |
248 | { | |
249 | #if defined(CONFIG_ETHER_ON_FCC) | |
250 | fec_initialize(bis); | |
251 | #endif | |
252 | ||
253 | #if defined(CONFIG_UEC_ETH) | |
254 | uec_standard_init(bis); | |
255 | #endif | |
256 | ||
257 | #if defined(CONFIG_TSEC_ENET) || defined(CONFIG_MPC85XX_FEC) | |
258 | tsec_standard_init(bis); | |
259 | #endif | |
260 | ||
c916d7c9 KG |
261 | #ifdef CONFIG_FMAN_ENET |
262 | fm_standard_init(bis); | |
263 | #endif | |
18bacc20 PA |
264 | return 0; |
265 | } |