1
0
Fork 0

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>
hifive-unleashed-5.1
Jonas Gorski 2013-03-21 14:03:16 +00:00 committed by Ralf Baechle
parent 6605428c50
commit 13be798c57
1 changed files with 42 additions and 45 deletions

View File

@ -240,53 +240,27 @@ static unsigned int detect_memory_size(void)
void __init bcm63xx_cpu_init(void)
{
unsigned int tmp, expected_cpu_id;
unsigned int tmp;
struct cpuinfo_mips *c = &current_cpu_data;
unsigned int cpu = smp_processor_id();
u32 chipid_reg;
/* soc registers location depends on cpu type */
expected_cpu_id = 0;
chipid_reg = 0;
switch (c->cputype) {
case CPU_BMIPS3300:
if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) {
expected_cpu_id = BCM6348_CPU_ID;
bcm63xx_regs_base = bcm6348_regs_base;
bcm63xx_irqs = bcm6348_irqs;
} else {
if ((read_c0_prid() & 0xff00) != PRID_IMP_BMIPS3300_ALT)
__cpu_name[cpu] = "Broadcom BCM6338";
expected_cpu_id = BCM6338_CPU_ID;
bcm63xx_regs_base = bcm6338_regs_base;
bcm63xx_irqs = bcm6338_irqs;
}
break;
/* fall-through */
case CPU_BMIPS32:
expected_cpu_id = BCM6345_CPU_ID;
bcm63xx_regs_base = bcm6345_regs_base;
bcm63xx_irqs = bcm6345_irqs;
chipid_reg = BCM_6345_PERF_BASE;
break;
case CPU_BMIPS4350:
if ((read_c0_prid() & 0xf0) == 0x10) {
expected_cpu_id = BCM6358_CPU_ID;
bcm63xx_regs_base = bcm6358_regs_base;
bcm63xx_irqs = bcm6358_irqs;
} else {
/* all newer chips have the same chip id location */
u16 chip_id = bcm_readw(BCM_6368_PERF_BASE);
switch (chip_id) {
case BCM6328_CPU_ID:
expected_cpu_id = BCM6328_CPU_ID;
bcm63xx_regs_base = bcm6328_regs_base;
bcm63xx_irqs = bcm6328_irqs;
break;
case BCM6368_CPU_ID:
expected_cpu_id = BCM6368_CPU_ID;
bcm63xx_regs_base = bcm6368_regs_base;
bcm63xx_irqs = bcm6368_irqs;
break;
}
}
if ((read_c0_prid() & 0xf0) == 0x10)
chipid_reg = BCM_6345_PERF_BASE;
else
chipid_reg = BCM_6368_PERF_BASE;
break;
}
@ -294,20 +268,43 @@ void __init bcm63xx_cpu_init(void)
* really early to panic, but delaying panic would not help since we
* will never get any working console
*/
if (!expected_cpu_id)
if (!chipid_reg)
panic("unsupported Broadcom CPU");
/*
* bcm63xx_regs_base is set, we can access soc registers
*/
/* double check CPU type */
tmp = bcm_perf_readl(PERF_REV_REG);
/* read out CPU type */
tmp = bcm_readl(chipid_reg);
bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
if (bcm63xx_cpu_id != expected_cpu_id)
panic("bcm63xx CPU id mismatch");
switch (bcm63xx_cpu_id) {
case BCM6328_CPU_ID:
bcm63xx_regs_base = bcm6328_regs_base;
bcm63xx_irqs = bcm6328_irqs;
break;
case BCM6338_CPU_ID:
bcm63xx_regs_base = bcm6338_regs_base;
bcm63xx_irqs = bcm6338_irqs;
break;
case BCM6345_CPU_ID:
bcm63xx_regs_base = bcm6345_regs_base;
bcm63xx_irqs = bcm6345_irqs;
break;
case BCM6348_CPU_ID:
bcm63xx_regs_base = bcm6348_regs_base;
bcm63xx_irqs = bcm6348_irqs;
break;
case BCM6358_CPU_ID:
bcm63xx_regs_base = bcm6358_regs_base;
bcm63xx_irqs = bcm6358_irqs;
break;
case BCM6368_CPU_ID:
bcm63xx_regs_base = bcm6368_regs_base;
bcm63xx_irqs = bcm6368_irqs;
break;
default:
panic("unsupported broadcom CPU %x", bcm63xx_cpu_id);
break;
}
bcm63xx_cpu_freq = detect_cpu_clock();
bcm63xx_memory_size = detect_memory_size();