mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 23:34:05 +08:00
ARM: 7855/1: Add check for Cortex-A15 errata 798181 ECO
The work-around for A15 errata 798181 is not needed if appropriate ECO fixes have been applied to r3p2 and earlier core revisions. This can be checked by reading REVIDR register bits 4 and 9. If only bit 4 is set, then the IPI broadcast can be skipped. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Reviewed-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
0cbad9c9df
commit
92871b94a5
@ -10,6 +10,7 @@
|
||||
#define CPUID_TLBTYPE 3
|
||||
#define CPUID_MPUIR 4
|
||||
#define CPUID_MPIDR 5
|
||||
#define CPUID_REVIDR 6
|
||||
|
||||
#ifdef CONFIG_CPU_V7M
|
||||
#define CPUID_EXT_PFR0 0x40
|
||||
|
@ -560,37 +560,6 @@ static inline void __flush_bp_all(void)
|
||||
asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero));
|
||||
}
|
||||
|
||||
#include <asm/cputype.h>
|
||||
#ifdef CONFIG_ARM_ERRATA_798181
|
||||
static inline int erratum_a15_798181(void)
|
||||
{
|
||||
unsigned int midr = read_cpuid_id();
|
||||
|
||||
/* Cortex-A15 r0p0..r3p2 affected */
|
||||
if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void dummy_flush_tlb_a15_erratum(void)
|
||||
{
|
||||
/*
|
||||
* Dummy TLBIMVAIS. Using the unmapped address 0 and ASID 0.
|
||||
*/
|
||||
asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0));
|
||||
dsb(ish);
|
||||
}
|
||||
#else
|
||||
static inline int erratum_a15_798181(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void dummy_flush_tlb_a15_erratum(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* flush_pmd_entry
|
||||
*
|
||||
@ -697,4 +666,21 @@ extern void flush_bp_all(void);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef CONFIG_ARM_ERRATA_798181
|
||||
extern void erratum_a15_798181_init(void);
|
||||
#else
|
||||
static inline void erratum_a15_798181_init(void) {}
|
||||
#endif
|
||||
extern bool (*erratum_a15_798181_handler)(void);
|
||||
|
||||
static inline bool erratum_a15_798181(void)
|
||||
{
|
||||
if (unlikely(IS_ENABLED(CONFIG_ARM_ERRATA_798181) &&
|
||||
erratum_a15_798181_handler))
|
||||
return erratum_a15_798181_handler();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -599,6 +599,8 @@ static void __init setup_processor(void)
|
||||
elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT);
|
||||
#endif
|
||||
|
||||
erratum_a15_798181_init();
|
||||
|
||||
feat_v6_fixup();
|
||||
|
||||
cacheid_init();
|
||||
|
@ -70,6 +70,40 @@ static inline void ipi_flush_bp_all(void *ignored)
|
||||
local_flush_bp_all();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_ERRATA_798181
|
||||
bool (*erratum_a15_798181_handler)(void);
|
||||
|
||||
static bool erratum_a15_798181_partial(void)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0));
|
||||
dsb(ish);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool erratum_a15_798181_broadcast(void)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0));
|
||||
dsb(ish);
|
||||
return true;
|
||||
}
|
||||
|
||||
void erratum_a15_798181_init(void)
|
||||
{
|
||||
unsigned int midr = read_cpuid_id();
|
||||
unsigned int revidr = read_cpuid(CPUID_REVIDR);
|
||||
|
||||
/* Cortex-A15 r0p0..r3p2 w/o ECO fix affected */
|
||||
if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2 ||
|
||||
(revidr & 0x210) == 0x210) {
|
||||
return;
|
||||
}
|
||||
if (revidr & 0x10)
|
||||
erratum_a15_798181_handler = erratum_a15_798181_partial;
|
||||
else
|
||||
erratum_a15_798181_handler = erratum_a15_798181_broadcast;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ipi_flush_tlb_a15_erratum(void *arg)
|
||||
{
|
||||
dmb();
|
||||
@ -80,7 +114,6 @@ static void broadcast_tlb_a15_erratum(void)
|
||||
if (!erratum_a15_798181())
|
||||
return;
|
||||
|
||||
dummy_flush_tlb_a15_erratum();
|
||||
smp_call_function(ipi_flush_tlb_a15_erratum, NULL, 1);
|
||||
}
|
||||
|
||||
@ -92,7 +125,6 @@ static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm)
|
||||
if (!erratum_a15_798181())
|
||||
return;
|
||||
|
||||
dummy_flush_tlb_a15_erratum();
|
||||
this_cpu = get_cpu();
|
||||
a15_erratum_get_cpumask(this_cpu, mm, &mask);
|
||||
smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user