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 <gautam.vivek@xxxxxxxxxxx> Cc: Doug Anderson <dianders@xxxxxxxxxxxx> Cc: Olof Johansson <olofj@xxxxxxxxxxxx> Cc: David Garbett <david.garbett@xxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html