diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-06-05 19:13:40 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-07-25 10:28:14 -0400 |
commit | f746929ffdc8a83c0e6092343d4475f6485e13d3 (patch) | |
tree | 3d8a782cdc5232e37dd21a7a3565d56a95b62080 | |
parent | 4e1f8a6f1d978f033f1751e2887b3a69fab3f878 (diff) |
Revert "ARM: OMAP4: remove dead kconfig option OMAP4_ERRATA_I688"
This reverts commit 606da4826b89b044b51e3a84958b802204cfe4c7.
We actually need this code for proper behaviour of OMAP4, and it needs
fixing a different way other than just removing the code. Disabling
code which is necessary in the hopes of persuing multiplatform kernels
is a stupid approach.
Acked-by: Tony Lindgren <tony@atomide.com>
Acked-by: Richard Woodruff <r-woodruff2@ti.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 21 | ||||
-rw-r--r-- | arch/arm/mach-omap2/common.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/common.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/io.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap-secure.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap4-common.c | 69 | ||||
-rw-r--r-- | arch/arm/mach-omap2/sleep44xx.S | 2 |
7 files changed, 105 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index ecc04ff13e95..2128441430ad 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -240,6 +240,27 @@ config OMAP3_SDRC_AC_TIMING | |||
240 | wish to say no. Selecting yes without understanding what is | 240 | wish to say no. Selecting yes without understanding what is |
241 | going on could result in system crashes; | 241 | going on could result in system crashes; |
242 | 242 | ||
243 | config OMAP4_ERRATA_I688 | ||
244 | bool "OMAP4 errata: Async Bridge Corruption" | ||
245 | depends on (ARCH_OMAP4 || SOC_OMAP5) && !ARCH_MULTIPLATFORM | ||
246 | select ARCH_HAS_BARRIERS | ||
247 | help | ||
248 | If a data is stalled inside asynchronous bridge because of back | ||
249 | pressure, it may be accepted multiple times, creating pointer | ||
250 | misalignment that will corrupt next transfers on that data path | ||
251 | until next reset of the system (No recovery procedure once the | ||
252 | issue is hit, the path remains consistently broken). Async bridge | ||
253 | can be found on path between MPU to EMIF and MPU to L3 interconnect. | ||
254 | This situation can happen only when the idle is initiated by a | ||
255 | Master Request Disconnection (which is trigged by software when | ||
256 | executing WFI on CPU). | ||
257 | The work-around for this errata needs all the initiators connected | ||
258 | through async bridge must ensure that data path is properly drained | ||
259 | before issuing WFI. This condition will be met if one Strongly ordered | ||
260 | access is performed to the target right before executing the WFI. | ||
261 | In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained. | ||
262 | IO barrier ensure that there is no synchronisation loss on initiators | ||
263 | operating on both interconnect port simultaneously. | ||
243 | endmenu | 264 | endmenu |
244 | 265 | ||
245 | endif | 266 | endif |
diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index eae6a0e87c90..484cdadfb187 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c | |||
@@ -30,4 +30,5 @@ int __weak omap_secure_ram_reserve_memblock(void) | |||
30 | void __init omap_reserve(void) | 30 | void __init omap_reserve(void) |
31 | { | 31 | { |
32 | omap_secure_ram_reserve_memblock(); | 32 | omap_secure_ram_reserve_memblock(); |
33 | omap_barrier_reserve_memblock(); | ||
33 | } | 34 | } |
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index cf3cf22ecd42..46e24581d624 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h | |||
@@ -200,6 +200,9 @@ void __init omap4_map_io(void); | |||
200 | void __init omap5_map_io(void); | 200 | void __init omap5_map_io(void); |
201 | void __init ti81xx_map_io(void); | 201 | void __init ti81xx_map_io(void); |
202 | 202 | ||
203 | /* omap_barriers_init() is OMAP4 only */ | ||
204 | void omap_barriers_init(void); | ||
205 | |||
203 | /** | 206 | /** |
204 | * omap_test_timeout - busy-loop, testing a condition | 207 | * omap_test_timeout - busy-loop, testing a condition |
205 | * @cond: condition to test until it evaluates to true | 208 | * @cond: condition to test until it evaluates to true |
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 820dde8b5b04..7743e3672f98 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -306,6 +306,7 @@ void __init am33xx_map_io(void) | |||
306 | void __init omap4_map_io(void) | 306 | void __init omap4_map_io(void) |
307 | { | 307 | { |
308 | iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); | 308 | iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); |
309 | omap_barriers_init(); | ||
309 | } | 310 | } |
310 | #endif | 311 | #endif |
311 | 312 | ||
@@ -313,6 +314,7 @@ void __init omap4_map_io(void) | |||
313 | void __init omap5_map_io(void) | 314 | void __init omap5_map_io(void) |
314 | { | 315 | { |
315 | iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc)); | 316 | iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc)); |
317 | omap_barriers_init(); | ||
316 | } | 318 | } |
317 | #endif | 319 | #endif |
318 | /* | 320 | /* |
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h index af2851fbcdf0..dec2b05d184b 100644 --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h | |||
@@ -70,6 +70,13 @@ extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs, | |||
70 | extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits); | 70 | extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits); |
71 | extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag); | 71 | extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag); |
72 | 72 | ||
73 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
74 | extern int omap_barrier_reserve_memblock(void); | ||
75 | #else | ||
76 | static inline void omap_barrier_reserve_memblock(void) | ||
77 | { } | ||
78 | #endif | ||
79 | |||
73 | #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER | 80 | #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER |
74 | void set_cntfreq(void); | 81 | void set_cntfreq(void); |
75 | #else | 82 | #else |
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 16350eefa66c..7bb116a6f86f 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c | |||
@@ -51,6 +51,75 @@ static void __iomem *twd_base; | |||
51 | 51 | ||
52 | #define IRQ_LOCALTIMER 29 | 52 | #define IRQ_LOCALTIMER 29 |
53 | 53 | ||
54 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
55 | /* Used to implement memory barrier on DRAM path */ | ||
56 | #define OMAP4_DRAM_BARRIER_VA 0xfe600000 | ||
57 | |||
58 | void __iomem *dram_sync, *sram_sync; | ||
59 | |||
60 | static phys_addr_t paddr; | ||
61 | static u32 size; | ||
62 | |||
63 | void omap_bus_sync(void) | ||
64 | { | ||
65 | if (dram_sync && sram_sync) { | ||
66 | writel_relaxed(readl_relaxed(dram_sync), dram_sync); | ||
67 | writel_relaxed(readl_relaxed(sram_sync), sram_sync); | ||
68 | isb(); | ||
69 | } | ||
70 | } | ||
71 | EXPORT_SYMBOL(omap_bus_sync); | ||
72 | |||
73 | static int __init omap4_sram_init(void) | ||
74 | { | ||
75 | struct device_node *np; | ||
76 | struct gen_pool *sram_pool; | ||
77 | |||
78 | np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu"); | ||
79 | if (!np) | ||
80 | pr_warn("%s:Unable to allocate sram needed to handle errata I688\n", | ||
81 | __func__); | ||
82 | sram_pool = of_get_named_gen_pool(np, "sram", 0); | ||
83 | if (!sram_pool) | ||
84 | pr_warn("%s:Unable to get sram pool needed to handle errata I688\n", | ||
85 | __func__); | ||
86 | else | ||
87 | sram_sync = (void *)gen_pool_alloc(sram_pool, PAGE_SIZE); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | omap_arch_initcall(omap4_sram_init); | ||
92 | |||
93 | /* Steal one page physical memory for barrier implementation */ | ||
94 | int __init omap_barrier_reserve_memblock(void) | ||
95 | { | ||
96 | |||
97 | size = ALIGN(PAGE_SIZE, SZ_1M); | ||
98 | paddr = arm_memblock_steal(size, SZ_1M); | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | void __init omap_barriers_init(void) | ||
104 | { | ||
105 | struct map_desc dram_io_desc[1]; | ||
106 | |||
107 | dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA; | ||
108 | dram_io_desc[0].pfn = __phys_to_pfn(paddr); | ||
109 | dram_io_desc[0].length = size; | ||
110 | dram_io_desc[0].type = MT_MEMORY_RW_SO; | ||
111 | iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc)); | ||
112 | dram_sync = (void __iomem *) dram_io_desc[0].virtual; | ||
113 | |||
114 | pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n", | ||
115 | (long long) paddr, dram_io_desc[0].virtual); | ||
116 | |||
117 | } | ||
118 | #else | ||
119 | void __init omap_barriers_init(void) | ||
120 | {} | ||
121 | #endif | ||
122 | |||
54 | void gic_dist_disable(void) | 123 | void gic_dist_disable(void) |
55 | { | 124 | { |
56 | if (gic_dist_base_addr) | 125 | if (gic_dist_base_addr) |
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index ad1bb9431e94..b84a0122d823 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S | |||
@@ -333,9 +333,11 @@ ENDPROC(omap4_cpu_resume) | |||
333 | 333 | ||
334 | #endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */ | 334 | #endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */ |
335 | 335 | ||
336 | #ifndef CONFIG_OMAP4_ERRATA_I688 | ||
336 | ENTRY(omap_bus_sync) | 337 | ENTRY(omap_bus_sync) |
337 | ret lr | 338 | ret lr |
338 | ENDPROC(omap_bus_sync) | 339 | ENDPROC(omap_bus_sync) |
340 | #endif | ||
339 | 341 | ||
340 | ENTRY(omap_do_wfi) | 342 | ENTRY(omap_do_wfi) |
341 | stmfd sp!, {lr} | 343 | stmfd sp!, {lr} |