diff options
| author | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
|---|---|---|
| committer | Mark Brown <[email protected]> | 2015-10-12 18:09:27 +0100 | 
| commit | 79828b4fa835f73cdaf4bffa48696abdcbea9d02 (patch) | |
| tree | 5e0fa7156acb75ba603022bc807df8f2fedb97a8 /arch/mips/kernel/cpu-probe.c | |
| parent | 721b51fcf91898299d96f4b72cb9434cda29dce6 (diff) | |
| parent | 8c1a9d6323abf0fb1e5dad96cf3f1c783505ea5a (diff) | |
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-fix-rt5645
Diffstat (limited to 'arch/mips/kernel/cpu-probe.c')
| -rw-r--r-- | arch/mips/kernel/cpu-probe.c | 56 | 
1 files changed, 46 insertions, 10 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index dbe0792fc9c1..571a8e6ea5bd 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -32,6 +32,9 @@  #include <asm/spram.h>  #include <asm/uaccess.h> +/* Hardware capabilities */ +unsigned int elf_hwcap __read_mostly; +  /*   * Get the FPU Implementation/Revision.   */ @@ -188,7 +191,7 @@ __setup("nohtw", htw_disable);  static int mips_ftlb_disabled;  static int mips_has_ftlb_configured; -static void set_ftlb_enable(struct cpuinfo_mips *c, int enable); +static int set_ftlb_enable(struct cpuinfo_mips *c, int enable);  static int __init ftlb_disable(char *s)  { @@ -202,7 +205,10 @@ static int __init ftlb_disable(char *s)  		return 1;  	/* Disable it in the boot cpu */ -	set_ftlb_enable(&cpu_data[0], 0); +	if (set_ftlb_enable(&cpu_data[0], 0)) { +		pr_warn("Can't turn FTLB off\n"); +		return 1; +	}  	back_to_back_c0_hazard(); @@ -364,30 +370,41 @@ static unsigned int calculate_ftlb_probability(struct cpuinfo_mips *c)  		return 3;  } -static void set_ftlb_enable(struct cpuinfo_mips *c, int enable) +static int set_ftlb_enable(struct cpuinfo_mips *c, int enable)  { -	unsigned int config6; +	unsigned int config;  	/* It's implementation dependent how the FTLB can be enabled */  	switch (c->cputype) {  	case CPU_PROAPTIV:  	case CPU_P5600:  		/* proAptiv & related cores use Config6 to enable the FTLB */ -		config6 = read_c0_config6(); +		config = read_c0_config6();  		/* Clear the old probability value */ -		config6 &= ~(3 << MIPS_CONF6_FTLBP_SHIFT); +		config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT);  		if (enable)  			/* Enable FTLB */ -			write_c0_config6(config6 | +			write_c0_config6(config |  					 (calculate_ftlb_probability(c)  					  << MIPS_CONF6_FTLBP_SHIFT)  					 | MIPS_CONF6_FTLBEN);  		else  			/* Disable FTLB */ -			write_c0_config6(config6 &  ~MIPS_CONF6_FTLBEN); -		back_to_back_c0_hazard(); +			write_c0_config6(config &  ~MIPS_CONF6_FTLBEN);  		break; +	case CPU_I6400: +		/* I6400 & related cores use Config7 to configure FTLB */ +		config = read_c0_config7(); +		/* Clear the old probability value */ +		config &= ~(3 << MIPS_CONF7_FTLBP_SHIFT); +		write_c0_config7(config | (calculate_ftlb_probability(c) +					   << MIPS_CONF7_FTLBP_SHIFT)); +		break; +	default: +		return 1;  	} + +	return 0;  }  static inline unsigned int decode_config0(struct cpuinfo_mips *c) @@ -524,6 +541,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c)  	}  	if (config3 & MIPS_CONF3_CDMM)  		c->options |= MIPS_CPU_CDMM; +	if (config3 & MIPS_CONF3_SP) +		c->options |= MIPS_CPU_SP;  	return config3 & MIPS_CONF_M;  } @@ -540,7 +559,16 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c)  	if (cpu_has_tlb) {  		if (((config4 & MIPS_CONF4_IE) >> 29) == 2)  			c->options |= MIPS_CPU_TLBINV; -		mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF; +		/* +		 * This is a bit ugly. R6 has dropped that field from +		 * config4 and the only valid configuration is VTLB+FTLB so +		 * set a good value for mmuextdef for that case. +		 */ +		if (cpu_has_mips_r6) +			mmuextdef = MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT; +		else +			mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF; +  		switch (mmuextdef) {  		case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:  			c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; @@ -1121,6 +1149,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)  		c->cputype = CPU_P5600;  		__cpu_name[cpu] = "MIPS P5600";  		break; +	case PRID_IMP_I6400: +		c->cputype = CPU_I6400; +		__cpu_name[cpu] = "MIPS I6400"; +		break;  	case PRID_IMP_M5150:  		c->cputype = CPU_M5150;  		__cpu_name[cpu] = "MIPS M5150"; @@ -1492,10 +1524,14 @@ void cpu_probe(void)  	else  		c->srsets = 1; +	if (cpu_has_mips_r6) +		elf_hwcap |= HWCAP_MIPS_R6; +  	if (cpu_has_msa) {  		c->msa_id = cpu_get_msa_id();  		WARN(c->msa_id & MSA_IR_WRPF,  		     "Vector register partitioning unimplemented!"); +		elf_hwcap |= HWCAP_MIPS_MSA;  	}  	cpu_probe_vmbits(c);  |