mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 12:14:01 +08:00
Merge branch 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson
* 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson: ux500: allow 5500 and 8500 to be built together ux500: modem_irq is only for 5500 ux500: dynamic SOC detection ux500: rename MOP board Kconfig ux500: remove build-time changing macros
This commit is contained in:
commit
e773202e22
@ -9,6 +9,10 @@ CONFIG_MODULE_UNLOAD=y
|
|||||||
# CONFIG_LBDAF is not set
|
# CONFIG_LBDAF is not set
|
||||||
# CONFIG_BLK_DEV_BSG is not set
|
# CONFIG_BLK_DEV_BSG is not set
|
||||||
CONFIG_ARCH_U8500=y
|
CONFIG_ARCH_U8500=y
|
||||||
|
CONFIG_UX500_SOC_DB5500=y
|
||||||
|
CONFIG_UX500_SOC_DB8500=y
|
||||||
|
CONFIG_MACH_U8500=y
|
||||||
|
CONFIG_MACH_U5500=y
|
||||||
CONFIG_SMP=y
|
CONFIG_SMP=y
|
||||||
CONFIG_NR_CPUS=2
|
CONFIG_NR_CPUS=2
|
||||||
CONFIG_PREEMPT=y
|
CONFIG_PREEMPT=y
|
||||||
|
@ -7,28 +7,30 @@ config UX500_SOC_COMMON
|
|||||||
select HAS_MTU
|
select HAS_MTU
|
||||||
select NOMADIK_GPIO
|
select NOMADIK_GPIO
|
||||||
|
|
||||||
config UX500_SOC_DB8500
|
menu "Ux500 SoC"
|
||||||
bool
|
|
||||||
|
|
||||||
config UX500_SOC_DB5500
|
config UX500_SOC_DB5500
|
||||||
bool
|
bool "DB5500"
|
||||||
|
|
||||||
choice
|
config UX500_SOC_DB8500
|
||||||
prompt "Ux500 target platform"
|
bool "DB8500"
|
||||||
default MACH_U8500_MOP
|
|
||||||
|
|
||||||
config MACH_U8500_MOP
|
endmenu
|
||||||
|
|
||||||
|
menu "Ux500 target platform"
|
||||||
|
|
||||||
|
config MACH_U8500
|
||||||
bool "U8500 Development platform"
|
bool "U8500 Development platform"
|
||||||
select UX500_SOC_DB8500
|
depends on UX500_SOC_DB8500
|
||||||
help
|
help
|
||||||
Include support for the mop500 development platform.
|
Include support for the mop500 development platform.
|
||||||
|
|
||||||
config MACH_U5500
|
config MACH_U5500
|
||||||
bool "U5500 Development platform"
|
bool "U5500 Development platform"
|
||||||
select UX500_SOC_DB5500
|
depends on UX500_SOC_DB5500
|
||||||
help
|
help
|
||||||
Include support for the U5500 development platform.
|
Include support for the U5500 development platform.
|
||||||
endchoice
|
endmenu
|
||||||
|
|
||||||
config UX500_DEBUG_UART
|
config UX500_DEBUG_UART
|
||||||
int "Ux500 UART to use for low-level debug"
|
int "Ux500 UART to use for low-level debug"
|
||||||
@ -39,14 +41,14 @@ config UX500_DEBUG_UART
|
|||||||
|
|
||||||
config U5500_MODEM_IRQ
|
config U5500_MODEM_IRQ
|
||||||
bool "Modem IRQ support"
|
bool "Modem IRQ support"
|
||||||
depends on MACH_U5500
|
depends on UX500_SOC_DB5500
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Add support for handling IRQ:s from modem side
|
Add support for handling IRQ:s from modem side
|
||||||
|
|
||||||
config U5500_MBOX
|
config U5500_MBOX
|
||||||
bool "Mailbox support"
|
bool "Mailbox support"
|
||||||
depends on MACH_U5500 && U5500_MODEM_IRQ
|
depends on U5500_MODEM_IRQ
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
Add support for U5500 mailbox communication with modem side
|
Add support for U5500 mailbox communication with modem side
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
# Makefile for the linux kernel, U8500 machine.
|
# Makefile for the linux kernel, U8500 machine.
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y := clock.o cpu.o devices.o devices-common.o
|
obj-y := clock.o cpu.o devices.o devices-common.o \
|
||||||
|
id.o
|
||||||
obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
|
obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
|
||||||
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o
|
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o
|
||||||
obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o \
|
obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \
|
||||||
board-mop500-keypads.o
|
board-mop500-keypads.o
|
||||||
obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o
|
obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o
|
||||||
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
|
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
|
||||||
|
@ -136,8 +136,7 @@ EXPORT_SYMBOL(clk_disable);
|
|||||||
*/
|
*/
|
||||||
static unsigned long clk_mtu_get_rate(struct clk *clk)
|
static unsigned long clk_mtu_get_rate(struct clk *clk)
|
||||||
{
|
{
|
||||||
void __iomem *addr = __io_address(UX500_PRCMU_BASE)
|
void __iomem *addr;
|
||||||
+ PRCM_TCR;
|
|
||||||
u32 tcr;
|
u32 tcr;
|
||||||
int mtu = (int) clk->data;
|
int mtu = (int) clk->data;
|
||||||
/*
|
/*
|
||||||
@ -149,13 +148,20 @@ static unsigned long clk_mtu_get_rate(struct clk *clk)
|
|||||||
unsigned long mturate;
|
unsigned long mturate;
|
||||||
unsigned long retclk;
|
unsigned long retclk;
|
||||||
|
|
||||||
|
if (cpu_is_u5500())
|
||||||
|
addr = __io_address(U5500_PRCMU_BASE);
|
||||||
|
else if (cpu_is_u8500())
|
||||||
|
addr = __io_address(U8500_PRCMU_BASE);
|
||||||
|
else
|
||||||
|
ux500_unknown_soc();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On a startup, always conifgure the TCR to the doze mode;
|
* On a startup, always conifgure the TCR to the doze mode;
|
||||||
* bootloaders do it for us. Do this in the kernel too.
|
* bootloaders do it for us. Do this in the kernel too.
|
||||||
*/
|
*/
|
||||||
writel(PRCM_TCR_DOZE_MODE, addr);
|
writel(PRCM_TCR_DOZE_MODE, addr + PRCM_TCR);
|
||||||
|
|
||||||
tcr = readl(addr);
|
tcr = readl(addr + PRCM_TCR);
|
||||||
|
|
||||||
/* Get the rate from the parent as a default */
|
/* Get the rate from the parent as a default */
|
||||||
if (clk->parent_periph)
|
if (clk->parent_periph)
|
||||||
|
@ -21,7 +21,20 @@
|
|||||||
|
|
||||||
#include "devices-db5500.h"
|
#include "devices-db5500.h"
|
||||||
|
|
||||||
|
static struct map_desc u5500_uart_io_desc[] __initdata = {
|
||||||
|
__IO_DEV_DESC(U5500_UART0_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U5500_UART2_BASE, SZ_4K),
|
||||||
|
};
|
||||||
|
|
||||||
static struct map_desc u5500_io_desc[] __initdata = {
|
static struct map_desc u5500_io_desc[] __initdata = {
|
||||||
|
__IO_DEV_DESC(U5500_GIC_CPU_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U5500_GIC_DIST_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U5500_L2CC_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U5500_TWD_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U5500_MTU0_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U5500_SCU_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U5500_BACKUPRAM0_BASE, SZ_8K),
|
||||||
|
|
||||||
__IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
|
__IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
|
||||||
__IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K),
|
__IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K),
|
||||||
__IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K),
|
__IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K),
|
||||||
@ -143,6 +156,11 @@ static void __init db5500_add_gpios(void)
|
|||||||
|
|
||||||
void __init u5500_map_io(void)
|
void __init u5500_map_io(void)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Map the UARTs early so that the DEBUG_LL stuff continues to work.
|
||||||
|
*/
|
||||||
|
iotable_init(u5500_uart_io_desc, ARRAY_SIZE(u5500_uart_io_desc));
|
||||||
|
|
||||||
ux500_map_io();
|
ux500_map_io();
|
||||||
|
|
||||||
iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc));
|
iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc));
|
||||||
|
@ -29,13 +29,31 @@ static struct platform_device *platform_devs[] __initdata = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* minimum static i/o mapping required to boot U8500 platforms */
|
/* minimum static i/o mapping required to boot U8500 platforms */
|
||||||
|
static struct map_desc u8500_uart_io_desc[] __initdata = {
|
||||||
|
__IO_DEV_DESC(U8500_UART0_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
|
||||||
|
};
|
||||||
|
|
||||||
static struct map_desc u8500_io_desc[] __initdata = {
|
static struct map_desc u8500_io_desc[] __initdata = {
|
||||||
|
__IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_TWD_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K),
|
||||||
|
|
||||||
|
__IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_CLKRST5_BASE, SZ_4K),
|
||||||
|
__IO_DEV_DESC(U8500_CLKRST6_BASE, SZ_4K),
|
||||||
|
|
||||||
__IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
|
__IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K),
|
||||||
__IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
|
__IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K),
|
||||||
__IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
|
__IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K),
|
||||||
__IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
|
__IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K),
|
||||||
__IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
|
__IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K),
|
||||||
__MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct map_desc u8500_ed_io_desc[] __initdata = {
|
static struct map_desc u8500_ed_io_desc[] __initdata = {
|
||||||
@ -52,71 +70,13 @@ static struct map_desc u8500_v2_io_desc[] __initdata = {
|
|||||||
__IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
|
__IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Functions to differentiate between later ASICs
|
|
||||||
* We look into the end of the ROM to locate the hardcoded ASIC ID.
|
|
||||||
* This is only needed to differentiate between minor revisions and
|
|
||||||
* process variants of an ASIC, the major revisions are encoded in
|
|
||||||
* the cpuid.
|
|
||||||
*/
|
|
||||||
#define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOT_ROM_BASE + 0x1FFF4)
|
|
||||||
#define U8500_ASIC_ID_LOC_V2 (U8500_BOOT_ROM_BASE + 0x1DBF4)
|
|
||||||
#define U8500_ASIC_REV_ED 0x01
|
|
||||||
#define U8500_ASIC_REV_V10 0xA0
|
|
||||||
#define U8500_ASIC_REV_V11 0xA1
|
|
||||||
#define U8500_ASIC_REV_V20 0xB0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* struct db8500_asic_id - fields of the ASIC ID
|
|
||||||
* @process: the manufacturing process, 0x40 is 40 nm
|
|
||||||
* 0x00 is "standard"
|
|
||||||
* @partnumber: hithereto 0x8500 for DB8500
|
|
||||||
* @revision: version code in the series
|
|
||||||
* This field definion is not formally defined but makes
|
|
||||||
* sense.
|
|
||||||
*/
|
|
||||||
struct db8500_asic_id {
|
|
||||||
u8 process;
|
|
||||||
u16 partnumber;
|
|
||||||
u8 revision;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This isn't going to change at runtime */
|
|
||||||
static struct db8500_asic_id db8500_id;
|
|
||||||
|
|
||||||
static void __init get_db8500_asic_id(void)
|
|
||||||
{
|
|
||||||
u32 asicid;
|
|
||||||
|
|
||||||
if (cpu_is_u8500v1() || cpu_is_u8500ed())
|
|
||||||
asicid = readl(__io_address(U8500_ASIC_ID_LOC_ED_V1));
|
|
||||||
else if (cpu_is_u8500v2())
|
|
||||||
asicid = readl(__io_address(U8500_ASIC_ID_LOC_V2));
|
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
db8500_id.process = (asicid >> 24);
|
|
||||||
db8500_id.partnumber = (asicid >> 16) & 0xFFFFU;
|
|
||||||
db8500_id.revision = asicid & 0xFFU;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cpu_is_u8500v10(void)
|
|
||||||
{
|
|
||||||
return (db8500_id.revision == U8500_ASIC_REV_V10);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cpu_is_u8500v11(void)
|
|
||||||
{
|
|
||||||
return (db8500_id.revision == U8500_ASIC_REV_V11);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cpu_is_u8500v20(void)
|
|
||||||
{
|
|
||||||
return (db8500_id.revision == U8500_ASIC_REV_V20);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init u8500_map_io(void)
|
void __init u8500_map_io(void)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Map the UARTs early so that the DEBUG_LL stuff continues to work.
|
||||||
|
*/
|
||||||
|
iotable_init(u8500_uart_io_desc, ARRAY_SIZE(u8500_uart_io_desc));
|
||||||
|
|
||||||
ux500_map_io();
|
ux500_map_io();
|
||||||
|
|
||||||
iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
|
iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
|
||||||
@ -127,9 +87,6 @@ void __init u8500_map_io(void)
|
|||||||
iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
|
iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
|
||||||
else if (cpu_is_u8500v2())
|
else if (cpu_is_u8500v2())
|
||||||
iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
|
iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
|
||||||
|
|
||||||
/* Read out the ASIC ID as early as we can */
|
|
||||||
get_db8500_asic_id();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static resource_size_t __initdata db8500_gpio_base[] = {
|
static resource_size_t __initdata db8500_gpio_base[] = {
|
||||||
@ -159,20 +116,6 @@ static void __init db8500_add_gpios(void)
|
|||||||
*/
|
*/
|
||||||
void __init u8500_init_devices(void)
|
void __init u8500_init_devices(void)
|
||||||
{
|
{
|
||||||
/* Display some ASIC boilerplate */
|
|
||||||
pr_info("DB8500: process: %02x, revision ID: 0x%02x\n",
|
|
||||||
db8500_id.process, db8500_id.revision);
|
|
||||||
if (cpu_is_u8500ed())
|
|
||||||
pr_info("DB8500: Early Drop (ED)\n");
|
|
||||||
else if (cpu_is_u8500v10())
|
|
||||||
pr_info("DB8500: version 1.0\n");
|
|
||||||
else if (cpu_is_u8500v11())
|
|
||||||
pr_info("DB8500: version 1.1\n");
|
|
||||||
else if (cpu_is_u8500v20())
|
|
||||||
pr_info("DB8500: version 2.0\n");
|
|
||||||
else
|
|
||||||
pr_warning("ASIC: UNKNOWN SILICON VERSION!\n");
|
|
||||||
|
|
||||||
if (cpu_is_u8500ed())
|
if (cpu_is_u8500ed())
|
||||||
dma40_u8500ed_fixup();
|
dma40_u8500ed_fixup();
|
||||||
|
|
||||||
|
@ -23,37 +23,25 @@
|
|||||||
|
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
|
|
||||||
static struct map_desc ux500_io_desc[] __initdata = {
|
#ifdef CONFIG_CACHE_L2X0
|
||||||
__IO_DEV_DESC(UX500_UART0_BASE, SZ_4K),
|
static void __iomem *l2x0_base;
|
||||||
__IO_DEV_DESC(UX500_UART2_BASE, SZ_4K),
|
#endif
|
||||||
|
|
||||||
__IO_DEV_DESC(UX500_GIC_CPU_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_GIC_DIST_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_L2CC_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_TWD_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_SCU_BASE, SZ_4K),
|
|
||||||
|
|
||||||
__IO_DEV_DESC(UX500_CLKRST1_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_CLKRST2_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_CLKRST3_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_CLKRST5_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_CLKRST6_BASE, SZ_4K),
|
|
||||||
|
|
||||||
__IO_DEV_DESC(UX500_MTU0_BASE, SZ_4K),
|
|
||||||
__IO_DEV_DESC(UX500_MTU1_BASE, SZ_4K),
|
|
||||||
|
|
||||||
__IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K),
|
|
||||||
};
|
|
||||||
|
|
||||||
void __init ux500_map_io(void)
|
|
||||||
{
|
|
||||||
iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc));
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init ux500_init_irq(void)
|
void __init ux500_init_irq(void)
|
||||||
{
|
{
|
||||||
gic_init(0, 29, __io_address(UX500_GIC_DIST_BASE),
|
void __iomem *dist_base;
|
||||||
__io_address(UX500_GIC_CPU_BASE));
|
void __iomem *cpu_base;
|
||||||
|
|
||||||
|
if (cpu_is_u5500()) {
|
||||||
|
dist_base = __io_address(U5500_GIC_DIST_BASE);
|
||||||
|
cpu_base = __io_address(U5500_GIC_CPU_BASE);
|
||||||
|
} else if (cpu_is_u8500()) {
|
||||||
|
dist_base = __io_address(U8500_GIC_DIST_BASE);
|
||||||
|
cpu_base = __io_address(U8500_GIC_CPU_BASE);
|
||||||
|
} else
|
||||||
|
ux500_unknown_soc();
|
||||||
|
|
||||||
|
gic_init(0, 29, dist_base, cpu_base);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Init clocks here so that they are available for system timer
|
* Init clocks here so that they are available for system timer
|
||||||
@ -74,7 +62,8 @@ static inline void ux500_cache_wait(void __iomem *reg, unsigned long mask)
|
|||||||
|
|
||||||
static inline void ux500_cache_sync(void)
|
static inline void ux500_cache_sync(void)
|
||||||
{
|
{
|
||||||
void __iomem *base = __io_address(UX500_L2CC_BASE);
|
void __iomem *base = l2x0_base;
|
||||||
|
|
||||||
writel_relaxed(0, base + L2X0_CACHE_SYNC);
|
writel_relaxed(0, base + L2X0_CACHE_SYNC);
|
||||||
ux500_cache_wait(base + L2X0_CACHE_SYNC, 1);
|
ux500_cache_wait(base + L2X0_CACHE_SYNC, 1);
|
||||||
}
|
}
|
||||||
@ -96,20 +85,23 @@ static void ux500_l2x0_disable(void)
|
|||||||
*/
|
*/
|
||||||
static void ux500_l2x0_inv_all(void)
|
static void ux500_l2x0_inv_all(void)
|
||||||
{
|
{
|
||||||
void __iomem *l2x0_base = __io_address(UX500_L2CC_BASE);
|
void __iomem *base = l2x0_base;
|
||||||
uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */
|
uint32_t l2x0_way_mask = (1<<16) - 1; /* Bitmask of active ways */
|
||||||
|
|
||||||
/* invalidate all ways */
|
/* invalidate all ways */
|
||||||
writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_INV_WAY);
|
writel_relaxed(l2x0_way_mask, base + L2X0_INV_WAY);
|
||||||
ux500_cache_wait(l2x0_base + L2X0_INV_WAY, l2x0_way_mask);
|
ux500_cache_wait(base + L2X0_INV_WAY, l2x0_way_mask);
|
||||||
ux500_cache_sync();
|
ux500_cache_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ux500_l2x0_init(void)
|
static int ux500_l2x0_init(void)
|
||||||
{
|
{
|
||||||
void __iomem *l2x0_base;
|
if (cpu_is_u5500())
|
||||||
|
l2x0_base = __io_address(U5500_L2CC_BASE);
|
||||||
l2x0_base = __io_address(UX500_L2CC_BASE);
|
else if (cpu_is_u8500())
|
||||||
|
l2x0_base = __io_address(U8500_L2CC_BASE);
|
||||||
|
else
|
||||||
|
ux500_unknown_soc();
|
||||||
|
|
||||||
/* 64KB way size, 8 way associativity, force WA */
|
/* 64KB way size, 8 way associativity, force WA */
|
||||||
l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
|
l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
|
||||||
@ -127,13 +119,21 @@ static void __init ux500_timer_init(void)
|
|||||||
{
|
{
|
||||||
#ifdef CONFIG_LOCAL_TIMERS
|
#ifdef CONFIG_LOCAL_TIMERS
|
||||||
/* Setup the local timer base */
|
/* Setup the local timer base */
|
||||||
twd_base = __io_address(UX500_TWD_BASE);
|
if (cpu_is_u5500())
|
||||||
#endif
|
twd_base = __io_address(U5500_TWD_BASE);
|
||||||
/* Setup the MTU base */
|
else if (cpu_is_u8500())
|
||||||
if (cpu_is_u8500ed())
|
twd_base = __io_address(U8500_TWD_BASE);
|
||||||
mtu_base = __io_address(U8500_MTU0_BASE_ED);
|
|
||||||
else
|
else
|
||||||
mtu_base = __io_address(UX500_MTU0_BASE);
|
ux500_unknown_soc();
|
||||||
|
#endif
|
||||||
|
if (cpu_is_u5500())
|
||||||
|
mtu_base = __io_address(U5500_MTU0_BASE);
|
||||||
|
else if (cpu_is_u8500ed())
|
||||||
|
mtu_base = __io_address(U8500_MTU0_BASE_ED);
|
||||||
|
else if (cpu_is_u8500())
|
||||||
|
mtu_base = __io_address(U8500_MTU0_BASE);
|
||||||
|
else
|
||||||
|
ux500_unknown_soc();
|
||||||
|
|
||||||
nmdk_timer_init();
|
nmdk_timer_init();
|
||||||
}
|
}
|
||||||
|
107
arch/arm/mach-ux500/id.c
Normal file
107
arch/arm/mach-ux500/id.c
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) ST-Ericsson SA 2010
|
||||||
|
*
|
||||||
|
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
|
||||||
|
* License terms: GNU General Public License (GPL) version 2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
|
||||||
|
#include <asm/cputype.h>
|
||||||
|
#include <asm/tlbflush.h>
|
||||||
|
#include <asm/cacheflush.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
#include <mach/setup.h>
|
||||||
|
|
||||||
|
struct dbx500_asic_id dbx500_id;
|
||||||
|
|
||||||
|
static unsigned int ux500_read_asicid(phys_addr_t addr)
|
||||||
|
{
|
||||||
|
phys_addr_t base = addr & ~0xfff;
|
||||||
|
struct map_desc desc = {
|
||||||
|
.virtual = IO_ADDRESS(base),
|
||||||
|
.pfn = __phys_to_pfn(base),
|
||||||
|
.length = SZ_16K,
|
||||||
|
.type = MT_DEVICE,
|
||||||
|
};
|
||||||
|
|
||||||
|
iotable_init(&desc, 1);
|
||||||
|
|
||||||
|
/* As in devicemaps_init() */
|
||||||
|
local_flush_tlb_all();
|
||||||
|
flush_cache_all();
|
||||||
|
|
||||||
|
return readl(__io_address(addr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ux500_print_soc_info(unsigned int asicid)
|
||||||
|
{
|
||||||
|
unsigned int rev = dbx500_revision();
|
||||||
|
|
||||||
|
pr_info("DB%4x ", dbx500_partnumber());
|
||||||
|
|
||||||
|
if (rev == 0x01)
|
||||||
|
pr_cont("Early Drop");
|
||||||
|
else if (rev >= 0xA0)
|
||||||
|
pr_cont("v%d.%d" , (rev >> 4) - 0xA + 1, rev & 0xf);
|
||||||
|
else
|
||||||
|
pr_cont("Unknown");
|
||||||
|
|
||||||
|
pr_cont(" [%#010x]\n", asicid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int partnumber(unsigned int asicid)
|
||||||
|
{
|
||||||
|
return (asicid >> 8) & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SOC MIDR ASICID ADDRESS ASICID VALUE
|
||||||
|
* DB8500ed 0x410fc090 0x9001FFF4 0x00850001
|
||||||
|
* DB8500v1 0x411fc091 0x9001FFF4 0x008500A0
|
||||||
|
* DB8500v1.1 0x411fc091 0x9001FFF4 0x008500A1
|
||||||
|
* DB8500v2 0x412fc091 0x9001DBF4 0x008500B0
|
||||||
|
* DB5500v1 0x412fc091 0x9001FFF4 0x005500A0
|
||||||
|
*/
|
||||||
|
|
||||||
|
void __init ux500_map_io(void)
|
||||||
|
{
|
||||||
|
unsigned int cpuid = read_cpuid_id();
|
||||||
|
unsigned int asicid = 0;
|
||||||
|
phys_addr_t addr = 0;
|
||||||
|
|
||||||
|
switch (cpuid) {
|
||||||
|
case 0x410fc090: /* DB8500ed */
|
||||||
|
case 0x411fc091: /* DB8500v1 */
|
||||||
|
addr = 0x9001FFF4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x412fc091: /* DB8500v2 / DB5500v1 */
|
||||||
|
asicid = ux500_read_asicid(0x9001DBF4);
|
||||||
|
if (partnumber(asicid) == 0x8500)
|
||||||
|
/* DB8500v2 */
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* DB5500v1 */
|
||||||
|
addr = 0x9001FFF4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr)
|
||||||
|
asicid = ux500_read_asicid(addr);
|
||||||
|
|
||||||
|
if (!asicid) {
|
||||||
|
pr_err("Unable to identify SoC\n");
|
||||||
|
ux500_unknown_soc();
|
||||||
|
}
|
||||||
|
|
||||||
|
dbx500_id.process = asicid >> 24;
|
||||||
|
dbx500_id.partnumber = partnumber(asicid);
|
||||||
|
dbx500_id.revision = asicid & 0xff;
|
||||||
|
|
||||||
|
ux500_print_soc_info(asicid);
|
||||||
|
}
|
@ -14,7 +14,24 @@
|
|||||||
#error Invalid Ux500 debug UART
|
#error Invalid Ux500 debug UART
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __UX500_UART(n) UX500_UART##n##_BASE
|
/*
|
||||||
|
* DEBUG_LL only works if only one SOC is built in. We don't use #else below
|
||||||
|
* in order to get "__UX500_UART redefined" warnings if more than one SOC is
|
||||||
|
* built, so that there's some hint during the build that something is wrong.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_UX500_SOC_DB5500
|
||||||
|
#define __UX500_UART(n) U5500_UART##n##_BASE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_UX500_SOC_DB8500
|
||||||
|
#define __UX500_UART(n) U8500_UART##n##_BASE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __UX500_UART
|
||||||
|
#error Unknown SOC
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UX500_UART(n) __UX500_UART(n)
|
#define UX500_UART(n) __UX500_UART(n)
|
||||||
#define UART_BASE UX500_UART(CONFIG_UX500_DEBUG_UART)
|
#define UART_BASE UX500_UART(CONFIG_UX500_DEBUG_UART)
|
||||||
|
|
||||||
|
@ -11,15 +11,10 @@
|
|||||||
* warranty of any kind, whether express or implied.
|
* warranty of any kind, whether express or implied.
|
||||||
*/
|
*/
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#define HAVE_GET_IRQNR_PREAMBLE
|
|
||||||
#include <asm/hardware/entry-macro-gic.S>
|
#include <asm/hardware/entry-macro-gic.S>
|
||||||
|
|
||||||
.macro disable_fiq
|
.macro disable_fiq
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro get_irqnr_preamble, base, tmp
|
|
||||||
ldr \base, =IO_ADDRESS(UX500_GIC_CPU_BASE)
|
|
||||||
.endm
|
|
||||||
|
|
||||||
.macro arch_ret_to_user, tmp1, tmp2
|
.macro arch_ret_to_user, tmp1, tmp2
|
||||||
.endm
|
.endm
|
||||||
|
@ -29,118 +29,12 @@
|
|||||||
#include <mach/db8500-regs.h>
|
#include <mach/db8500-regs.h>
|
||||||
#include <mach/db5500-regs.h>
|
#include <mach/db5500-regs.h>
|
||||||
|
|
||||||
#ifdef CONFIG_UX500_SOC_DB8500
|
|
||||||
#define UX500(periph) U8500_##periph##_BASE
|
|
||||||
#elif defined(CONFIG_UX500_SOC_DB5500)
|
|
||||||
#define UX500(periph) U5500_##periph##_BASE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UX500_BACKUPRAM0_BASE UX500(BACKUPRAM0)
|
|
||||||
#define UX500_BACKUPRAM1_BASE UX500(BACKUPRAM1)
|
|
||||||
#define UX500_B2R2_BASE UX500(B2R2)
|
|
||||||
|
|
||||||
#define UX500_CLKRST1_BASE UX500(CLKRST1)
|
|
||||||
#define UX500_CLKRST2_BASE UX500(CLKRST2)
|
|
||||||
#define UX500_CLKRST3_BASE UX500(CLKRST3)
|
|
||||||
#define UX500_CLKRST5_BASE UX500(CLKRST5)
|
|
||||||
#define UX500_CLKRST6_BASE UX500(CLKRST6)
|
|
||||||
|
|
||||||
#define UX500_DMA_BASE UX500(DMA)
|
|
||||||
#define UX500_FSMC_BASE UX500(FSMC)
|
|
||||||
|
|
||||||
#define UX500_GIC_CPU_BASE UX500(GIC_CPU)
|
|
||||||
#define UX500_GIC_DIST_BASE UX500(GIC_DIST)
|
|
||||||
|
|
||||||
#define UX500_I2C1_BASE UX500(I2C1)
|
|
||||||
#define UX500_I2C2_BASE UX500(I2C2)
|
|
||||||
#define UX500_I2C3_BASE UX500(I2C3)
|
|
||||||
|
|
||||||
#define UX500_L2CC_BASE UX500(L2CC)
|
|
||||||
#define UX500_MCDE_BASE UX500(MCDE)
|
|
||||||
#define UX500_MTU0_BASE UX500(MTU0)
|
|
||||||
#define UX500_MTU1_BASE UX500(MTU1)
|
|
||||||
#define UX500_PRCMU_BASE UX500(PRCMU)
|
|
||||||
|
|
||||||
#define UX500_RNG_BASE UX500(RNG)
|
|
||||||
#define UX500_RTC_BASE UX500(RTC)
|
|
||||||
|
|
||||||
#define UX500_SCU_BASE UX500(SCU)
|
|
||||||
|
|
||||||
#define UX500_SDI0_BASE UX500(SDI0)
|
|
||||||
#define UX500_SDI1_BASE UX500(SDI1)
|
|
||||||
#define UX500_SDI2_BASE UX500(SDI2)
|
|
||||||
#define UX500_SDI3_BASE UX500(SDI3)
|
|
||||||
#define UX500_SDI4_BASE UX500(SDI4)
|
|
||||||
|
|
||||||
#define UX500_SPI0_BASE UX500(SPI0)
|
|
||||||
#define UX500_SPI1_BASE UX500(SPI1)
|
|
||||||
#define UX500_SPI2_BASE UX500(SPI2)
|
|
||||||
#define UX500_SPI3_BASE UX500(SPI3)
|
|
||||||
|
|
||||||
#define UX500_SIA_BASE UX500(SIA)
|
|
||||||
#define UX500_SVA_BASE UX500(SVA)
|
|
||||||
|
|
||||||
#define UX500_TWD_BASE UX500(TWD)
|
|
||||||
|
|
||||||
#define UX500_UART0_BASE UX500(UART0)
|
|
||||||
#define UX500_UART1_BASE UX500(UART1)
|
|
||||||
#define UX500_UART2_BASE UX500(UART2)
|
|
||||||
|
|
||||||
#define UX500_USBOTG_BASE UX500(USBOTG)
|
|
||||||
|
|
||||||
/* ST-Ericsson modified pl022 id */
|
/* ST-Ericsson modified pl022 id */
|
||||||
#define SSP_PER_ID 0x01080022
|
#define SSP_PER_ID 0x01080022
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <asm/cputype.h>
|
#include <mach/id.h>
|
||||||
|
|
||||||
static inline bool cpu_is_u8500(void)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_UX500_SOC_DB8500
|
|
||||||
return 1;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CPUID_DB8500ED 0x410fc090
|
|
||||||
#define CPUID_DB8500V1 0x411fc091
|
|
||||||
#define CPUID_DB8500V2 0x412fc091
|
|
||||||
|
|
||||||
static inline bool cpu_is_u8500ed(void)
|
|
||||||
{
|
|
||||||
return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500ED);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool cpu_is_u8500v1(void)
|
|
||||||
{
|
|
||||||
return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool cpu_is_u8500v2(void)
|
|
||||||
{
|
|
||||||
return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_UX500_SOC_DB8500
|
|
||||||
bool cpu_is_u8500v10(void);
|
|
||||||
bool cpu_is_u8500v11(void);
|
|
||||||
bool cpu_is_u8500v20(void);
|
|
||||||
#else
|
|
||||||
static inline bool cpu_is_u8500v10(void) { return false; }
|
|
||||||
static inline bool cpu_is_u8500v11(void) { return false; }
|
|
||||||
static inline bool cpu_is_u8500v20(void) { return false; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline bool cpu_is_u5500(void)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_UX500_SOC_DB5500
|
|
||||||
return 1;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
|
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
|
||||||
|
|
||||||
|
80
arch/arm/mach-ux500/include/mach/id.h
Normal file
80
arch/arm/mach-ux500/include/mach/id.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) ST-Ericsson SA 2010
|
||||||
|
*
|
||||||
|
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
|
||||||
|
* License terms: GNU General Public License (GPL) version 2
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MACH_UX500_ID
|
||||||
|
#define __MACH_UX500_ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct dbx500_asic_id - fields of the ASIC ID
|
||||||
|
* @process: the manufacturing process, 0x40 is 40 nm 0x00 is "standard"
|
||||||
|
* @partnumber: hithereto 0x8500 for DB8500
|
||||||
|
* @revision: version code in the series
|
||||||
|
*/
|
||||||
|
struct dbx500_asic_id {
|
||||||
|
u16 partnumber;
|
||||||
|
u8 revision;
|
||||||
|
u8 process;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct dbx500_asic_id dbx500_id;
|
||||||
|
|
||||||
|
static inline unsigned int __attribute_const__ dbx500_partnumber(void)
|
||||||
|
{
|
||||||
|
return dbx500_id.partnumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int __attribute_const__ dbx500_revision(void)
|
||||||
|
{
|
||||||
|
return dbx500_id.revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SOCs
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool __attribute_const__ cpu_is_u8500(void)
|
||||||
|
{
|
||||||
|
return dbx500_partnumber() == 0x8500;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool __attribute_const__ cpu_is_u5500(void)
|
||||||
|
{
|
||||||
|
return dbx500_partnumber() == 0x5500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 8500 revisions
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool __attribute_const__ cpu_is_u8500ed(void)
|
||||||
|
{
|
||||||
|
return cpu_is_u8500() && dbx500_revision() == 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool __attribute_const__ cpu_is_u8500v1(void)
|
||||||
|
{
|
||||||
|
return cpu_is_u8500() && (dbx500_revision() & 0xf0) == 0xA0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool __attribute_const__ cpu_is_u8500v10(void)
|
||||||
|
{
|
||||||
|
return cpu_is_u8500() && dbx500_revision() == 0xA0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool __attribute_const__ cpu_is_u8500v11(void)
|
||||||
|
{
|
||||||
|
return cpu_is_u8500() && dbx500_revision() == 0xA1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool __attribute_const__ cpu_is_u8500v2(void)
|
||||||
|
{
|
||||||
|
return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ux500_unknown_soc() BUG()
|
||||||
|
|
||||||
|
#endif
|
@ -36,7 +36,7 @@
|
|||||||
/* This will be overridden by board-specific irq headers */
|
/* This will be overridden by board-specific irq headers */
|
||||||
#define IRQ_BOARD_END IRQ_BOARD_START
|
#define IRQ_BOARD_END IRQ_BOARD_START
|
||||||
|
|
||||||
#ifdef CONFIG_MACH_U8500_MOP
|
#ifdef CONFIG_MACH_U8500
|
||||||
#include <mach/irqs-board-mop500.h>
|
#include <mach/irqs-board-mop500.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include <asm/mach/time.h>
|
#include <asm/mach/time.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
|
||||||
extern void __init ux500_map_io(void);
|
void __init ux500_map_io(void);
|
||||||
extern void __init u5500_map_io(void);
|
extern void __init u5500_map_io(void);
|
||||||
extern void __init u8500_map_io(void);
|
extern void __init u8500_map_io(void);
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
#include <mach/id.h>
|
||||||
|
|
||||||
#define MODEM_INTCON_BASE_ADDR 0xBFFD3000
|
#define MODEM_INTCON_BASE_ADDR 0xBFFD3000
|
||||||
#define MODEM_INTCON_SIZE 0xFFF
|
#define MODEM_INTCON_SIZE 0xFFF
|
||||||
|
|
||||||
@ -101,6 +103,9 @@ static int modem_irq_init(void)
|
|||||||
static struct irq_chip modem_irq_chip;
|
static struct irq_chip modem_irq_chip;
|
||||||
struct modem_irq *mi;
|
struct modem_irq *mi;
|
||||||
|
|
||||||
|
if (!cpu_is_u5500())
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n",
|
pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n",
|
||||||
IRQ_DB5500_MODEM);
|
IRQ_DB5500_MODEM);
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/smp_scu.h>
|
#include <asm/smp_scu.h>
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
|
#include <mach/setup.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* control for which core is the next to come out of the secondary
|
* control for which core is the next to come out of the secondary
|
||||||
@ -40,6 +41,18 @@ static void write_pen_release(int val)
|
|||||||
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
|
outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __iomem *scu_base_addr(void)
|
||||||
|
{
|
||||||
|
if (cpu_is_u5500())
|
||||||
|
return __io_address(U5500_SCU_BASE);
|
||||||
|
else if (cpu_is_u8500())
|
||||||
|
return __io_address(U8500_SCU_BASE);
|
||||||
|
else
|
||||||
|
ux500_unknown_soc();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(boot_lock);
|
static DEFINE_SPINLOCK(boot_lock);
|
||||||
|
|
||||||
void __cpuinit platform_secondary_init(unsigned int cpu)
|
void __cpuinit platform_secondary_init(unsigned int cpu)
|
||||||
@ -100,21 +113,28 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
|
|||||||
|
|
||||||
static void __init wakeup_secondary(void)
|
static void __init wakeup_secondary(void)
|
||||||
{
|
{
|
||||||
|
void __iomem *backupram;
|
||||||
|
|
||||||
|
if (cpu_is_u5500())
|
||||||
|
backupram = __io_address(U5500_BACKUPRAM0_BASE);
|
||||||
|
else if (cpu_is_u8500())
|
||||||
|
backupram = __io_address(U8500_BACKUPRAM0_BASE);
|
||||||
|
else
|
||||||
|
ux500_unknown_soc();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* write the address of secondary startup into the backup ram register
|
* write the address of secondary startup into the backup ram register
|
||||||
* at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
|
* at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
|
||||||
* backup ram register at offset 0x1FF0, which is what boot rom code
|
* backup ram register at offset 0x1FF0, which is what boot rom code
|
||||||
* is waiting for. This would wake up the secondary core from WFE
|
* is waiting for. This would wake up the secondary core from WFE
|
||||||
*/
|
*/
|
||||||
#define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4
|
#define UX500_CPU1_JUMPADDR_OFFSET 0x1FF4
|
||||||
__raw_writel(virt_to_phys(u8500_secondary_startup),
|
__raw_writel(virt_to_phys(u8500_secondary_startup),
|
||||||
__io_address(UX500_BACKUPRAM0_BASE) +
|
backupram + UX500_CPU1_JUMPADDR_OFFSET);
|
||||||
U8500_CPU1_JUMPADDR_OFFSET);
|
|
||||||
|
|
||||||
#define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
|
#define UX500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
|
||||||
__raw_writel(0xA1FEED01,
|
__raw_writel(0xA1FEED01,
|
||||||
__io_address(UX500_BACKUPRAM0_BASE) +
|
backupram + UX500_CPU1_WAKEMAGIC_OFFSET);
|
||||||
U8500_CPU1_WAKEMAGIC_OFFSET);
|
|
||||||
|
|
||||||
/* make sure write buffer is drained */
|
/* make sure write buffer is drained */
|
||||||
mb();
|
mb();
|
||||||
@ -126,9 +146,10 @@ static void __init wakeup_secondary(void)
|
|||||||
*/
|
*/
|
||||||
void __init smp_init_cpus(void)
|
void __init smp_init_cpus(void)
|
||||||
{
|
{
|
||||||
|
void __iomem *scu_base = scu_base_addr();
|
||||||
unsigned int i, ncores;
|
unsigned int i, ncores;
|
||||||
|
|
||||||
ncores = scu_get_core_count(__io_address(UX500_SCU_BASE));
|
ncores = scu_base ? scu_get_core_count(scu_base) : 1;
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (ncores > NR_CPUS) {
|
if (ncores > NR_CPUS) {
|
||||||
@ -154,6 +175,6 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
|
|||||||
for (i = 0; i < max_cpus; i++)
|
for (i = 0; i < max_cpus; i++)
|
||||||
set_cpu_present(i, true);
|
set_cpu_present(i, true);
|
||||||
|
|
||||||
scu_enable(__io_address(UX500_SCU_BASE));
|
scu_enable(scu_base_addr());
|
||||||
wakeup_secondary();
|
wakeup_secondary();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user