The erratum-773769 occurs on Arm Coretex-A15 (rev r2p0),
when L2 Data Ram latency is set to 4 cycles or more; or
when ACP is in use, or with L2 Data RAM slice configured.
Therefore, the effective latency as calculated in Table 7-2 of
Cotex-A15 (rev r2p0) trm should be 3 cycles or less.

On Exynos5250 based systems the effective data ram latency
is 4 cycles, since we have DATA_RAM_SETUP bit enabled (L2CTRL[5]=1b'1)
and DATA_RAM_LATENCY bits set to 0x2 (L2CTLR[2:0]=3b'010) therefore,
the effective L2 data RAM latency becomes 4 cycles.
So erratum '773769' occurs causing a corrupted L2 Cache.

This patch gives a workaround to the mentioned erratum, using below
mentioned algo:
----------------------------------------------------------------
if data RAM setup = 1
  then check if effective latency i.e (latency + setup + 1) > 3
  if 'true'
    then clear data RAM setup
      goto branch 'a'
if data RAM setup = 0
  a: then check if data RAM latency > 0x10
    if true then force data RAM latency = 0x10
----------------------------------------------------------------
so that the effective data RAM latency reduces to 3 cycles or less
and hence prevent hitting the erratum.

NOTE: The Exynos5250 based products have already been shipped, which
      makes it impossible to add the change in bootloader, so we are
      adding the required change in kernel.

Signed-off-by: Vivek Gautam <[email protected]>
Cc: Doug Anderson <[email protected]>
Cc: Olof Johansson <[email protected]>
Cc: David Garbett <[email protected]>
---
 arch/arm/Kconfig             |   15 ++++++++
 arch/arm/mach-exynos/Kconfig |    1 +
 arch/arm/mm/proc-v7.S        |   79 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 95 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c59fa19..2e6f36c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1250,6 +1250,21 @@ config ARM_ERRATA_751472
          operation is received by a CPU before the ICIALLUIS has completed,
          potentially leading to corrupted entries in the cache or TLB.
 
+config ARM_ERRATA_773769
+       bool "ARM errata: Large data RAM latencies can lead to rare data 
corruption"
+       depends on CPU_V7
+       help
+         This option enables the workaround for the erratum 773769, which 
affects
+         Cortex-A15 (rev r2p0).
+         In systems with L2 Data RAM latency programmed to 4 or more cycles,
+         or with ACP in use, or with a L2 Data RAM slice configured, it is
+         possible that a rare collision between non-cacheable stores and
+         L1 data cache evictions which can lead to data corruption in L2 cache
+         or memory.
+         This workaround is to configure an effective Data RAM latency of 3 or
+         less. Also note that, if a Data RAM slice is configured in A15 then
+         there is no workaround.
+
 config PL310_ERRATA_753970
        bool "PL310 errata: cache sync operation may be faulty"
        depends on CACHE_PL310
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 4c414af..29f505f 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -82,6 +82,7 @@ config SOC_EXYNOS5250
        default y
        depends on ARCH_EXYNOS5
        select ARCH_HAS_BANDGAP
+       select ARM_ERRATA_773769
        select PINCTRL_EXYNOS
        select PM_GENERIC_DOMAINS if PM
        select S5P_PM if PM
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index bd17819..0674c4c 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -141,6 +141,49 @@ ENTRY(cpu_v7_do_resume)
        mcr     p15, 0, r4, c10, c2, 0  @ write PRRR
        mcr     p15, 0, r5, c10, c2, 1  @ write NMRR
 #endif /* CONFIG_MMU */
+
+#ifdef CONFIG_ARM_ERRATA_773769
+       /* get the arm rev id */
+       mrc     p15, 0, r3, c0, c0, 0           @ read main ID register
+       and     r4, r3, #0xff000000             @ ARM?
+       teq     r4, #0x41000000
+       bne     8f
+       and     r5, r3, #0x00f00000             @ variant
+       and     r7, r3, #0x0000000f             @ revision
+       orr     r7, r7, r5, lsr #20-4           @ combine variant and revision
+       ubfx    r3, r3, #4, #12                 @ primary part number
+
+       ldr     r4, =0x00000c0f                 @ Cortex-A15 primary part number
+       teq     r3, r4
+       bne     8f
+
+       ALT_SMP(cmp r7, #0x21)                  @ present prior to r2p1
+       ALT_UP_B(8f)
+       mrclt   p15, 0, r3, c1, c0, 0           @ read system control register
+       andlt   r3, r3, #0x4                    @ mask for C bit
+       cmplt   r3, #0x0                        @ check if cache is on/off
+       bne     8f                              @ Do nothing when cache is on
+
+       mrceq   p15, 1, r5, c9, c0, 2           @ read L2 control register
+       andeq   r3, r5, #(1 << 5)               @ mask for data RAM setup
+       lsreq   r3, r3, #0x5
+       cmpeq   r3, #0x1                        @ check if data RAM setup = 1
+       bne     9f
+       and     r4, r5, #0x7                    @ mask for data RAM latency
+       add     r4, r4, r3
+       add     r4, r4, #0x1                    @ effective latency
+       cmp     r4, #0x3
+       bicgt   r5, r5, #(1 << 5)               @ clear data RAM setup bit
+
+9:     and     r4, r5, #0x7                    @ mask for data RAM latency
+       cmp     r4, #0x2                        @ check if data RAM latency > 2
+       ble     10f
+       bic     r5, r5, #0x7                    @ clear data RAM latency bits
+       orr     r5, r5, #0x2                    @ force data RAM latency = 2
+10:    mcr     p15, 1, r5, c9, c0, 2           @ set L2 control register
+8:
+#endif
+
        mrc     p15, 0, r4, c1, c0, 1   @ Read Auxiliary control register
        teq     r4, r9                  @ Is it already set?
        mcrne   p15, 0, r9, c1, c0, 1   @ No, so write it
@@ -349,6 +392,42 @@ __v7_setup:
        mcrle   p15, 0, r10, c1, c0, 1          @ write aux control register
 #endif
 
+#ifdef CONFIG_ARM_ERRATA_773769
+       ALT_SMP(cmp r6, #0x21)                  @ present prior to r2p1
+       ALT_UP_B(5f)
+       mrclt   p15, 0, r3, c1, c0, 0           @ read system control register
+       andlt   r3, r3, #0x4                    @ mask for C bit
+       cmplt   r3, #0x0                        @ check if cache is on/off
+       bne     5f                              @ Do nothing when cache is on
+       /*
+        * if data RAM setup = 1
+        *      then check if effective latency i.e (latency + setup + 1) > 3
+        *              if true then clear data RAM setup
+        *              goto branch 'a'
+        * if data RAM setup = 0
+        *      a: then check if data RAM latency > 0x10
+        *              if true then force data RAM latency = 0x10
+        */
+       mrceq   p15, 1, r5, c9, c0, 2           @ read L2 control register
+       andeq   r3, r5, #(1 << 5)               @ mask for data RAM setup
+       lsreq   r3, r3, #0x5
+       cmpeq   r3, #0x1                        @ check if data RAM setup = 1
+       bne     6f
+       and     r10, r5, #0x7                   @ mask for data RAM latency
+       add     r10, r10, r3
+       add     r10, r10, #0x1                  @ effective latency
+       cmp     r10, #0x3
+       bicgt   r5, r5, #(1 << 5)               @ clear data RAM setup bit
+
+6:     and     r10, r5, #0x7                   @ mask for data RAM latency
+       cmp     r10, #0x2                       @ check if data RAM latency > 2
+       ble     7f
+       bic     r5, r5, #0x7                    @ clear data RAM latency bits
+       orr     r5, r5, #0x2                    @ force data RAM latency = 2
+7:     mcr     p15, 1, r5, c9, c0, 2           @ set L2 control register
+5:
+#endif
+
 4:     mov     r10, #0
        mcr     p15, 0, r10, c7, c5, 0          @ I+BTB cache invalidate
        dsb
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to