Commit f4ca3dc0b69c2bd4c6a40ae1551578e2a4b1cbd3
Committed by
Rajendra Nayak
1 parent
86617f774a
Exists in
ti-linux-3.12.y
and in
3 other branches
ARM: Add 799270 erratum workaround
799270: Writing ACTLR.SMP when the L2 cache has been idle for an extended period may not work correctly. Description: If the L2 cache logic clock is stopped because of L2 inactivity, setting or clearing the ACTLR.SMP bit might not be effective. The bit is modified in the ACTLR, meaning a read of the register returns the updated value. However the logic that uses that bit retains the previous value. 1) The L2 cache block has been idle for 256 or more cycles with no memory requests from any core, no external snoops, and no ACP requests. 2) A CPU executes an “MCR p15,0,r0,c1,c0,1” instruction (write the ACTLR register) that modifies ACTLR[6]. Implications: If the errata conditions occur when the ACTLR.SMP bit is being set at boot, the instruction cache or TLB could become incoherent, as that CPU would not receive necessary DVM requests. Workaround: The following code must be executed with all interrupts disabled r1 must contain the value of an Non-cacheable, SO, or Dev memory location or register (typically a memory mapped register with no read side effects would be used) mrc p15,0,r0,c1,c0,1 ; read current value of ACTLR orr r0,r0,#0x40 ; set/clear SMP bit (ACTLR[6]) ldr r1, [r1] ; read a device register (location guaranteed not to hit the L1 cache) and r1,r1,#0 ; orr r0,r0,r1 ; create dummy dependency between dummy load and MCR to write SMP MCR p15,0,r0,c1,c0,1 ; Write CP15 ACTLR ISB DSB Signed-off-by: Sricharan R <r.sricharan@ti.com> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Showing 3 changed files with 45 additions and 0 deletions Side-by-side Diff
arch/arm/Kconfig
... | ... | @@ -1406,6 +1406,14 @@ |
1406 | 1406 | loop buffer may deliver incorrect instructions. This |
1407 | 1407 | workaround disables the loop buffer to avoid the erratum. |
1408 | 1408 | |
1409 | +config ARM_ERRATA_799270 | |
1410 | + bool "ARM errata: writing ACTLR.SMP when the L2 cache has been idle for an extended period may not work correctly" | |
1411 | + depends on CPU_V7 && SMP | |
1412 | + help | |
1413 | + This option enables the workaround for the 799270 Cortex-A15 | |
1414 | + (up to r2p4) erratum. If the L2 cache has been idle for 256 or more | |
1415 | + cycles and when the CPU executes the ACTLR to modify the SMP bit, it may | |
1416 | + not work correctly | |
1409 | 1417 | endmenu |
1410 | 1418 | |
1411 | 1419 | source "arch/arm/common/Kconfig" |
arch/arm/mm/proc-macros.S
... | ... | @@ -338,4 +338,29 @@ |
338 | 338 | .globl \x |
339 | 339 | .equ \x, \y |
340 | 340 | .endm |
341 | + | |
342 | +.macro write_actlr_smp x, y | |
343 | + mrc p15, 0, \x, c1, c0, 1 | |
344 | + orr \x, \x, #0x40 | |
345 | + ldr \y, __temp | |
346 | + and \y, \y, #0 | |
347 | + orr \x, \x, \y | |
348 | + mcr p15, 0, \x, c1, c0, 1 | |
349 | + isb | |
350 | + dsb | |
351 | +.endm | |
352 | + | |
353 | +.macro clear_actlr_smp x, y | |
354 | + mrc p15, 0, \x, c1, c0, 1 | |
355 | + bic \x, \x, #0x40 | |
356 | + ldr \y, __temp | |
357 | + and \y, \y, #0 | |
358 | + orr \x, \x, \y | |
359 | + mcr p15, 0, \x, c1, c0, 1 | |
360 | + isb | |
361 | + dsb | |
362 | +.endm | |
363 | + | |
364 | +__temp: | |
365 | + .space 4 |
arch/arm/mm/proc-v7.S
... | ... | @@ -136,7 +136,13 @@ |
136 | 136 | #endif /* CONFIG_MMU */ |
137 | 137 | mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register |
138 | 138 | teq r4, r9 @ Is it already set? |
139 | +#ifdef CONFIG_ARM_ERRATA_799270 | |
140 | + beq 1f | |
141 | + write_actlr_smp r9, r10 | |
142 | +#else | |
139 | 143 | mcrne p15, 0, r9, c1, c0, 1 @ No, so write it |
144 | +#endif | |
145 | +1: | |
140 | 146 | mcr p15, 0, r10, c1, c0, 2 @ Co-processor access control |
141 | 147 | isb |
142 | 148 | dsb |
143 | 149 | |
144 | 150 | |
... | ... | @@ -192,10 +198,16 @@ |
192 | 198 | ALT_SMP(mrc p15, 0, r0, c1, c0, 1) |
193 | 199 | ALT_UP(mov r0, #(1 << 6)) @ fake it for UP |
194 | 200 | tst r0, #(1 << 6) @ SMP/nAMP mode enabled? |
201 | +#ifdef ARM_ERRATA_799270 | |
202 | + bne 2f | |
203 | + write_actlr_smp r0, r12 | |
204 | +#else | |
195 | 205 | orreq r0, r0, #(1 << 6) @ Enable SMP/nAMP mode |
206 | +#endif | |
196 | 207 | orreq r0, r0, r10 @ Enable CPU-specific SMP bits |
197 | 208 | mcreq p15, 0, r0, c1, c0, 1 |
198 | 209 | #endif |
210 | +2: | |
199 | 211 | b __v7_setup |
200 | 212 | |
201 | 213 | __v7_pj4b_setup: |