aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSrinidhi Kasagar <srinidhi.kasagar@stericsson.com>2011-02-17 01:03:51 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-02-19 06:23:21 -0500
commit885028e4ba4caf49d565c96481e1a05220ecb517 (patch)
tree45be55a3aa9cbd14bf924e00f974c43a35c573bc /arch
parent0cc9d5257857608ba85885b75fcada13d359b5d1 (diff)
ARM: 6741/1: errata: pl310 cache sync operation may be faulty
The effect of cache sync operation is to drain the store buffer and wait for all internal buffers to be empty. In normal conditions, store buffer is able to merge the normal memory writes within its 32-byte data buffers. Due to this erratum present in r3p0, the effect of cache sync operation on the store buffer still remains when the operation completes. This means that the store buffer is always asked to drain and this prevents it from merging any further writes. This can severely affect performance on the write traffic esp. on Normal memory NC one. The proposed workaround is to replace the normal offset of cache sync operation(0x730) by another offset targeting an unmapped PL310 register 0x740. Signed-off-by: srinidhi kasagar <srinidhi.kasagar@stericsson.com> Acked-by: Linus Walleij <linus.walleij@stericsson.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig15
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h1
-rw-r--r--arch/arm/mm/cache-l2x0.c6
3 files changed, 22 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 26d45e5b636b..ba9fc213f344 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1177,6 +1177,21 @@ config ARM_ERRATA_743622
1177 visible impact on the overall performance or power consumption of the 1177 visible impact on the overall performance or power consumption of the
1178 processor. 1178 processor.
1179 1179
1180config ARM_ERRATA_753970
1181 bool "ARM errata: cache sync operation may be faulty"
1182 depends on CACHE_PL310
1183 help
1184 This option enables the workaround for the 753970 PL310 (r3p0) erratum.
1185
1186 Under some condition the effect of cache sync operation on
1187 the store buffer still remains when the operation completes.
1188 This means that the store buffer is always asked to drain and
1189 this prevents it from merging any further writes. The workaround
1190 is to replace the normal offset of cache sync operation (0x730)
1191 by another offset targeting an unmapped PL310 register 0x740.
1192 This has the same effect as the cache sync operation: store buffer
1193 drain and waiting for all buffers empty.
1194
1180endmenu 1195endmenu
1181 1196
1182source "arch/arm/common/Kconfig" 1197source "arch/arm/common/Kconfig"
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 5aeec1e1735c..16bd48031583 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -36,6 +36,7 @@
36#define L2X0_RAW_INTR_STAT 0x21C 36#define L2X0_RAW_INTR_STAT 0x21C
37#define L2X0_INTR_CLEAR 0x220 37#define L2X0_INTR_CLEAR 0x220
38#define L2X0_CACHE_SYNC 0x730 38#define L2X0_CACHE_SYNC 0x730
39#define L2X0_DUMMY_REG 0x740
39#define L2X0_INV_LINE_PA 0x770 40#define L2X0_INV_LINE_PA 0x770
40#define L2X0_INV_WAY 0x77C 41#define L2X0_INV_WAY 0x77C
41#define L2X0_CLEAN_LINE_PA 0x7B0 42#define L2X0_CLEAN_LINE_PA 0x7B0
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 170c9bb95866..f2ce38e085d2 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -49,7 +49,13 @@ static inline void cache_wait(void __iomem *reg, unsigned long mask)
49static inline void cache_sync(void) 49static inline void cache_sync(void)
50{ 50{
51 void __iomem *base = l2x0_base; 51 void __iomem *base = l2x0_base;
52
53#ifdef CONFIG_ARM_ERRATA_753970
54 /* write to an unmmapped register */
55 writel_relaxed(0, base + L2X0_DUMMY_REG);
56#else
52 writel_relaxed(0, base + L2X0_CACHE_SYNC); 57 writel_relaxed(0, base + L2X0_CACHE_SYNC);
58#endif
53 cache_wait(base + L2X0_CACHE_SYNC, 1); 59 cache_wait(base + L2X0_CACHE_SYNC, 1);
54} 60}
55 61