diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-secure.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-smp.c | 48 |
3 files changed, 52 insertions, 5 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 0517f0c1581a..a63d3fe2ca46 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -240,4 +240,12 @@ endmenu | |||
240 | 240 | ||
241 | endif | 241 | endif |
242 | 242 | ||
243 | config OMAP5_ERRATA_801819 | ||
244 | bool "Errata 801819: An eviction from L1 data cache might stall indefinitely" | ||
245 | depends on SOC_OMAP5 || SOC_DRA7XX | ||
246 | help | ||
247 | A livelock can occur in the L2 cache arbitration that might prevent | ||
248 | a snoop from completing. Under certain conditions this can cause the | ||
249 | system to deadlock. | ||
250 | |||
243 | endmenu | 251 | endmenu |
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h index af2851fbcdf0..bae263fba640 100644 --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | #define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109 | 47 | #define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109 |
48 | #define OMAP5_MON_AMBA_IF_INDEX 0x108 | 48 | #define OMAP5_MON_AMBA_IF_INDEX 0x108 |
49 | #define OMAP5_DRA7_MON_SET_ACR_INDEX 0x107 | ||
49 | 50 | ||
50 | /* Secure PPA(Primary Protected Application) APIs */ | 51 | /* Secure PPA(Primary Protected Application) APIs */ |
51 | #define OMAP4_PPA_L2_POR_INDEX 0x23 | 52 | #define OMAP4_PPA_L2_POR_INDEX 0x23 |
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index c625cc10d9f9..8cd1de914ee4 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -50,6 +50,39 @@ void __iomem *omap4_get_scu_base(void) | |||
50 | return scu_base; | 50 | return scu_base; |
51 | } | 51 | } |
52 | 52 | ||
53 | #ifdef CONFIG_OMAP5_ERRATA_801819 | ||
54 | void omap5_erratum_workaround_801819(void) | ||
55 | { | ||
56 | u32 acr, revidr; | ||
57 | u32 acr_mask; | ||
58 | |||
59 | /* REVIDR[3] indicates erratum fix available on silicon */ | ||
60 | asm volatile ("mrc p15, 0, %0, c0, c0, 6" : "=r" (revidr)); | ||
61 | if (revidr & (0x1 << 3)) | ||
62 | return; | ||
63 | |||
64 | asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr)); | ||
65 | /* | ||
66 | * BIT(27) - Disables streaming. All write-allocate lines allocate in | ||
67 | * the L1 or L2 cache. | ||
68 | * BIT(25) - Disables streaming. All write-allocate lines allocate in | ||
69 | * the L1 cache. | ||
70 | */ | ||
71 | acr_mask = (0x3 << 25) | (0x3 << 27); | ||
72 | /* do we already have it done.. if yes, skip expensive smc */ | ||
73 | if ((acr & acr_mask) == acr_mask) | ||
74 | return; | ||
75 | |||
76 | acr |= acr_mask; | ||
77 | omap_smc1(OMAP5_DRA7_MON_SET_ACR_INDEX, acr); | ||
78 | |||
79 | pr_debug("%s: ARM erratum workaround 801819 applied on CPU%d\n", | ||
80 | __func__, smp_processor_id()); | ||
81 | } | ||
82 | #else | ||
83 | static inline void omap5_erratum_workaround_801819(void) { } | ||
84 | #endif | ||
85 | |||
53 | static void omap4_secondary_init(unsigned int cpu) | 86 | static void omap4_secondary_init(unsigned int cpu) |
54 | { | 87 | { |
55 | /* | 88 | /* |
@@ -64,12 +97,15 @@ static void omap4_secondary_init(unsigned int cpu) | |||
64 | omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, | 97 | omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX, |
65 | 4, 0, 0, 0, 0, 0); | 98 | 4, 0, 0, 0, 0, 0); |
66 | 99 | ||
67 | /* | 100 | if (soc_is_omap54xx() || soc_is_dra7xx()) { |
68 | * Configure the CNTFRQ register for the secondary cpu's which | 101 | /* |
69 | * indicates the frequency of the cpu local timers. | 102 | * Configure the CNTFRQ register for the secondary cpu's which |
70 | */ | 103 | * indicates the frequency of the cpu local timers. |
71 | if (soc_is_omap54xx() || soc_is_dra7xx()) | 104 | */ |
72 | set_cntfreq(); | 105 | set_cntfreq(); |
106 | /* Configure ACR to disable streaming WA for 801819 */ | ||
107 | omap5_erratum_workaround_801819(); | ||
108 | } | ||
73 | 109 | ||
74 | /* | 110 | /* |
75 | * Synchronise with the boot thread. | 111 | * Synchronise with the boot thread. |
@@ -218,6 +254,8 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) | |||
218 | 254 | ||
219 | if (cpu_is_omap446x()) | 255 | if (cpu_is_omap446x()) |
220 | startup_addr = omap4460_secondary_startup; | 256 | startup_addr = omap4460_secondary_startup; |
257 | if (soc_is_dra74x() || soc_is_omap54xx()) | ||
258 | omap5_erratum_workaround_801819(); | ||
221 | 259 | ||
222 | /* | 260 | /* |
223 | * Write the address of secondary startup routine into the | 261 | * Write the address of secondary startup routine into the |