diff options
Diffstat (limited to 'arch/powerpc/kernel/dt_cpu_ftrs.c')
| -rw-r--r-- | arch/powerpc/kernel/dt_cpu_ftrs.c | 35 | 
1 files changed, 32 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index bd95318d2202..180b3a5d1001 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -101,7 +101,7 @@ static void __restore_cpu_cpufeatures(void)  	if (hv_mode) {  		mtspr(SPRN_LPID, 0);  		mtspr(SPRN_HFSCR, system_registers.hfscr); -		mtspr(SPRN_PCR, 0); +		mtspr(SPRN_PCR, PCR_MASK);  	}  	mtspr(SPRN_FSCR, system_registers.fscr); @@ -144,6 +144,7 @@ static void __init cpufeatures_setup_cpu(void)  		mtspr(SPRN_HFSCR, 0);  	}  	mtspr(SPRN_FSCR, 0); +	mtspr(SPRN_PCR, PCR_MASK);  	/*  	 * LPCR does not get cleared, to match behaviour with secondaries @@ -691,9 +692,37 @@ static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f)  	return true;  } +/* + * Handle POWER9 broadcast tlbie invalidation issue using + * cpu feature flag. + */ +static __init void update_tlbie_feature_flag(unsigned long pvr) +{ +	if (PVR_VER(pvr) == PVR_POWER9) { +		/* +		 * Set the tlbie feature flag for anything below +		 * Nimbus DD 2.3 and Cumulus DD 1.3 +		 */ +		if ((pvr & 0xe000) == 0) { +			/* Nimbus */ +			if ((pvr & 0xfff) < 0x203) +				cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG; +		} else if ((pvr & 0xc000) == 0) { +			/* Cumulus */ +			if ((pvr & 0xfff) < 0x103) +				cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG; +		} else { +			WARN_ONCE(1, "Unknown PVR"); +			cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_STQ_BUG; +		} + +		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_ERAT_BUG; +	} +} +  static __init void cpufeatures_cpu_quirks(void)  { -	int version = mfspr(SPRN_PVR); +	unsigned long version = mfspr(SPRN_PVR);  	/*  	 * Not all quirks can be derived from the cpufeatures device tree. @@ -712,10 +741,10 @@ static __init void cpufeatures_cpu_quirks(void)  	if ((version & 0xffff0000) == 0x004e0000) {  		cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR); -		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TLBIE_BUG;  		cur_cpu_spec->cpu_features |= CPU_FTR_P9_TIDR;  	} +	update_tlbie_feature_flag(version);  	/*  	 * PKEY was not in the initial base or feature node  	 * specification, but it should become optional in the next  |