diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 15 | ||||
-rw-r--r-- | arch/arm/include/asm/hardware/cache-l2x0.h | 1 | ||||
-rw-r--r-- | arch/arm/mm/cache-l2x0.c | 6 |
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 | ||
1180 | config 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 | |||
1180 | endmenu | 1195 | endmenu |
1181 | 1196 | ||
1182 | source "arch/arm/common/Kconfig" | 1197 | source "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) | |||
49 | static inline void cache_sync(void) | 49 | static 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 | ||