diff options
Diffstat (limited to 'arch/mips/bcm63xx/cpu.c')
-rw-r--r-- | arch/mips/bcm63xx/cpu.c | 142 |
1 files changed, 94 insertions, 48 deletions
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index a7afb289b15a..79fe32df5e96 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c | |||
@@ -25,7 +25,7 @@ const int *bcm63xx_irqs; | |||
25 | EXPORT_SYMBOL(bcm63xx_irqs); | 25 | EXPORT_SYMBOL(bcm63xx_irqs); |
26 | 26 | ||
27 | static u16 bcm63xx_cpu_id; | 27 | static u16 bcm63xx_cpu_id; |
28 | static u16 bcm63xx_cpu_rev; | 28 | static u8 bcm63xx_cpu_rev; |
29 | static unsigned int bcm63xx_cpu_freq; | 29 | static unsigned int bcm63xx_cpu_freq; |
30 | static unsigned int bcm63xx_memory_size; | 30 | static unsigned int bcm63xx_memory_size; |
31 | 31 | ||
@@ -71,6 +71,15 @@ static const int bcm6358_irqs[] = { | |||
71 | 71 | ||
72 | }; | 72 | }; |
73 | 73 | ||
74 | static const unsigned long bcm6362_regs_base[] = { | ||
75 | __GEN_CPU_REGS_TABLE(6362) | ||
76 | }; | ||
77 | |||
78 | static const int bcm6362_irqs[] = { | ||
79 | __GEN_CPU_IRQ_TABLE(6362) | ||
80 | |||
81 | }; | ||
82 | |||
74 | static const unsigned long bcm6368_regs_base[] = { | 83 | static const unsigned long bcm6368_regs_base[] = { |
75 | __GEN_CPU_REGS_TABLE(6368) | 84 | __GEN_CPU_REGS_TABLE(6368) |
76 | }; | 85 | }; |
@@ -87,7 +96,7 @@ u16 __bcm63xx_get_cpu_id(void) | |||
87 | 96 | ||
88 | EXPORT_SYMBOL(__bcm63xx_get_cpu_id); | 97 | EXPORT_SYMBOL(__bcm63xx_get_cpu_id); |
89 | 98 | ||
90 | u16 bcm63xx_get_cpu_rev(void) | 99 | u8 bcm63xx_get_cpu_rev(void) |
91 | { | 100 | { |
92 | return bcm63xx_cpu_rev; | 101 | return bcm63xx_cpu_rev; |
93 | } | 102 | } |
@@ -169,6 +178,42 @@ static unsigned int detect_cpu_clock(void) | |||
169 | return (16 * 1000000 * n1 * n2) / m1; | 178 | return (16 * 1000000 * n1 * n2) / m1; |
170 | } | 179 | } |
171 | 180 | ||
181 | case BCM6362_CPU_ID: | ||
182 | { | ||
183 | unsigned int tmp, mips_pll_fcvo; | ||
184 | |||
185 | tmp = bcm_misc_readl(MISC_STRAPBUS_6362_REG); | ||
186 | mips_pll_fcvo = (tmp & STRAPBUS_6362_FCVO_MASK) | ||
187 | >> STRAPBUS_6362_FCVO_SHIFT; | ||
188 | switch (mips_pll_fcvo) { | ||
189 | case 0x03: | ||
190 | case 0x0b: | ||
191 | case 0x13: | ||
192 | case 0x1b: | ||
193 | return 240000000; | ||
194 | case 0x04: | ||
195 | case 0x0c: | ||
196 | case 0x14: | ||
197 | case 0x1c: | ||
198 | return 160000000; | ||
199 | case 0x05: | ||
200 | case 0x0e: | ||
201 | case 0x16: | ||
202 | case 0x1e: | ||
203 | case 0x1f: | ||
204 | return 400000000; | ||
205 | case 0x06: | ||
206 | return 440000000; | ||
207 | case 0x07: | ||
208 | case 0x17: | ||
209 | return 384000000; | ||
210 | case 0x15: | ||
211 | case 0x1d: | ||
212 | return 200000000; | ||
213 | default: | ||
214 | return 320000000; | ||
215 | } | ||
216 | } | ||
172 | case BCM6368_CPU_ID: | 217 | case BCM6368_CPU_ID: |
173 | { | 218 | { |
174 | unsigned int tmp, p1, p2, ndiv, m1; | 219 | unsigned int tmp, p1, p2, ndiv, m1; |
@@ -205,7 +250,7 @@ static unsigned int detect_memory_size(void) | |||
205 | unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0; | 250 | unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0; |
206 | u32 val; | 251 | u32 val; |
207 | 252 | ||
208 | if (BCMCPU_IS_6328()) | 253 | if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) |
209 | return bcm_ddr_readl(DDR_CSEND_REG) << 24; | 254 | return bcm_ddr_readl(DDR_CSEND_REG) << 24; |
210 | 255 | ||
211 | if (BCMCPU_IS_6345()) { | 256 | if (BCMCPU_IS_6345()) { |
@@ -240,53 +285,27 @@ static unsigned int detect_memory_size(void) | |||
240 | 285 | ||
241 | void __init bcm63xx_cpu_init(void) | 286 | void __init bcm63xx_cpu_init(void) |
242 | { | 287 | { |
243 | unsigned int tmp, expected_cpu_id; | 288 | unsigned int tmp; |
244 | struct cpuinfo_mips *c = ¤t_cpu_data; | 289 | struct cpuinfo_mips *c = ¤t_cpu_data; |
245 | unsigned int cpu = smp_processor_id(); | 290 | unsigned int cpu = smp_processor_id(); |
291 | u32 chipid_reg; | ||
246 | 292 | ||
247 | /* soc registers location depends on cpu type */ | 293 | /* soc registers location depends on cpu type */ |
248 | expected_cpu_id = 0; | 294 | chipid_reg = 0; |
249 | 295 | ||
250 | switch (c->cputype) { | 296 | switch (c->cputype) { |
251 | case CPU_BMIPS3300: | 297 | case CPU_BMIPS3300: |
252 | if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) { | 298 | if ((read_c0_prid() & 0xff00) != PRID_IMP_BMIPS3300_ALT) |
253 | expected_cpu_id = BCM6348_CPU_ID; | ||
254 | bcm63xx_regs_base = bcm6348_regs_base; | ||
255 | bcm63xx_irqs = bcm6348_irqs; | ||
256 | } else { | ||
257 | __cpu_name[cpu] = "Broadcom BCM6338"; | 299 | __cpu_name[cpu] = "Broadcom BCM6338"; |
258 | expected_cpu_id = BCM6338_CPU_ID; | 300 | /* fall-through */ |
259 | bcm63xx_regs_base = bcm6338_regs_base; | ||
260 | bcm63xx_irqs = bcm6338_irqs; | ||
261 | } | ||
262 | break; | ||
263 | case CPU_BMIPS32: | 301 | case CPU_BMIPS32: |
264 | expected_cpu_id = BCM6345_CPU_ID; | 302 | chipid_reg = BCM_6345_PERF_BASE; |
265 | bcm63xx_regs_base = bcm6345_regs_base; | ||
266 | bcm63xx_irqs = bcm6345_irqs; | ||
267 | break; | 303 | break; |
268 | case CPU_BMIPS4350: | 304 | case CPU_BMIPS4350: |
269 | if ((read_c0_prid() & 0xf0) == 0x10) { | 305 | if ((read_c0_prid() & 0xf0) == 0x10) |
270 | expected_cpu_id = BCM6358_CPU_ID; | 306 | chipid_reg = BCM_6345_PERF_BASE; |
271 | bcm63xx_regs_base = bcm6358_regs_base; | 307 | else |
272 | bcm63xx_irqs = bcm6358_irqs; | 308 | chipid_reg = BCM_6368_PERF_BASE; |
273 | } else { | ||
274 | /* all newer chips have the same chip id location */ | ||
275 | u16 chip_id = bcm_readw(BCM_6368_PERF_BASE); | ||
276 | |||
277 | switch (chip_id) { | ||
278 | case BCM6328_CPU_ID: | ||
279 | expected_cpu_id = BCM6328_CPU_ID; | ||
280 | bcm63xx_regs_base = bcm6328_regs_base; | ||
281 | bcm63xx_irqs = bcm6328_irqs; | ||
282 | break; | ||
283 | case BCM6368_CPU_ID: | ||
284 | expected_cpu_id = BCM6368_CPU_ID; | ||
285 | bcm63xx_regs_base = bcm6368_regs_base; | ||
286 | bcm63xx_irqs = bcm6368_irqs; | ||
287 | break; | ||
288 | } | ||
289 | } | ||
290 | break; | 309 | break; |
291 | } | 310 | } |
292 | 311 | ||
@@ -294,20 +313,47 @@ void __init bcm63xx_cpu_init(void) | |||
294 | * really early to panic, but delaying panic would not help since we | 313 | * really early to panic, but delaying panic would not help since we |
295 | * will never get any working console | 314 | * will never get any working console |
296 | */ | 315 | */ |
297 | if (!expected_cpu_id) | 316 | if (!chipid_reg) |
298 | panic("unsupported Broadcom CPU"); | 317 | panic("unsupported Broadcom CPU"); |
299 | 318 | ||
300 | /* | 319 | /* read out CPU type */ |
301 | * bcm63xx_regs_base is set, we can access soc registers | 320 | tmp = bcm_readl(chipid_reg); |
302 | */ | ||
303 | |||
304 | /* double check CPU type */ | ||
305 | tmp = bcm_perf_readl(PERF_REV_REG); | ||
306 | bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT; | 321 | bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT; |
307 | bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT; | 322 | bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT; |
308 | 323 | ||
309 | if (bcm63xx_cpu_id != expected_cpu_id) | 324 | switch (bcm63xx_cpu_id) { |
310 | panic("bcm63xx CPU id mismatch"); | 325 | case BCM6328_CPU_ID: |
326 | bcm63xx_regs_base = bcm6328_regs_base; | ||
327 | bcm63xx_irqs = bcm6328_irqs; | ||
328 | break; | ||
329 | case BCM6338_CPU_ID: | ||
330 | bcm63xx_regs_base = bcm6338_regs_base; | ||
331 | bcm63xx_irqs = bcm6338_irqs; | ||
332 | break; | ||
333 | case BCM6345_CPU_ID: | ||
334 | bcm63xx_regs_base = bcm6345_regs_base; | ||
335 | bcm63xx_irqs = bcm6345_irqs; | ||
336 | break; | ||
337 | case BCM6348_CPU_ID: | ||
338 | bcm63xx_regs_base = bcm6348_regs_base; | ||
339 | bcm63xx_irqs = bcm6348_irqs; | ||
340 | break; | ||
341 | case BCM6358_CPU_ID: | ||
342 | bcm63xx_regs_base = bcm6358_regs_base; | ||
343 | bcm63xx_irqs = bcm6358_irqs; | ||
344 | break; | ||
345 | case BCM6362_CPU_ID: | ||
346 | bcm63xx_regs_base = bcm6362_regs_base; | ||
347 | bcm63xx_irqs = bcm6362_irqs; | ||
348 | break; | ||
349 | case BCM6368_CPU_ID: | ||
350 | bcm63xx_regs_base = bcm6368_regs_base; | ||
351 | bcm63xx_irqs = bcm6368_irqs; | ||
352 | break; | ||
353 | default: | ||
354 | panic("unsupported broadcom CPU %x", bcm63xx_cpu_id); | ||
355 | break; | ||
356 | } | ||
311 | 357 | ||
312 | bcm63xx_cpu_freq = detect_cpu_clock(); | 358 | bcm63xx_cpu_freq = detect_cpu_clock(); |
313 | bcm63xx_memory_size = detect_memory_size(); | 359 | bcm63xx_memory_size = detect_memory_size(); |