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 65ea7bb57c4d..ef41f7e39f69 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1135,7 +1135,7 @@ config ARM_ERRATA_742231 | |||
1135 | 1135 | ||
1136 | config PL310_ERRATA_588369 | 1136 | config PL310_ERRATA_588369 |
1137 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" | 1137 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" |
1138 | depends on CACHE_L2X0 && ARCH_OMAP4 | 1138 | depends on CACHE_L2X0 |
1139 | help | 1139 | help |
1140 | The PL310 L2 cache controller implements three types of Clean & | 1140 | The PL310 L2 cache controller implements three types of Clean & |
1141 | Invalidate maintenance operations: by Physical Address | 1141 | Invalidate maintenance operations: by Physical Address |
@@ -1144,8 +1144,7 @@ config PL310_ERRATA_588369 | |||
1144 | clean operation followed immediately by an invalidate operation, | 1144 | clean operation followed immediately by an invalidate operation, |
1145 | both performing to the same memory location. This functionality | 1145 | both performing to the same memory location. This functionality |
1146 | is not correctly implemented in PL310 as clean lines are not | 1146 | is not correctly implemented in PL310 as clean lines are not |
1147 | invalidated as a result of these operations. Note that this errata | 1147 | invalidated as a result of these operations. |
1148 | uses Texas Instrument's secure monitor api. | ||
1149 | 1148 | ||
1150 | config ARM_ERRATA_720789 | 1149 | config ARM_ERRATA_720789 |
1151 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" | 1150 | bool "ARM errata: TLBIASIDIS and TLBIMVAIS operations can broadcast a faulty ASID" |
@@ -1172,6 +1171,16 @@ config ARM_ERRATA_743622 | |||
1172 | visible impact on the overall performance or power consumption of the | 1171 | visible impact on the overall performance or power consumption of the |
1173 | processor. | 1172 | processor. |
1174 | 1173 | ||
1174 | config PL310_ERRATA_727915 | ||
1175 | bool "Background Clean & Invalidate by Way operation can cause data corruption" | ||
1176 | depends on CACHE_L2X0 | ||
1177 | help | ||
1178 | PL310 implements the Clean & Invalidate by Way L2 cache maintenance | ||
1179 | operation (offset 0x7FC). This operation runs in background so that | ||
1180 | PL310 can handle normal accesses while it is in progress. Under very | ||
1181 | rare circumstances, due to this erratum, write data can be lost when | ||
1182 | PL310 treats a cacheable write transaction during a Clean & | ||
1183 | Invalidate by Way operation. | ||
1175 | endmenu | 1184 | endmenu |
1176 | 1185 | ||
1177 | source "arch/arm/common/Kconfig" | 1186 | source "arch/arm/common/Kconfig" |
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h index fc1900925275..348d513afa92 100644 --- a/arch/arm/include/asm/outercache.h +++ b/arch/arm/include/asm/outercache.h | |||
@@ -31,6 +31,7 @@ struct outer_cache_fns { | |||
31 | #ifdef CONFIG_OUTER_CACHE_SYNC | 31 | #ifdef CONFIG_OUTER_CACHE_SYNC |
32 | void (*sync)(void); | 32 | void (*sync)(void); |
33 | #endif | 33 | #endif |
34 | void (*set_debug)(unsigned long); | ||
34 | }; | 35 | }; |
35 | 36 | ||
36 | #ifdef CONFIG_OUTER_CACHE | 37 | #ifdef CONFIG_OUTER_CACHE |
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 170c9bb95866..803bce8845a7 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) | |||
67 | writel_relaxed(addr, base + L2X0_INV_LINE_PA); | 67 | writel_relaxed(addr, base + L2X0_INV_LINE_PA); |
68 | } | 68 | } |
69 | 69 | ||
70 | #ifdef CONFIG_PL310_ERRATA_588369 | 70 | #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) |
71 | static void debug_writel(unsigned long val) | ||
72 | { | ||
73 | extern void omap_smc1(u32 fn, u32 arg); | ||
74 | 71 | ||
75 | /* | 72 | #define debug_writel(val) outer_cache.set_debug(val) |
76 | * Texas Instrument secure monitor api to modify the | 73 | |
77 | * PL310 Debug Control Register. | 74 | static void l2x0_set_debug(unsigned long val) |
78 | */ | 75 | { |
79 | omap_smc1(0x100, val); | 76 | writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); |
80 | } | 77 | } |
78 | #else | ||
79 | /* Optimised out for non-errata case */ | ||
80 | static inline void debug_writel(unsigned long val) | ||
81 | { | ||
82 | } | ||
83 | |||
84 | #define l2x0_set_debug NULL | ||
85 | #endif | ||
81 | 86 | ||
87 | #ifdef CONFIG_PL310_ERRATA_588369 | ||
82 | static inline void l2x0_flush_line(unsigned long addr) | 88 | static inline void l2x0_flush_line(unsigned long addr) |
83 | { | 89 | { |
84 | void __iomem *base = l2x0_base; | 90 | void __iomem *base = l2x0_base; |
@@ -91,11 +97,6 @@ static inline void l2x0_flush_line(unsigned long addr) | |||
91 | } | 97 | } |
92 | #else | 98 | #else |
93 | 99 | ||
94 | /* Optimised out for non-errata case */ | ||
95 | static inline void debug_writel(unsigned long val) | ||
96 | { | ||
97 | } | ||
98 | |||
99 | static inline void l2x0_flush_line(unsigned long addr) | 100 | static inline void l2x0_flush_line(unsigned long addr) |
100 | { | 101 | { |
101 | void __iomem *base = l2x0_base; | 102 | void __iomem *base = l2x0_base; |
@@ -119,9 +120,11 @@ static void l2x0_flush_all(void) | |||
119 | 120 | ||
120 | /* clean all ways */ | 121 | /* clean all ways */ |
121 | spin_lock_irqsave(&l2x0_lock, flags); | 122 | spin_lock_irqsave(&l2x0_lock, flags); |
123 | debug_writel(0x03); | ||
122 | writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); | 124 | writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); |
123 | cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); | 125 | cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); |
124 | cache_sync(); | 126 | cache_sync(); |
127 | debug_writel(0x00); | ||
125 | spin_unlock_irqrestore(&l2x0_lock, flags); | 128 | spin_unlock_irqrestore(&l2x0_lock, flags); |
126 | } | 129 | } |
127 | 130 | ||
@@ -329,6 +332,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) | |||
329 | outer_cache.flush_all = l2x0_flush_all; | 332 | outer_cache.flush_all = l2x0_flush_all; |
330 | outer_cache.inv_all = l2x0_inv_all; | 333 | outer_cache.inv_all = l2x0_inv_all; |
331 | outer_cache.disable = l2x0_disable; | 334 | outer_cache.disable = l2x0_disable; |
335 | outer_cache.set_debug = l2x0_set_debug; | ||
332 | 336 | ||
333 | printk(KERN_INFO "%s cache controller enabled\n", type); | 337 | printk(KERN_INFO "%s cache controller enabled\n", type); |
334 | printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", | 338 | printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", |