From ead8510d99488080939f20bd18593d8cec1d232b Mon Sep 17 00:00:00 2001 From: Michel JAOUEN Date: Thu, 19 Jan 2012 17:33:37 +0100 Subject: mach-ux500: support ape u9450 id, cpu, irq, reg, timer, uart, l2 cache. ST-Ericsson ID: 409625 Signed-off-by: Michel JAOUEN --- arch/arm/mach-ux500/cache-l2x0.c | 17 ++++++-- arch/arm/mach-ux500/cpu-db8500.c | 29 +++++++++---- arch/arm/mach-ux500/cpu.c | 4 +- arch/arm/mach-ux500/id.c | 26 ++++++++++++ arch/arm/mach-ux500/include/mach/db8500-regs.h | 6 +++ arch/arm/mach-ux500/include/mach/hardware.h | 12 ++++++ arch/arm/mach-ux500/include/mach/id.h | 11 ++++- arch/arm/mach-ux500/include/mach/irqs-db9540.h | 58 ++++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/irqs.h | 4 +- arch/arm/mach-ux500/include/mach/setup.h | 7 ++++ arch/arm/mach-ux500/l2x0-prefetch.c | 2 +- arch/arm/mach-ux500/platsmp.c | 4 +- arch/arm/mach-ux500/timer.c | 2 +- 13 files changed, 162 insertions(+), 20 deletions(-) create mode 100644 arch/arm/mach-ux500/include/mach/irqs-db9540.h 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 #include 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 + * 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 #include +#include + #ifdef CONFIG_MACH_MOP500 #include 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 { -- cgit v1.2.3