diff options
author | Jonas Gorski <jogo@openwrt.org> | 2013-03-21 10:03:16 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2013-05-07 19:19:03 -0400 |
commit | 13be798c57ebe5df09254832330f48c936ac39fd (patch) | |
tree | cca5018a85c958b937517f3e87868a60db25c5ca /arch/mips/bcm63xx/cpu.c | |
parent | 6605428c506bea269ca6c4aed85e97fbee2cbe7b (diff) |
MIPS: BCM63XX: rework chip detection
Instead of trying to use a correlation of cpu prid and chip id and
hoping they will always be unique, use the cpu prid to determine the
chip id register location and just read out the chip id.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/5008/
Acked-by: John Crispin <blogic@openwrt.org>
Diffstat (limited to 'arch/mips/bcm63xx/cpu.c')
-rw-r--r-- | arch/mips/bcm63xx/cpu.c | 87 |
1 files changed, 42 insertions, 45 deletions
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index ae16626d4001..fef168d85884 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c | |||
@@ -240,53 +240,27 @@ static unsigned int detect_memory_size(void) | |||
240 | 240 | ||
241 | void __init bcm63xx_cpu_init(void) | 241 | void __init bcm63xx_cpu_init(void) |
242 | { | 242 | { |
243 | unsigned int tmp, expected_cpu_id; | 243 | unsigned int tmp; |
244 | struct cpuinfo_mips *c = ¤t_cpu_data; | 244 | struct cpuinfo_mips *c = ¤t_cpu_data; |
245 | unsigned int cpu = smp_processor_id(); | 245 | unsigned int cpu = smp_processor_id(); |
246 | u32 chipid_reg; | ||
246 | 247 | ||
247 | /* soc registers location depends on cpu type */ | 248 | /* soc registers location depends on cpu type */ |
248 | expected_cpu_id = 0; | 249 | chipid_reg = 0; |
249 | 250 | ||
250 | switch (c->cputype) { | 251 | switch (c->cputype) { |
251 | case CPU_BMIPS3300: | 252 | case CPU_BMIPS3300: |
252 | if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) { | 253 | 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"; | 254 | __cpu_name[cpu] = "Broadcom BCM6338"; |
258 | expected_cpu_id = BCM6338_CPU_ID; | 255 | /* fall-through */ |
259 | bcm63xx_regs_base = bcm6338_regs_base; | ||
260 | bcm63xx_irqs = bcm6338_irqs; | ||
261 | } | ||
262 | break; | ||
263 | case CPU_BMIPS32: | 256 | case CPU_BMIPS32: |
264 | expected_cpu_id = BCM6345_CPU_ID; | 257 | chipid_reg = BCM_6345_PERF_BASE; |
265 | bcm63xx_regs_base = bcm6345_regs_base; | ||
266 | bcm63xx_irqs = bcm6345_irqs; | ||
267 | break; | 258 | break; |
268 | case CPU_BMIPS4350: | 259 | case CPU_BMIPS4350: |
269 | if ((read_c0_prid() & 0xf0) == 0x10) { | 260 | if ((read_c0_prid() & 0xf0) == 0x10) |
270 | expected_cpu_id = BCM6358_CPU_ID; | 261 | chipid_reg = BCM_6345_PERF_BASE; |
271 | bcm63xx_regs_base = bcm6358_regs_base; | 262 | else |
272 | bcm63xx_irqs = bcm6358_irqs; | 263 | 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; | 264 | break; |
291 | } | 265 | } |
292 | 266 | ||
@@ -294,20 +268,43 @@ void __init bcm63xx_cpu_init(void) | |||
294 | * really early to panic, but delaying panic would not help since we | 268 | * really early to panic, but delaying panic would not help since we |
295 | * will never get any working console | 269 | * will never get any working console |
296 | */ | 270 | */ |
297 | if (!expected_cpu_id) | 271 | if (!chipid_reg) |
298 | panic("unsupported Broadcom CPU"); | 272 | panic("unsupported Broadcom CPU"); |
299 | 273 | ||
300 | /* | 274 | /* read out CPU type */ |
301 | * bcm63xx_regs_base is set, we can access soc registers | 275 | 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; | 276 | bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT; |
307 | bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT; | 277 | bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT; |
308 | 278 | ||
309 | if (bcm63xx_cpu_id != expected_cpu_id) | 279 | switch (bcm63xx_cpu_id) { |
310 | panic("bcm63xx CPU id mismatch"); | 280 | case BCM6328_CPU_ID: |
281 | bcm63xx_regs_base = bcm6328_regs_base; | ||
282 | bcm63xx_irqs = bcm6328_irqs; | ||
283 | break; | ||
284 | case BCM6338_CPU_ID: | ||
285 | bcm63xx_regs_base = bcm6338_regs_base; | ||
286 | bcm63xx_irqs = bcm6338_irqs; | ||
287 | break; | ||
288 | case BCM6345_CPU_ID: | ||
289 | bcm63xx_regs_base = bcm6345_regs_base; | ||
290 | bcm63xx_irqs = bcm6345_irqs; | ||
291 | break; | ||
292 | case BCM6348_CPU_ID: | ||
293 | bcm63xx_regs_base = bcm6348_regs_base; | ||
294 | bcm63xx_irqs = bcm6348_irqs; | ||
295 | break; | ||
296 | case BCM6358_CPU_ID: | ||
297 | bcm63xx_regs_base = bcm6358_regs_base; | ||
298 | bcm63xx_irqs = bcm6358_irqs; | ||
299 | break; | ||
300 | case BCM6368_CPU_ID: | ||
301 | bcm63xx_regs_base = bcm6368_regs_base; | ||
302 | bcm63xx_irqs = bcm6368_irqs; | ||
303 | break; | ||
304 | default: | ||
305 | panic("unsupported broadcom CPU %x", bcm63xx_cpu_id); | ||
306 | break; | ||
307 | } | ||
311 | 308 | ||
312 | bcm63xx_cpu_freq = detect_cpu_clock(); | 309 | bcm63xx_cpu_freq = detect_cpu_clock(); |
313 | bcm63xx_memory_size = detect_memory_size(); | 310 | bcm63xx_memory_size = detect_memory_size(); |