diff options
| -rw-r--r-- | arch/arm/Kconfig | 15 | ||||
| -rw-r--r-- | arch/arm/include/asm/outercache.h | 1 | ||||
| -rw-r--r-- | arch/arm/mm/cache-l2x0.c | 32 | 
3 files changed, 31 insertions, 17 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 65ea7bb57c4..ef41f7e39f6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1135,7 +1135,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  	help  	   The PL310 L2 cache controller implements three types of Clean &  	   Invalidate maintenance operations: by Physical Address @@ -1144,8 +1144,7 @@ config PL310_ERRATA_588369  	   clean operation followed immediately by an invalidate operation,  	   both performing to the same memory location. This functionality  	   is not correctly implemented in PL310 as clean lines are not -	   invalidated as a result of these operations. Note that this errata -	   uses Texas Instrument's secure monitor api. +	   invalidated as a result of these operations.  config ARM_ERRATA_720789  	bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" @@ -1172,6 +1171,16 @@ 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 +	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.  endmenu  source "arch/arm/common/Kconfig" diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h index fc190092527..348d513afa9 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/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 170c9bb9586..803bce8845a 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -67,18 +67,24 @@ static inline void l2x0_inv_line(unsigned long addr)  	writel_relaxed(addr, base + L2X0_INV_LINE_PA);  } -#ifdef CONFIG_PL310_ERRATA_588369 -static void debug_writel(unsigned long val) -{ -	extern void omap_smc1(u32 fn, u32 arg); +#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) -	/* -	 * Texas Instrument secure monitor api to modify the -	 * PL310 Debug Control Register. -	 */ -	omap_smc1(0x100, val); +#define debug_writel(val)	outer_cache.set_debug(val) + +static void l2x0_set_debug(unsigned long val) +{ +	writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL);  } +#else +/* Optimised out for non-errata case */ +static inline void debug_writel(unsigned long val) +{ +} + +#define l2x0_set_debug	NULL +#endif +#ifdef CONFIG_PL310_ERRATA_588369  static inline void l2x0_flush_line(unsigned long addr)  {  	void __iomem *base = l2x0_base; @@ -91,11 +97,6 @@ static inline void l2x0_flush_line(unsigned long addr)  }  #else -/* Optimised out for non-errata case */ -static inline void debug_writel(unsigned long val) -{ -} -  static inline void l2x0_flush_line(unsigned long addr)  {  	void __iomem *base = l2x0_base; @@ -119,9 +120,11 @@ static void l2x0_flush_all(void)  	/* clean all ways */  	spin_lock_irqsave(&l2x0_lock, flags); +	debug_writel(0x03);  	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);  	cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);  	cache_sync(); +	debug_writel(0x00);  	spin_unlock_irqrestore(&l2x0_lock, flags);  } @@ -329,6 +332,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)  	outer_cache.flush_all = l2x0_flush_all;  	outer_cache.inv_all = l2x0_inv_all;  	outer_cache.disable = l2x0_disable; +	outer_cache.set_debug = l2x0_set_debug;  	printk(KERN_INFO "%s cache controller enabled\n", type);  	printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n",  |