Commit f4ca3dc0b69c2bd4c6a40ae1551578e2a4b1cbd3

Authored by Sricharan R
Committed by Rajendra Nayak
1 parent 86617f774a

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

... ... @@ -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: