aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm63xx/cpu.c
diff options
context:
space:
mode:
authorJonas Gorski <jogo@openwrt.org>2013-03-21 10:03:16 -0400
committerRalf Baechle <ralf@linux-mips.org>2013-05-07 19:19:03 -0400
commit13be798c57ebe5df09254832330f48c936ac39fd (patch)
treecca5018a85c958b937517f3e87868a60db25c5ca /arch/mips/bcm63xx/cpu.c
parent6605428c506bea269ca6c4aed85e97fbee2cbe7b (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.c87
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
241void __init bcm63xx_cpu_init(void) 241void __init bcm63xx_cpu_init(void)
242{ 242{
243 unsigned int tmp, expected_cpu_id; 243 unsigned int tmp;
244 struct cpuinfo_mips *c = &current_cpu_data; 244 struct cpuinfo_mips *c = &current_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();