Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 281875
b: refs/heads/master
c: 137d105
h: refs/heads/master
i:
  281873: f3d55b8
  281871: 558bf99
v: v3
  • Loading branch information
Santosh Shilimkar authored and Kevin Hilman committed Dec 8, 2011
1 parent 132e51d commit 47f676e
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 49404dd09f5dc78c247c6044c60d7be7768a71bc
refs/heads/master: 137d105d50f6e6c373c1aa759f59045e6239cf66
21 changes: 21 additions & 0 deletions trunk/arch/arm/mach-omap2/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,27 @@ config OMAP3_SDRC_AC_TIMING
wish to say no. Selecting yes without understanding what is
going on could result in system crashes;

config OMAP4_ERRATA_I688
bool "OMAP4 errata: Async Bridge Corruption"
depends on ARCH_OMAP4
select ARCH_HAS_BARRIERS
help
If a data is stalled inside asynchronous bridge because of back
pressure, it may be accepted multiple times, creating pointer
misalignment that will corrupt next transfers on that data path
until next reset of the system (No recovery procedure once the
issue is hit, the path remains consistently broken). Async bridge
can be found on path between MPU to EMIF and MPU to L3 interconnect.
This situation can happen only when the idle is initiated by a
Master Request Disconnection (which is trigged by software when
executing WFI on CPU).
The work-around for this errata needs all the initiators connected
through async bridge must ensure that data path is properly drained
before issuing WFI. This condition will be met if one Strongly ordered
access is performed to the target right before executing the WFI.
In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained.
IO barrier ensure that there is no synchronisation loss on initiators
operating on both interconnect port simultaneously.
endmenu

endif
31 changes: 31 additions & 0 deletions trunk/arch/arm/mach-omap2/include/mach/barriers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* OMAP memory barrier header.
*
* Copyright (C) 2011 Texas Instruments, Inc.
* Santosh Shilimkar <santosh.shilimkar@ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#ifndef __MACH_BARRIERS_H
#define __MACH_BARRIERS_H

extern void omap_bus_sync(void);

#define rmb() dsb()
#define wmb() do { dsb(); outer_sync(); omap_bus_sync(); } while (0)
#define mb() wmb()

#endif /* __MACH_BARRIERS_H */
9 changes: 9 additions & 0 deletions trunk/arch/arm/mach-omap2/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@ static struct map_desc omap44xx_io_desc[] __initdata = {
.length = L4_EMU_44XX_SIZE,
.type = MT_DEVICE,
},
#ifdef CONFIG_OMAP4_ERRATA_I688
{
.virtual = OMAP4_SRAM_VA,
.pfn = __phys_to_pfn(OMAP4_SRAM_PA),
.length = PAGE_SIZE,
.type = MT_MEMORY_SO,
},
#endif

};
#endif

Expand Down
51 changes: 51 additions & 0 deletions trunk/arch/arm/mach-omap2/omap4-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/memblock.h>

#include <asm/hardware/gic.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/mach/map.h>

#include <plat/irqs.h>
#include <plat/sram.h>

#include <mach/hardware.h>
#include <mach/omap-wakeupgen.h>
Expand All @@ -33,6 +36,54 @@ static void __iomem *l2cache_base;

static void __iomem *sar_ram_base;

#ifdef CONFIG_OMAP4_ERRATA_I688
/* Used to implement memory barrier on DRAM path */
#define OMAP4_DRAM_BARRIER_VA 0xfe600000

void __iomem *dram_sync, *sram_sync;

void omap_bus_sync(void)
{
if (dram_sync && sram_sync) {
writel_relaxed(readl_relaxed(dram_sync), dram_sync);
writel_relaxed(readl_relaxed(sram_sync), sram_sync);
isb();
}
}

static int __init omap_barriers_init(void)
{
struct map_desc dram_io_desc[1];
phys_addr_t paddr;
u32 size;

if (!cpu_is_omap44xx())
return -ENODEV;

size = ALIGN(PAGE_SIZE, SZ_1M);
paddr = memblock_alloc(size, SZ_1M);
if (!paddr) {
pr_err("%s: failed to reserve 4 Kbytes\n", __func__);
return -ENOMEM;
}
memblock_free(paddr, size);
memblock_remove(paddr, size);
dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
dram_io_desc[0].pfn = __phys_to_pfn(paddr);
dram_io_desc[0].length = size;
dram_io_desc[0].type = MT_MEMORY_SO;
iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
dram_sync = (void __iomem *) dram_io_desc[0].virtual;
sram_sync = (void __iomem *) OMAP4_SRAM_VA;

pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
(long long) paddr, dram_io_desc[0].virtual);

return 0;
}
core_initcall(omap_barriers_init);
#endif

void __init gic_init_irq(void)
{
void __iomem *omap_irq_base;
Expand Down
8 changes: 8 additions & 0 deletions trunk/arch/arm/mach-omap2/sleep44xx.S
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,16 @@ skip_l2en:
ENDPROC(omap4_cpu_resume)
#endif

#ifndef CONFIG_OMAP4_ERRATA_I688
ENTRY(omap_bus_sync)
mov pc, lr
ENDPROC(omap_bus_sync)
#endif

ENTRY(omap_do_wfi)
stmfd sp!, {lr}
/* Drain interconnect write buffers. */
bl omap_bus_sync

/*
* Execute an ISB instruction to ensure that all of the
Expand Down
6 changes: 5 additions & 1 deletion trunk/arch/arm/plat-omap/include/plat/sram.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ static inline void omap_push_sram_idle(void) {}
*/
#define OMAP2_SRAM_PA 0x40200000
#define OMAP3_SRAM_PA 0x40200000
#ifdef CONFIG_OMAP4_ERRATA_I688
#define OMAP4_SRAM_PA 0x40304000
#define OMAP4_SRAM_VA 0xfe404000
#else
#define OMAP4_SRAM_PA 0x40300000

#endif
#endif
8 changes: 8 additions & 0 deletions trunk/arch/arm/plat-omap/sram.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@
#define OMAP1_SRAM_PA 0x20000000
#define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800)
#define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000)
#ifdef CONFIG_OMAP4_ERRATA_I688
#define OMAP4_SRAM_PUB_PA OMAP4_SRAM_PA
#else
#define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000)
#endif

#if defined(CONFIG_ARCH_OMAP2PLUS)
#define SRAM_BOOTLOADER_SZ 0x00
Expand Down Expand Up @@ -163,6 +167,10 @@ static void __init omap_map_sram(void)
if (omap_sram_size == 0)
return;

#ifdef CONFIG_OMAP4_ERRATA_I688
omap_sram_start += PAGE_SIZE;
omap_sram_size -= SZ_16K;
#endif
if (cpu_is_omap34xx()) {
/*
* SRAM must be marked as non-cached on OMAP3 since the
Expand Down

0 comments on commit 47f676e

Please sign in to comment.