diff mbox

[3/5] ARM: l2x0: Errata fix for flush by Way operation can cause data corruption

Message ID 4dfaffa99292bf8e36791ea9a68de75e@mail.gmail.com (mailing list archive)
State Awaiting Upstream, archived
Delegated to: Tony Lindgren
Headers show

Commit Message

Santosh Shilimkar Feb. 15, 2011, 7:14 a.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5cff165..ebadd95 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1140,7 +1140,7 @@  config ARM_ERRATA_742231

 config PL310_ERRATA_588369
 	bool "Clean & Invalidate maintenance operations do not invalidate
clean lines"
-	depends on CACHE_L2X0 && ARCH_OMAP4
+	depends on CACHE_L2X0 && CACHE_PL310
 	help
 	   The PL310 L2 cache controller implements three types of Clean &
 	   Invalidate maintenance operations: by Physical Address
@@ -1177,6 +1177,17 @@  config ARM_ERRATA_743622
 	  visible impact on the overall performance or power consumption
of the
 	  processor.

+config PL310_ERRATA_727915
+	bool "Background Clean & Invalidate by Way operation can cause
data corruption"
+	depends on CACHE_L2X0 && CACHE_PL310
+	help
+	  PL310 implements the Clean & Invalidate by Way L2 cache
maintenance
+	  operation (offset 0x7FC). This operation runs in background so
that
+	  PL310 can handle normal accesses while it is in progress. Under
very
+	  rare circumstances, due to this erratum, write data can be lost
when
+	  PL310 treats a cacheable write transaction during a Clean &
+	  Invalidate by Way operation Note that this errata uses Texas
+	  Instrument's secure monitor api to implement the work around.
 endmenu

 source "arch/arm/common/Kconfig"
diff --git a/arch/arm/include/asm/outercache.h
b/arch/arm/include/asm/outercache.h
index fc19009..348d513 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -31,6 +31,7 @@  struct outer_cache_fns {
 #ifdef CONFIG_OUTER_CACHE_SYNC
 	void (*sync)(void);
 #endif
+	void (*set_debug)(unsigned long);
 };

 #ifdef CONFIG_OUTER_CACHE
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index f285dd7..fd11ab4 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -45,7 +45,10 @@  config ARCH_OMAP4
 	select CPU_V7
 	select ARM_GIC
 	select LOCAL_TIMERS
+	select CACHE_L2X0
+	select CACHE_PL310
 	select PL310_ERRATA_588369
+	select PL310_ERRATA_727915
 	select ARM_ERRATA_720789
 	select ARCH_HAS_OPP
 	select PM_OPP if PM
diff --git a/arch/arm/mach-omap2/omap4-common.c
b/arch/arm/mach-omap2/omap4-common.c
index 1926864..9ef8c29 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -52,6 +52,12 @@  static void omap4_l2x0_disable(void)
 	omap_smc1(0x102, 0x0);
 }

+static void omap4_l2x0_set_debug(unsigned long val)
+{
+	/* Program PL310 L2 Cache controller debug register */
+	omap_smc1(0x100, val);
+}
+
 static int __init omap_l2_cache_init(void)
 {
 	u32 aux_ctrl = 0;
@@ -99,6 +105,7 @@  static int __init omap_l2_cache_init(void)
 	 * specific one
 	*/
 	outer_cache.disable = omap4_l2x0_disable;
+	outer_cache.set_debug = omap4_l2x0_set_debug;

 	return 0;
 }
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 170c9bb..a8caee4 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -67,18 +67,22 @@  static inline void l2x0_inv_line(unsigned long addr)
 	writel_relaxed(addr, base + L2X0_INV_LINE_PA);
 }

-#ifdef CONFIG_PL310_ERRATA_588369
+#if defined(CONFIG_PL310_ERRATA_588369) ||
defined(CONFIG_PL310_ERRATA_727915)
 static void debug_writel(unsigned long val)
 {
-	extern void omap_smc1(u32 fn, u32 arg);
-
-	/*
-	 * Texas Instrument secure monitor api to modify the
-	 * PL310 Debug Control Register.
-	 */
-	omap_smc1(0x100, val);
+	if (outer_cache.set_debug)
+		outer_cache.set_debug(val);
+	else
+		writel(val, l2x0_base + L2X0_DEBUG_CTRL);
+}
+#else
+/* Optimised out for non-errata case */
+static inline void debug_writel(unsigned long val)
+{
 }
+#endif

+#ifdef CONFIG_PL310_ERRATA_588369
 static inline void l2x0_flush_line(unsigned long addr)
 {