Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm
Pull ARM development updates from Russell King: "Included in this update: - moving PSCI code from ARM64/ARM to drivers/ - removal of some architecture internals from global kernel view - addition of software based "privileged no access" support using the old domains register to turn off the ability for kernel loads/stores to access userspace. Only the proper accessors will be usable. - addition of early fixup support for early console - re-addition (and reimplementation) of OMAP special interconnect barrier - removal of finish_arch_switch() - only expose cpuX/online in sysfs if hotpluggable - a number of code cleanups" * 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (41 commits) ARM: software-based priviledged-no-access support ARM: entry: provide uaccess assembly macro hooks ARM: entry: get rid of multiple macro definitions ARM: 8421/1: smp: Collapse arch_cpu_idle_dead() into cpu_die() ARM: uaccess: provide uaccess_save_and_enable() and uaccess_restore() ARM: mm: improve do_ldrd_abort macro ARM: entry: ensure that IRQs are enabled when calling syscall_trace_exit() ARM: entry: efficiency cleanups ARM: entry: get rid of asm_trace_hardirqs_on_cond ARM: uaccess: simplify user access assembly ARM: domains: remove DOMAIN_TABLE ARM: domains: keep vectors in separate domain ARM: domains: get rid of manager mode for user domain ARM: domains: move initial domain setting value to asm/domains.h ARM: domains: provide domain_mask() ARM: domains: switch to keeping domain value in register ARM: 8419/1: dma-mapping: harmonize definition of DMA_ERROR_CODE ARM: 8417/1: refactor bitops functions with BIT_MASK() and BIT_WORD() ARM: 8416/1: Feroceon: use of_iomap() to map register base ARM: 8415/1: early fixmap support for earlycon ...
This commit is contained in:
@@ -29,6 +29,7 @@ config ARCH_OMAP4
|
||||
select HAVE_ARM_SCU if SMP
|
||||
select HAVE_ARM_TWD if SMP
|
||||
select OMAP_INTERCONNECT
|
||||
select OMAP_INTERCONNECT_BARRIER
|
||||
select PL310_ERRATA_588369 if CACHE_L2X0
|
||||
select PL310_ERRATA_727915 if CACHE_L2X0
|
||||
select PM_OPP if PM
|
||||
@@ -46,6 +47,7 @@ config SOC_OMAP5
|
||||
select HAVE_ARM_TWD if SMP
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select ARM_ERRATA_798181 if SMP
|
||||
select OMAP_INTERCONNECT_BARRIER
|
||||
|
||||
config SOC_AM33XX
|
||||
bool "TI AM33XX"
|
||||
@@ -71,6 +73,7 @@ config SOC_DRA7XX
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select IRQ_CROSSBAR
|
||||
select ARM_ERRATA_798181 if SMP
|
||||
select OMAP_INTERCONNECT_BARRIER
|
||||
|
||||
config ARCH_OMAP2PLUS
|
||||
bool
|
||||
@@ -92,6 +95,10 @@ config ARCH_OMAP2PLUS
|
||||
help
|
||||
Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
|
||||
|
||||
config OMAP_INTERCONNECT_BARRIER
|
||||
bool
|
||||
select ARM_HEAVY_MB
|
||||
|
||||
|
||||
if ARCH_OMAP2PLUS
|
||||
|
||||
|
@@ -30,4 +30,5 @@ int __weak omap_secure_ram_reserve_memblock(void)
|
||||
void __init omap_reserve(void)
|
||||
{
|
||||
omap_secure_ram_reserve_memblock();
|
||||
omap_barrier_reserve_memblock();
|
||||
}
|
||||
|
@@ -189,6 +189,15 @@ static inline void omap44xx_restart(enum reboot_mode mode, const char *cmd)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
|
||||
void omap_barrier_reserve_memblock(void);
|
||||
void omap_barriers_init(void);
|
||||
#else
|
||||
static inline void omap_barrier_reserve_memblock(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This gets called from mach-omap2/io.c, do not call this */
|
||||
void __init omap2_set_globals_tap(u32 class, void __iomem *tap);
|
||||
|
||||
|
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include <asm/outercache.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 */
|
@@ -352,6 +352,7 @@ void __init am33xx_map_io(void)
|
||||
void __init omap4_map_io(void)
|
||||
{
|
||||
iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
|
||||
omap_barriers_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -359,6 +360,7 @@ void __init omap4_map_io(void)
|
||||
void __init omap5_map_io(void)
|
||||
{
|
||||
iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
|
||||
omap_barriers_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -51,6 +51,127 @@ static void __iomem *twd_base;
|
||||
|
||||
#define IRQ_LOCALTIMER 29
|
||||
|
||||
#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
|
||||
|
||||
/* Used to implement memory barrier on DRAM path */
|
||||
#define OMAP4_DRAM_BARRIER_VA 0xfe600000
|
||||
|
||||
static void __iomem *dram_sync, *sram_sync;
|
||||
static phys_addr_t dram_sync_paddr;
|
||||
static u32 dram_sync_size;
|
||||
|
||||
/*
|
||||
* The OMAP4 bus structure contains asynchrnous bridges which can buffer
|
||||
* data writes from the MPU. These asynchronous bridges can be found on
|
||||
* paths between the MPU to EMIF, and the MPU to L3 interconnects.
|
||||
*
|
||||
* We need to be careful about re-ordering which can happen as a result
|
||||
* of different accesses being performed via different paths, and
|
||||
* therefore different asynchronous bridges.
|
||||
*/
|
||||
|
||||
/*
|
||||
* OMAP4 interconnect barrier which is called for each mb() and wmb().
|
||||
* This is to ensure that normal paths to DRAM (normal memory, cacheable
|
||||
* accesses) are properly synchronised with writes to DMA coherent memory
|
||||
* (normal memory, uncacheable) and device writes.
|
||||
*
|
||||
* The mb() and wmb() barriers only operate only on the MPU->MA->EMIF
|
||||
* path, as we need to ensure that data is visible to other system
|
||||
* masters prior to writes to those system masters being seen.
|
||||
*
|
||||
* Note: the SRAM path is not synchronised via mb() and wmb().
|
||||
*/
|
||||
static void omap4_mb(void)
|
||||
{
|
||||
if (dram_sync)
|
||||
writel_relaxed(0, dram_sync);
|
||||
}
|
||||
|
||||
/*
|
||||
* OMAP4 Errata i688 - asynchronous bridge corruption when entering WFI.
|
||||
*
|
||||
* 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 bridges can be found on paths between MPU to EMIF and MPU to L3
|
||||
* interconnects.
|
||||
*
|
||||
* This situation can happen only when the idle is initiated by a Master
|
||||
* Request Disconnection (which is trigged by software when executing WFI
|
||||
* on the CPU).
|
||||
*
|
||||
* The work-around for this errata needs all the initiators connected
|
||||
* through an async bridge to 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.
|
||||
*
|
||||
* This is a stronger version of the OMAP4 memory barrier below, and
|
||||
* operates on both the MPU->MA->EMIF path but also the MPU->OCP path
|
||||
* as well, and is necessary prior to executing a WFI.
|
||||
*/
|
||||
void omap_interconnect_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 omap4_sram_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
struct gen_pool *sram_pool;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
|
||||
if (!np)
|
||||
pr_warn("%s:Unable to allocate sram needed to handle errata I688\n",
|
||||
__func__);
|
||||
sram_pool = of_gen_pool_get(np, "sram", 0);
|
||||
if (!sram_pool)
|
||||
pr_warn("%s:Unable to get sram pool needed to handle errata I688\n",
|
||||
__func__);
|
||||
else
|
||||
sram_sync = (void *)gen_pool_alloc(sram_pool, PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
omap_arch_initcall(omap4_sram_init);
|
||||
|
||||
/* Steal one page physical memory for barrier implementation */
|
||||
void __init omap_barrier_reserve_memblock(void)
|
||||
{
|
||||
dram_sync_size = ALIGN(PAGE_SIZE, SZ_1M);
|
||||
dram_sync_paddr = arm_memblock_steal(dram_sync_size, SZ_1M);
|
||||
}
|
||||
|
||||
void __init omap_barriers_init(void)
|
||||
{
|
||||
struct map_desc dram_io_desc[1];
|
||||
|
||||
dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
|
||||
dram_io_desc[0].pfn = __phys_to_pfn(dram_sync_paddr);
|
||||
dram_io_desc[0].length = dram_sync_size;
|
||||
dram_io_desc[0].type = MT_MEMORY_RW_SO;
|
||||
iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
|
||||
dram_sync = (void __iomem *) dram_io_desc[0].virtual;
|
||||
|
||||
pr_info("OMAP4: Map %pa to %p for dram barrier\n",
|
||||
&dram_sync_paddr, dram_sync);
|
||||
|
||||
soc_mb = omap4_mb;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void gic_dist_disable(void)
|
||||
{
|
||||
if (gic_dist_base_addr)
|
||||
|
@@ -333,14 +333,12 @@ ENDPROC(omap4_cpu_resume)
|
||||
|
||||
#endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */
|
||||
|
||||
ENTRY(omap_bus_sync)
|
||||
ret lr
|
||||
ENDPROC(omap_bus_sync)
|
||||
|
||||
ENTRY(omap_do_wfi)
|
||||
stmfd sp!, {lr}
|
||||
#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
|
||||
/* Drain interconnect write buffers. */
|
||||
bl omap_bus_sync
|
||||
bl omap_interconnect_sync
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Execute an ISB instruction to ensure that all of the
|
||||
|
Reference in New Issue
Block a user