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 a7afb289b15..79fe32df5e9 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c @@ -25,7 +25,7 @@ const int *bcm63xx_irqs;  EXPORT_SYMBOL(bcm63xx_irqs);  static u16 bcm63xx_cpu_id; -static u16 bcm63xx_cpu_rev; +static u8 bcm63xx_cpu_rev;  static unsigned int bcm63xx_cpu_freq;  static unsigned int bcm63xx_memory_size; @@ -71,6 +71,15 @@ static const int bcm6358_irqs[] = {  }; +static const unsigned long bcm6362_regs_base[] = { +	__GEN_CPU_REGS_TABLE(6362) +}; + +static const int bcm6362_irqs[] = { +	__GEN_CPU_IRQ_TABLE(6362) + +}; +  static const unsigned long bcm6368_regs_base[] = {  	__GEN_CPU_REGS_TABLE(6368)  }; @@ -87,7 +96,7 @@ u16 __bcm63xx_get_cpu_id(void)  EXPORT_SYMBOL(__bcm63xx_get_cpu_id); -u16 bcm63xx_get_cpu_rev(void) +u8 bcm63xx_get_cpu_rev(void)  {  	return bcm63xx_cpu_rev;  } @@ -169,6 +178,42 @@ static unsigned int detect_cpu_clock(void)  		return (16 * 1000000 * n1 * n2) / m1;  	} +	case BCM6362_CPU_ID: +	{ +		unsigned int tmp, mips_pll_fcvo; + +		tmp = bcm_misc_readl(MISC_STRAPBUS_6362_REG); +		mips_pll_fcvo = (tmp & STRAPBUS_6362_FCVO_MASK) +				>> STRAPBUS_6362_FCVO_SHIFT; +		switch (mips_pll_fcvo) { +		case 0x03: +		case 0x0b: +		case 0x13: +		case 0x1b: +			return 240000000; +		case 0x04: +		case 0x0c: +		case 0x14: +		case 0x1c: +			return 160000000; +		case 0x05: +		case 0x0e: +		case 0x16: +		case 0x1e: +		case 0x1f: +			return 400000000; +		case 0x06: +			return 440000000; +		case 0x07: +		case 0x17: +			return 384000000; +		case 0x15: +		case 0x1d: +			return 200000000; +		default: +			return 320000000; +		} +	}  	case BCM6368_CPU_ID:  	{  		unsigned int tmp, p1, p2, ndiv, m1; @@ -205,7 +250,7 @@ static unsigned int detect_memory_size(void)  	unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;  	u32 val; -	if (BCMCPU_IS_6328()) +	if (BCMCPU_IS_6328() || BCMCPU_IS_6362())  		return bcm_ddr_readl(DDR_CSEND_REG) << 24;  	if (BCMCPU_IS_6345()) { @@ -240,53 +285,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 = ¤t_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 +313,47 @@ 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 BCM6362_CPU_ID: +		bcm63xx_regs_base = bcm6362_regs_base; +		bcm63xx_irqs = bcm6362_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();  |