summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel JAOUEN <michel.jaouen@stericsson.com>2012-01-19 17:33:37 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:02:43 +0200
commitead8510d99488080939f20bd18593d8cec1d232b (patch)
tree0bd8d0687ab07d1ad3cff3b7356788c0d86fae58
parent98cae5b67dc5c3ce4e188c82eabd7b30029b6273 (diff)
mach-ux500: support ape u9450
id, cpu, irq, reg, timer, uart, l2 cache. ST-Ericsson ID: 409625 Signed-off-by: Michel JAOUEN <michel.jaouen@stericsson.com>
-rw-r--r--arch/arm/mach-ux500/cache-l2x0.c17
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c29
-rw-r--r--arch/arm/mach-ux500/cpu.c4
-rw-r--r--arch/arm/mach-ux500/id.c26
-rw-r--r--arch/arm/mach-ux500/include/mach/db8500-regs.h6
-rw-r--r--arch/arm/mach-ux500/include/mach/hardware.h12
-rw-r--r--arch/arm/mach-ux500/include/mach/id.h11
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-db9540.h58
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs.h4
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h7
-rw-r--r--arch/arm/mach-ux500/l2x0-prefetch.c2
-rw-r--r--arch/arm/mach-ux500/platsmp.c4
-rw-r--r--arch/arm/mach-ux500/timer.c2
13 files changed, 162 insertions, 20 deletions
diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
index 77a75ed0df6..7048fc71aff 100644
--- a/arch/arm/mach-ux500/cache-l2x0.c
+++ b/arch/arm/mach-ux500/cache-l2x0.c
@@ -36,9 +36,11 @@ static int __init ux500_l2x0_unlock(void)
static int __init ux500_l2x0_init(void)
{
+ uint32_t aux_val = 0x3e000000; /* 8 way associativity, force WA */
+
if (cpu_is_u5500())
l2x0_base = __io_address(U5500_L2CC_BASE);
- else if (cpu_is_u8500())
+ else if (cpu_is_u8500() || cpu_is_u9540())
l2x0_base = __io_address(U8500_L2CC_BASE);
else
ux500_unknown_soc();
@@ -46,11 +48,18 @@ static int __init ux500_l2x0_init(void)
/* Unlock before init */
ux500_l2x0_unlock();
- /* 64KB way size, 8 way associativity, force WA */
+ /* u9540's L2 has 128KB way size */
+ if (cpu_is_u9540())
+ aux_val |=
+ (0x4 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT); /* 128KB way size */
+ else
+ aux_val |=
+ (0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT); /* 64KB way size */
+
if (of_have_populated_dt())
- l2x0_of_init(0x3e060000, 0xc0000fff);
+ l2x0_of_init(aux_val, 0xc0000fff);
else
- l2x0_init(l2x0_base, 0x3e060000, 0xc0000fff);
+ l2x0_init(l2x0_base, aux_val, 0xc0000fff);
/*
* We can't disable l2 as we are in non secure mode, currently
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 9f75feb07a2..bcd43611b69 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -38,7 +38,8 @@ static struct map_desc u8500_uart_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_UART2_BASE, SZ_4K),
};
-static struct map_desc u8500_io_desc[] __initdata = {
+/* U8500 and U9540 common io_desc */
+static struct map_desc u8500_common_io_desc[] __initdata = {
/* SCU base also covers GIC CPU BASE and TWD with its 4K page */
__IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
__IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
@@ -47,12 +48,6 @@ static struct map_desc u8500_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_MTU1_BASE, SZ_4K),
__IO_DEV_DESC(U8500_RTC_BASE, SZ_4K),
__IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K),
-
- /* Map U8500_PUBLIC_BOOT_ROM_BASE (base+17000) only
- * for TEE security driver
- * and avoid overlap with asic ID at base+1D000 */
- __MEM_DEV_DESC(U8500_BOOT_ROM_BASE+0x17000, 6*SZ_4K),
-
__IO_DEV_DESC(U8500_CLKRST1_BASE, SZ_4K),
__IO_DEV_DESC(U8500_CLKRST2_BASE, SZ_4K),
__IO_DEV_DESC(U8500_CLKRST3_BASE, SZ_4K),
@@ -67,6 +62,19 @@ static struct map_desc u8500_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K),
};
+/* U8500 IO map specific description */
+static struct map_desc u8500_io_desc[] __initdata = {
+ /* Map U8500_PUBLIC_BOOT_ROM_BASE (base+17000) only
+ * for TEE security driver
+ * and avoid overlap with asic ID at base+1D000 */
+ __MEM_DEV_DESC(U8500_BOOT_ROM_BASE+0x17000, 6*SZ_4K),
+};
+
+/* U9540 IO map specific description */
+static struct map_desc u9540_io_desc[] __initdata = {
+ __MEM_DEV_DESC_DB9540_ROM(U9540_BOOT_ROM_BASE, SZ_1M),
+};
+
void __init u8500_map_io(void)
{
/*
@@ -84,7 +92,12 @@ void __init u8500_map_io(void)
ux500_map_io();
- iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
+ iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc));
+
+ if (cpu_is_u9540())
+ iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc));
+ else
+ iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
_PRCMU_BASE = __io_address(U8500_PRCMU_BASE);
}
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 3375becddd9..6be4e1d62c6 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -93,7 +93,7 @@ void __init ux500_init_irq(void)
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()) {
+ } else if (cpu_is_u8500() || cpu_is_u9540()) {
dist_base = __io_address(U8500_GIC_DIST_BASE);
cpu_base = __io_address(U8500_GIC_CPU_BASE);
} else
@@ -118,7 +118,7 @@ void __init ux500_init_irq(void)
*/
if (cpu_is_u5500())
db5500_prcmu_early_init();
- if (cpu_is_u8500())
+ if (cpu_is_u8500() || cpu_is_u9540())
db8500_prcmu_early_init();
arm_pm_restart = ux500_restart;
diff --git a/arch/arm/mach-ux500/id.c b/arch/arm/mach-ux500/id.c
index 80489597ced..fe1d3ffe3f7 100644
--- a/arch/arm/mach-ux500/id.c
+++ b/arch/arm/mach-ux500/id.c
@@ -39,6 +39,25 @@ static unsigned int ux500_read_asicid(phys_addr_t addr)
return readl(__io_address(addr));
}
+static unsigned int u9540_read_asicid(phys_addr_t addr)
+{
+ phys_addr_t base = addr & ~0xfff;
+ struct map_desc desc = {
+ .virtual = IO_ADDRESS_DB9540_ROM(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_db9540_rom(addr));
+}
+
static void ux500_print_soc_info(unsigned int asicid)
{
unsigned int rev = dbx500_revision();
@@ -69,6 +88,7 @@ static unsigned int partnumber(unsigned int asicid)
* DB8520v2.2 0x412fc091 0x9001DBF4 0x008500B2
* AP9500 0x412fc091 0x9001DBF4 0x008500B2
* DB5500v1 0x412fc091 0x9001FFF4 0x005500A0
+ * DB9540 0x413fc090 0xFFFFDBF4 0x009540xx
*/
void __init ux500_map_io(void)
@@ -93,6 +113,12 @@ void __init ux500_map_io(void)
/* DB5500v1 */
addr = 0x9001FFF4;
break;
+
+ case 0x413fc090: /* DB9540 */
+ addr = 0xFFFFDBF4;
+ asicid = u9540_read_asicid(addr);
+ addr = 0;
+ break;
}
if (addr)
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h
index 9ec20b96d8f..1530d493879 100644
--- a/arch/arm/mach-ux500/include/mach/db8500-regs.h
+++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h
@@ -41,6 +41,10 @@
/* ASIC ID is at 0xbf4 offset within this region */
#define U8500_ASIC_ID_BASE 0x9001D000
+#define U9540_BOOT_ROM_BASE 0xFFFE0000
+/* ASIC ID is at 0xbf4 offset within this region */
+#define U9540_ASIC_ID_BASE 0xFFFFD000
+
#define U8500_PER6_BASE 0xa03c0000
#define U8500_PER7_BASE 0xa03d0000
#define U8500_PER5_BASE 0xa03e0000
@@ -96,7 +100,9 @@
#define U8500_SCR_BASE (U8500_PER4_BASE + 0x05000)
#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000)
#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000)
+#define U9540_DMC1_BASE (U8500_PER4_BASE + 0x0A000)
#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
+#define U9540_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x6A000)
#define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000)
#define U8500_PRCMU_TIMER_3_BASE (U8500_PER4_BASE + 0x07338)
#define U8500_PRCMU_TIMER_4_BASE (U8500_PER4_BASE + 0x07450)
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
index 7429c6b0064..88b105d8d89 100644
--- a/arch/arm/mach-ux500/include/mach/hardware.h
+++ b/arch/arm/mach-ux500/include/mach/hardware.h
@@ -22,9 +22,21 @@
#define IO_ADDRESS(x) \
(((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL)
+/*
+ * For 9540, ROM code is at address 0xFFFE0000
+ * The previous macro cannot be used
+ * Or else its virtual address would be above 0xFFFFFFFF
+ */
+#define IO_ADDRESS_DB9540_ROM(x) \
+ (((x) & 0x0001ffff) + U8500_IO_VIRTUAL + 0x0B000000)
+
/* typesafe io address */
#define __io_address(n) IOMEM(IO_ADDRESS(n))
+#define __io_address_db9540_rom(n) __io(IO_ADDRESS_DB9540_ROM(n))
+/* Used by some plat-nomadik code */
+#define io_p2v(n) __io_address(n)
+
#include <mach/db8500-regs.h>
#include <mach/db5500-regs.h>
diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h
index e888929d43d..3bbeb0c9ae3 100644
--- a/arch/arm/mach-ux500/include/mach/id.h
+++ b/arch/arm/mach-ux500/include/mach/id.h
@@ -72,6 +72,14 @@ static inline bool cpu_is_u9500(void)
return false;
}
#endif
+static inline bool __attribute_const__ cpu_is_u9540(void)
+{
+#ifdef CONFIG_UX500_SOC_DB8500
+ return dbx500_partnumber() == 0x9540;
+#else
+ return false;
+#endif
+}
/*
* 5500 revisions
@@ -123,7 +131,8 @@ static inline bool cpu_is_u8500v22(void)
static inline bool cpu_is_u8500v20_or_later(void)
{
- return cpu_is_u8500() && ((dbx500_revision() & 0xf0) >= 0xB0);
+ return cpu_is_u9540() ||
+ (cpu_is_u8500() && ((dbx500_revision() & 0xf0) >= 0xB0));
}
static inline bool ux500_is_svp(void)
diff --git a/arch/arm/mach-ux500/include/mach/irqs-db9540.h b/arch/arm/mach-ux500/include/mach/irqs-db9540.h
new file mode 100644
index 00000000000..6a616e4d320
--- /dev/null
+++ b/arch/arm/mach-ux500/include/mach/irqs-db9540.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: Sebastien Pasdeloup <sebastien.pasdeloup-nonst@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_DB9540_H
+#define __MACH_IRQS_DB9540_H
+
+#define IRQ_AP9540_VSENSOR (IRQ_SHPI_START + 30)
+#define IRQ_AP9540_SLIMBUS0 (IRQ_SHPI_START + 101)
+#define IRQ_AP9540_THSENS (IRQ_SHPI_START + 102)
+#define IRQ_AP9540_DDR0 (IRQ_SHPI_START + 103)
+#define IRQ_AP9540_CTIEXTRIG0 (IRQ_SHPI_START + 111)
+#define IRQ_AP9540_SGX (IRQ_SHPI_START + 112)
+#define IRQ_AP9540_CTIEXTRIG1 (IRQ_SHPI_START + 117)
+#define IRQ_AP9540_C2C_GENO0 (IRQ_SHPI_START + 128)
+#define IRQ_AP9540_C2C_GENO1 (IRQ_SHPI_START + 129)
+#define IRQ_AP9540_C2C_GENO2 (IRQ_SHPI_START + 130)
+#define IRQ_AP9540_C2C_GENO3 (IRQ_SHPI_START + 131)
+#define IRQ_AP9540_C2C_GENO4 (IRQ_SHPI_START + 132)
+#define IRQ_AP9540_C2C_GENO5 (IRQ_SHPI_START + 133)
+#define IRQ_AP9540_C2C_GENO6 (IRQ_SHPI_START + 134)
+#define IRQ_AP9540_C2C_GENO7 (IRQ_SHPI_START + 135)
+#define IRQ_AP9540_C2C_GENO8 (IRQ_SHPI_START + 136)
+#define IRQ_AP9540_C2C_GENO9 (IRQ_SHPI_START + 137)
+#define IRQ_AP9540_C2C_GENO10 (IRQ_SHPI_START + 138)
+#define IRQ_AP9540_C2C_GENO11 (IRQ_SHPI_START + 139)
+#define IRQ_AP9540_C2C_GENO12 (IRQ_SHPI_START + 140)
+#define IRQ_AP9540_C2C_GENO13 (IRQ_SHPI_START + 141)
+#define IRQ_AP9540_C2C_GENO14 (IRQ_SHPI_START + 142)
+#define IRQ_AP9540_C2C_GENO15 (IRQ_SHPI_START + 143)
+#define IRQ_AP9540_C2C_GENO16 (IRQ_SHPI_START + 144)
+#define IRQ_AP9540_C2C_GENO17 (IRQ_SHPI_START + 145)
+#define IRQ_AP9540_C2C_GENO18 (IRQ_SHPI_START + 146)
+#define IRQ_AP9540_C2C_GENO19 (IRQ_SHPI_START + 147)
+#define IRQ_AP9540_C2C_GENO20 (IRQ_SHPI_START + 148)
+#define IRQ_AP9540_C2C_GENO21 (IRQ_SHPI_START + 149)
+#define IRQ_AP9540_C2C_GENO22 (IRQ_SHPI_START + 150)
+#define IRQ_AP9540_C2C_GENO23 (IRQ_SHPI_START + 151)
+#define IRQ_AP9540_C2C_GENO24 (IRQ_SHPI_START + 152)
+#define IRQ_AP9540_C2C_GENO25 (IRQ_SHPI_START + 153)
+#define IRQ_AP9540_C2C_GENO26 (IRQ_SHPI_START + 154)
+#define IRQ_AP9540_C2C_GENO27 (IRQ_SHPI_START + 155)
+#define IRQ_AP9540_C2C_GENO28 (IRQ_SHPI_START + 156)
+#define IRQ_AP9540_C2C_GENO29 (IRQ_SHPI_START + 157)
+#define IRQ_AP9540_C2C_GENO30 (IRQ_SHPI_START + 158)
+#define IRQ_AP9540_C2C_GENO31 (IRQ_SHPI_START + 159)
+#define IRQ_AP9540_C2C_IRQ0 (IRQ_SHPI_START + 160)
+#define IRQ_AP9540_C2C_IRQ1 (IRQ_SHPI_START + 161)
+#define IRQ_AP9540_HVA_ITS (IRQ_SHPI_START + 162)
+#define IRQ_AP9540_HVA_ERR (IRQ_SHPI_START + 163)
+#define IRQ_AP9540_C2C_G1 (IRQ_SHPI_START + 164)
+#define IRQ_AP9540_C2C_DDR1 (IRQ_SHPI_START + 165)
+#define IRQ_AP9540_C2C_SGX_IDLE (IRQ_SHPI_START + 166)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
index 1d273dd67ad..f96628fa147 100644
--- a/arch/arm/mach-ux500/include/mach/irqs.h
+++ b/arch/arm/mach-ux500/include/mach/irqs.h
@@ -27,7 +27,7 @@
/*********************************************************************/
-#define DBX500_NR_INTERNAL_IRQS 160
+#define DBX500_NR_INTERNAL_IRQS 166
/* After chip-specific IRQ numbers we have the GPIO ones */
#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + DBX500_NR_INTERNAL_IRQS)
@@ -47,6 +47,8 @@
#include <mach/irqs-db5500.h>
#include <mach/irqs-db8500.h>
+#include <mach/irqs-db9540.h>
+
#ifdef CONFIG_MACH_MOP500
#include <mach/irqs-board-mop500.h>
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index e4690ad2209..1998b84b50a 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -52,4 +52,11 @@ extern struct sys_timer ux500_timer;
.type = MT_MEMORY, \
}
+#define __MEM_DEV_DESC_DB9540_ROM(x, sz) { \
+ .virtual = IO_ADDRESS_DB9540_ROM(x), \
+ .pfn = __phys_to_pfn(x), \
+ .length = sz, \
+ .type = MT_MEMORY, \
+}
+
#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/l2x0-prefetch.c b/arch/arm/mach-ux500/l2x0-prefetch.c
index 48a4495533f..4085c351f20 100644
--- a/arch/arm/mach-ux500/l2x0-prefetch.c
+++ b/arch/arm/mach-ux500/l2x0-prefetch.c
@@ -107,7 +107,7 @@ static int __init prefetch_ctrl_init(void)
/* Get PL310 base address. It will be used as readonly. */
if (cpu_is_u5500())
l2x0_base = __io_address(U5500_L2CC_BASE);
- else if (cpu_is_u8500())
+ else if (cpu_is_u8500() || cpu_is_u9540())
l2x0_base = __io_address(U8500_L2CC_BASE);
else
ux500_unknown_soc();
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index eff5842f623..dc661de8bca 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -50,7 +50,7 @@ static void __iomem *scu_base_addr(void)
{
if (cpu_is_u5500())
return __io_address(U5500_SCU_BASE);
- else if (cpu_is_u8500())
+ else if (cpu_is_u8500() || cpu_is_u9540())
return __io_address(U8500_SCU_BASE);
else
ux500_unknown_soc();
@@ -122,7 +122,7 @@ static void __init wakeup_secondary(void)
if (cpu_is_u5500())
backupram = __io_address(U5500_BACKUPRAM0_BASE);
- else if (cpu_is_u8500())
+ else if (cpu_is_u8500() || cpu_is_u9540())
backupram = __io_address(U8500_BACKUPRAM0_BASE);
else
ux500_unknown_soc();
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index 8b973c2722f..e69ca9b50a2 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -66,7 +66,7 @@ static void __init ux500_timer_init(void)
if (cpu_is_u5500()) {
mtu_timer_base = __io_address(U5500_MTU0_BASE);
prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
- } else if (cpu_is_u8500()) {
+ } else if (cpu_is_u8500() || cpu_is_u9540()) {
mtu_timer_base = __io_address(U8500_MTU0_BASE);
prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
} else {