diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 21 | ||||
-rw-r--r-- | arch/arm/mach-omap2/include/mach/barriers.h | 31 | ||||
-rw-r--r-- | arch/arm/mach-omap2/io.c | 9 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap4-common.c | 51 | ||||
-rw-r--r-- | arch/arm/mach-omap2/sleep44xx.S | 8 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/sram.h | 6 | ||||
-rw-r--r-- | arch/arm/plat-omap/sram.c | 8 |
7 files changed, 133 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index b6625130831d..50f43942c1aa 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -353,6 +353,27 @@ config OMAP3_SDRC_AC_TIMING | |||
353 | wish to say no. Selecting yes without understanding what is | 353 | wish to say no. Selecting yes without understanding what is |
354 | going on could result in system crashes; | 354 | going on could result in system crashes; |
355 | 355 | ||
356 | config OMAP4_ERRATA_I688 | ||
357 | bool "OMAP4 errata: Async Bridge Corruption" | ||
358 | depends on ARCH_OMAP4 | ||
359 | select ARCH_HAS_BARRIERS | ||
360 | help | ||
361 | If a data is stalled inside asynchronous bridge because of back | ||
362 | pressure, it may be accepted multiple times, creating pointer | ||
363 | misalignment that will corrupt next transfers on that data path | ||
364 | until next reset of the system (No recovery procedure once the | ||
365 | issue is hit, the path remains consistently broken). Async bridge | ||
366 | can be found on path between MPU to EMIF and MPU to L3 interconnect. | ||
367 | This situation can happen only when the idle is initiated by a | ||
368 | Master Request Disconnection (which is trigged by software when | ||
369 | executing WFI on CPU). | ||
370 | The work-around for this errata needs all the initiators connected | ||
371 | through async bridge must ensure that data path is properly drained | ||
372 | before issuing WFI. This condition will be met if one Strongly ordered | ||
373 | access is performed to the target right before executing the WFI. | ||
374 | In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained. | ||
375 | IO barrier ensure that there is no synchronisation loss on initiators | ||
376 | operating on both interconnect port simultaneously. | ||
356 | endmenu | 377 | endmenu |
357 | 378 | ||
358 | endif | 379 | endif |
diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h new file mode 100644 index 000000000000..4fa72c7cc7cd --- /dev/null +++ b/arch/arm/mach-omap2/include/mach/barriers.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * OMAP memory barrier header. | ||
3 | * | ||
4 | * Copyright (C) 2011 Texas Instruments, Inc. | ||
5 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
6 | * Richard Woodruff <r-woodruff2@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef __MACH_BARRIERS_H | ||
23 | #define __MACH_BARRIERS_H | ||
24 | |||
25 | extern void omap_bus_sync(void); | ||
26 | |||
27 | #define rmb() dsb() | ||
28 | #define wmb() do { dsb(); outer_sync(); omap_bus_sync(); } while (0) | ||
29 | #define mb() wmb() | ||
30 | |||
31 | #endif /* __MACH_BARRIERS_H */ | ||
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 3f565dd2ea8d..65843390e7f0 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -237,6 +237,15 @@ static struct map_desc omap44xx_io_desc[] __initdata = { | |||
237 | .length = L4_EMU_44XX_SIZE, | 237 | .length = L4_EMU_44XX_SIZE, |
238 | .type = MT_DEVICE, | 238 | .type = MT_DEVICE, |
239 | }, | 239 | }, |
240 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
241 | { | ||
242 | .virtual = OMAP4_SRAM_VA, | ||
243 | .pfn = __phys_to_pfn(OMAP4_SRAM_PA), | ||
244 | .length = PAGE_SIZE, | ||
245 | .type = MT_MEMORY_SO, | ||
246 | }, | ||
247 | #endif | ||
248 | |||
240 | }; | 249 | }; |
241 | #endif | 250 | #endif |
242 | 251 | ||
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 1b93d31fe8e9..bc16c818c6b7 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c | |||
@@ -15,11 +15,14 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/memblock.h> | ||
18 | 19 | ||
19 | #include <asm/hardware/gic.h> | 20 | #include <asm/hardware/gic.h> |
20 | #include <asm/hardware/cache-l2x0.h> | 21 | #include <asm/hardware/cache-l2x0.h> |
22 | #include <asm/mach/map.h> | ||
21 | 23 | ||
22 | #include <plat/irqs.h> | 24 | #include <plat/irqs.h> |
25 | #include <plat/sram.h> | ||
23 | 26 | ||
24 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
25 | #include <mach/omap-wakeupgen.h> | 28 | #include <mach/omap-wakeupgen.h> |
@@ -33,6 +36,54 @@ static void __iomem *l2cache_base; | |||
33 | 36 | ||
34 | static void __iomem *sar_ram_base; | 37 | static void __iomem *sar_ram_base; |
35 | 38 | ||
39 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
40 | /* Used to implement memory barrier on DRAM path */ | ||
41 | #define OMAP4_DRAM_BARRIER_VA 0xfe600000 | ||
42 | |||
43 | void __iomem *dram_sync, *sram_sync; | ||
44 | |||
45 | void omap_bus_sync(void) | ||
46 | { | ||
47 | if (dram_sync && sram_sync) { | ||
48 | writel_relaxed(readl_relaxed(dram_sync), dram_sync); | ||
49 | writel_relaxed(readl_relaxed(sram_sync), sram_sync); | ||
50 | isb(); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | static int __init omap_barriers_init(void) | ||
55 | { | ||
56 | struct map_desc dram_io_desc[1]; | ||
57 | phys_addr_t paddr; | ||
58 | u32 size; | ||
59 | |||
60 | if (!cpu_is_omap44xx()) | ||
61 | return -ENODEV; | ||
62 | |||
63 | size = ALIGN(PAGE_SIZE, SZ_1M); | ||
64 | paddr = memblock_alloc(size, SZ_1M); | ||
65 | if (!paddr) { | ||
66 | pr_err("%s: failed to reserve 4 Kbytes\n", __func__); | ||
67 | return -ENOMEM; | ||
68 | } | ||
69 | memblock_free(paddr, size); | ||
70 | memblock_remove(paddr, size); | ||
71 | dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA; | ||
72 | dram_io_desc[0].pfn = __phys_to_pfn(paddr); | ||
73 | dram_io_desc[0].length = size; | ||
74 | dram_io_desc[0].type = MT_MEMORY_SO; | ||
75 | iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc)); | ||
76 | dram_sync = (void __iomem *) dram_io_desc[0].virtual; | ||
77 | sram_sync = (void __iomem *) OMAP4_SRAM_VA; | ||
78 | |||
79 | pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n", | ||
80 | (long long) paddr, dram_io_desc[0].virtual); | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | core_initcall(omap_barriers_init); | ||
85 | #endif | ||
86 | |||
36 | void __init gic_init_irq(void) | 87 | void __init gic_init_irq(void) |
37 | { | 88 | { |
38 | void __iomem *omap_irq_base; | 89 | void __iomem *omap_irq_base; |
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index 3154b63def35..abd283400490 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S | |||
@@ -325,8 +325,16 @@ skip_l2en: | |||
325 | ENDPROC(omap4_cpu_resume) | 325 | ENDPROC(omap4_cpu_resume) |
326 | #endif | 326 | #endif |
327 | 327 | ||
328 | #ifndef CONFIG_OMAP4_ERRATA_I688 | ||
329 | ENTRY(omap_bus_sync) | ||
330 | mov pc, lr | ||
331 | ENDPROC(omap_bus_sync) | ||
332 | #endif | ||
333 | |||
328 | ENTRY(omap_do_wfi) | 334 | ENTRY(omap_do_wfi) |
329 | stmfd sp!, {lr} | 335 | stmfd sp!, {lr} |
336 | /* Drain interconnect write buffers. */ | ||
337 | bl omap_bus_sync | ||
330 | 338 | ||
331 | /* | 339 | /* |
332 | * Execute an ISB instruction to ensure that all of the | 340 | * Execute an ISB instruction to ensure that all of the |
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h index f500fc34d065..75aa1b2bef51 100644 --- a/arch/arm/plat-omap/include/plat/sram.h +++ b/arch/arm/plat-omap/include/plat/sram.h | |||
@@ -95,6 +95,10 @@ static inline void omap_push_sram_idle(void) {} | |||
95 | */ | 95 | */ |
96 | #define OMAP2_SRAM_PA 0x40200000 | 96 | #define OMAP2_SRAM_PA 0x40200000 |
97 | #define OMAP3_SRAM_PA 0x40200000 | 97 | #define OMAP3_SRAM_PA 0x40200000 |
98 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
99 | #define OMAP4_SRAM_PA 0x40304000 | ||
100 | #define OMAP4_SRAM_VA 0xfe404000 | ||
101 | #else | ||
98 | #define OMAP4_SRAM_PA 0x40300000 | 102 | #define OMAP4_SRAM_PA 0x40300000 |
99 | 103 | #endif | |
100 | #endif | 104 | #endif |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 8b28664d1c62..ad6a71a00cef 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -40,7 +40,11 @@ | |||
40 | #define OMAP1_SRAM_PA 0x20000000 | 40 | #define OMAP1_SRAM_PA 0x20000000 |
41 | #define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) | 41 | #define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) |
42 | #define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) | 42 | #define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) |
43 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
44 | #define OMAP4_SRAM_PUB_PA OMAP4_SRAM_PA | ||
45 | #else | ||
43 | #define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) | 46 | #define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) |
47 | #endif | ||
44 | 48 | ||
45 | #if defined(CONFIG_ARCH_OMAP2PLUS) | 49 | #if defined(CONFIG_ARCH_OMAP2PLUS) |
46 | #define SRAM_BOOTLOADER_SZ 0x00 | 50 | #define SRAM_BOOTLOADER_SZ 0x00 |
@@ -163,6 +167,10 @@ static void __init omap_map_sram(void) | |||
163 | if (omap_sram_size == 0) | 167 | if (omap_sram_size == 0) |
164 | return; | 168 | return; |
165 | 169 | ||
170 | #ifdef CONFIG_OMAP4_ERRATA_I688 | ||
171 | omap_sram_start += PAGE_SIZE; | ||
172 | omap_sram_size -= SZ_16K; | ||
173 | #endif | ||
166 | if (cpu_is_omap34xx()) { | 174 | if (cpu_is_omap34xx()) { |
167 | /* | 175 | /* |
168 | * SRAM must be marked as non-cached on OMAP3 since the | 176 | * SRAM must be marked as non-cached on OMAP3 since the |