@@ -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"
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
@@ -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
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;
}
@@ -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)
{