From 951b833ee88c2b6df4346414dc9d88a96076ff2d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 13 May 2015 15:01:48 +0200 Subject: [PATCH 01/10] ARM: ux500: delete UART static map Delete the static maps for the Ux500 UARTs and rely on debug_ll_io_init() to do the trick. commit f87b95dd2e4a8832b1d6034f15a5324db42608a0 "ARM: ux500: move debugmacro to debug includes" defined the necessary addruart macro two years ago. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 537a7753afc1..391d329a7e88 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -43,12 +43,6 @@ static struct prcmu_pdata db8500_prcmu_pdata = { .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET, }; -/* 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), -}; - /* 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 */ @@ -73,11 +67,7 @@ static struct map_desc u9540_io_desc[] __initdata = { static 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)); - + debug_ll_io_init(); ux500_map_io(); iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc)); From 2d6dd1711346d1708eacdbb1b5e8a5a573562fd1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 09:20:23 +0200 Subject: [PATCH 02/10] ARM: ux500: remove static maps from platsmp This removes the reliance on static maps for SCU and backupram for the SMP startup of the Ux500 SoC. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/platsmp.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index a44967f3168c..1e13d0a8ad77 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -26,6 +26,9 @@ #include "db8500-regs.h" #include "id.h" +static void __iomem *scu_base; +static void __iomem *backupram; + /* This is called from headsmp.S to wakeup the secondary core */ extern void u8500_secondary_startup(void); @@ -41,16 +44,6 @@ static void write_pen_release(int val) sync_cache_w(&pen_release); } -static void __iomem *scu_base_addr(void) -{ - if (cpu_is_u8500_family() || cpu_is_ux540_family()) - return __io_address(U8500_SCU_BASE); - else - ux500_unknown_soc(); - - return NULL; -} - static DEFINE_SPINLOCK(boot_lock); static void ux500_secondary_init(unsigned int cpu) @@ -104,13 +97,6 @@ static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init wakeup_secondary(void) { - void __iomem *backupram; - - if (cpu_is_u8500_family() || cpu_is_ux540_family()) - backupram = __io_address(U8500_BACKUPRAM0_BASE); - else - ux500_unknown_soc(); - /* * write the address of secondary startup into the backup ram register * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the @@ -135,10 +121,11 @@ static void __init wakeup_secondary(void) */ static void __init ux500_smp_init_cpus(void) { - void __iomem *scu_base = scu_base_addr(); unsigned int i, ncores; - ncores = scu_base ? scu_get_core_count(scu_base) : 1; + scu_base = ioremap(U8500_SCU_BASE, 0x100); + backupram = ioremap(U8500_BACKUPRAM0_BASE, SZ_8K); + ncores = scu_get_core_count(scu_base); /* sanity check */ if (ncores > nr_cpu_ids) { @@ -153,8 +140,7 @@ static void __init ux500_smp_init_cpus(void) static void __init ux500_smp_prepare_cpus(unsigned int max_cpus) { - - scu_enable(scu_base_addr()); + scu_enable(scu_base); wakeup_secondary(); } From 80757f2335c93fbb9a8fa5a2e68f8ef46d2d5081 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 09:35:46 +0200 Subject: [PATCH 03/10] ARM: ux500: remap BB offset dynamically Instead of relying on static maps, remap the BB chip ID offset dynamically. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 391d329a7e88..0b3ebbf38702 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -104,14 +104,18 @@ static struct arm_pmu_platdata db8500_pmu_platdata = { static const char *db8500_read_soc_id(void) { - void __iomem *uid = __io_address(U8500_BB_UID_BASE); + void __iomem *uid; + uid = ioremap(U8500_BB_UID_BASE, 0x20); + if (!uid) + return NULL; /* Throw these device-specific numbers into the entropy pool */ add_device_randomness(uid, 0x14); return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", readl((u32 *)uid+0), readl((u32 *)uid+1), readl((u32 *)uid+2), readl((u32 *)uid+3), readl((u32 *)uid+4)); + iounmap(uid); } static struct device * __init db8500_soc_device_init(void) From 58202033faca18198af21dabb7e75481d4a2cd8a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 09:46:40 +0200 Subject: [PATCH 04/10] ARM: ux500: get SCU base from device tree The SMP startup/shutdown code relied on a static SCU base address, let's get this from the device tree instead. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/platsmp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 1e13d0a8ad77..62b1de922bd8 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -122,8 +124,13 @@ static void __init wakeup_secondary(void) static void __init ux500_smp_init_cpus(void) { unsigned int i, ncores; + struct device_node *np; - scu_base = ioremap(U8500_SCU_BASE, 0x100); + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); + scu_base = of_iomap(np, 0); + of_node_put(np); + if (!scu_base) + return; backupram = ioremap(U8500_BACKUPRAM0_BASE, SZ_8K); ncores = scu_get_core_count(scu_base); From 26ef94dc8b97156ce1ce3fb74855a598dac067aa Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 09:48:37 +0200 Subject: [PATCH 05/10] ARM: ux500: get rid of static GIC dist base The GIC distributor was mapped statically for the PM code but the driver already get the base address from the DT. Augment the PM code to get the base from the device tree and remove the static map. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 1 - arch/arm/mach-ux500/pm.c | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 0b3ebbf38702..a36fdd8657d2 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -47,7 +47,6 @@ static struct prcmu_pdata db8500_prcmu_pdata = { 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), __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), }; diff --git a/arch/arm/mach-ux500/pm.c b/arch/arm/mach-ux500/pm.c index 2cb587b50905..8538910db202 100644 --- a/arch/arm/mach-ux500/pm.c +++ b/arch/arm/mach-ux500/pm.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "db8500-regs.h" #include "pm_domains.h" @@ -42,6 +44,7 @@ #define PRCM_ARMITVAL127TO96 (prcmu_base + 0x26C) static void __iomem *prcmu_base; +static void __iomem *dist_base; /* This function decouple the gic from the prcmu */ int prcmu_gic_decouple(void) @@ -88,7 +91,6 @@ bool prcmu_gic_pending_irq(void) { u32 pr; /* Pending register */ u32 er; /* Enable register */ - void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE); int i; /* 5 registers. STI & PPI not skipped */ @@ -143,7 +145,6 @@ bool prcmu_is_cpu_in_wfi(int cpu) int prcmu_copy_gic_settings(void) { u32 er; /* Enable register */ - void __iomem *dist_base = __io_address(U8500_GIC_DIST_BASE); int i; /* We skip the STI and PPI */ @@ -179,11 +180,21 @@ static const struct platform_suspend_ops ux500_suspend_ops = { void __init ux500_pm_init(u32 phy_base, u32 size) { + struct device_node *np; + prcmu_base = ioremap(phy_base, size); if (!prcmu_base) { pr_err("could not remap PRCMU for PM functions\n"); return; } + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic"); + dist_base = of_iomap(np, 0); + of_node_put(np); + if (!dist_base) { + pr_err("could not remap GIC dist base for PM functions\n"); + return; + } + /* * On watchdog reboot the GIC is in some cases decoupled. * This will make sure that the GIC is correctly configured. From c1424803f6467fbbf269a5dfa830d9c60ae32181 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 09:53:32 +0200 Subject: [PATCH 06/10] ARM: ux500: get rid of SCU and backupram static maps After moving the SMP and PM code to use dynamic mappings from the device tree, we can delete the static maps for SCU and backup RAM. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index a36fdd8657d2..3562b9aea767 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -45,10 +45,7 @@ static struct prcmu_pdata db8500_prcmu_pdata = { /* 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_L2CC_BASE, SZ_4K), - __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), }; /* U8500 IO map specific description */ From 583ecab9e36ec3077228cc4e303276856ee7519e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 10:06:55 +0200 Subject: [PATCH 07/10] ARM: ux500: kill off L2CC static map The l2x0 level 2 cache initialization used a static map to get at the l2x0 registers. Get rid of this by getting the register range from the device tree and just remap it for the short time we need it. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cache-l2x0.c | 11 ++++++++++- arch/arm/mach-ux500/cpu-db8500.c | 7 ------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c index e97ee556f92f..7557bede7ae6 100644 --- a/arch/arm/mach-ux500/cache-l2x0.c +++ b/arch/arm/mach-ux500/cache-l2x0.c @@ -6,6 +6,7 @@ #include #include +#include #include @@ -15,7 +16,14 @@ static int __init ux500_l2x0_unlock(void) { int i; - void __iomem *l2x0_base = __io_address(U8500_L2CC_BASE); + struct device_node *np; + void __iomem *l2x0_base; + + np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache"); + l2x0_base = of_iomap(np, 0); + of_node_put(np); + if (!l2x0_base) + return -ENODEV; /* * Unlock Data and Instruction Lock if locked. Ux500 U-Boot versions @@ -30,6 +38,7 @@ static int __init ux500_l2x0_unlock(void) writel_relaxed(0x0, l2x0_base + L2X0_LOCKDOWN_WAY_I_BASE + i * L2X0_LOCKDOWN_STRIDE); } + iounmap(l2x0_base); return 0; } diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 3562b9aea767..fd0bc1978dbb 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -43,11 +43,6 @@ static struct prcmu_pdata db8500_prcmu_pdata = { .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET, }; -/* U8500 and U9540 common io_desc */ -static struct map_desc u8500_common_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_L2CC_BASE, SZ_4K), -}; - /* U8500 IO map specific description */ static struct map_desc u8500_io_desc[] __initdata = { __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), @@ -66,8 +61,6 @@ static void __init u8500_map_io(void) debug_ll_io_init(); ux500_map_io(); - iotable_init(u8500_common_io_desc, ARRAY_SIZE(u8500_common_io_desc)); - if (cpu_is_ux540_family()) iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc)); else From 6252bd35782a3bf636b665c0d5700dd449492ca2 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 10:29:59 +0200 Subject: [PATCH 08/10] ARM: ux500: look up PRCMU resource from DT This removes the static map for the PRCMU in favor of looking up that resource from the device tree. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 18 ------------------ arch/arm/mach-ux500/cpu.c | 20 +++++++++++++------- 2 files changed, 13 insertions(+), 25 deletions(-) diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index fd0bc1978dbb..d9359d7b80d7 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -43,28 +43,10 @@ static struct prcmu_pdata db8500_prcmu_pdata = { .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET, }; -/* U8500 IO map specific description */ -static struct map_desc u8500_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), - __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), - -}; - -/* U9540 IO map specific description */ -static struct map_desc u9540_io_desc[] __initdata = { - __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K + SZ_8K), - __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K + SZ_8K), -}; - static void __init u8500_map_io(void) { debug_ll_io_init(); ux500_map_io(); - - if (cpu_is_ux540_family()) - iotable_init(u9540_io_desc, ARRAY_SIZE(u9540_io_desc)); - else - iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); } /* diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 6ced0f680262..e31d3d61c998 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -52,31 +53,36 @@ void ux500_restart(enum reboot_mode mode, const char *cmd) */ void __init ux500_init_irq(void) { + struct device_node *np; + struct resource r; + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND); irqchip_init(); + np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu"); + of_address_to_resource(np, 0, &r); + of_node_put(np); + if (!r.start) { + pr_err("could not find PRCMU base resource\n"); + return; + } + prcmu_early_init(r.start, r.end-r.start); + ux500_pm_init(r.start, r.end-r.start); /* * Init clocks here so that they are available for system timer * initialization. */ if (cpu_is_u8500_family()) { - prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1); - ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1); - u8500_of_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE, U8500_CLKRST3_BASE, U8500_CLKRST5_BASE, U8500_CLKRST6_BASE); } else if (cpu_is_u9540()) { - prcmu_early_init(U8500_PRCMU_BASE, SZ_8K - 1); - ux500_pm_init(U8500_PRCMU_BASE, SZ_8K - 1); u9540_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE, U8500_CLKRST3_BASE, U8500_CLKRST5_BASE, U8500_CLKRST6_BASE); } else if (cpu_is_u8540()) { - prcmu_early_init(U8500_PRCMU_BASE, SZ_8K + SZ_4K - 1); - ux500_pm_init(U8500_PRCMU_BASE, SZ_8K + SZ_4K - 1); u8540_clk_init(U8500_CLKRST1_BASE, U8500_CLKRST2_BASE, U8500_CLKRST3_BASE, U8500_CLKRST5_BASE, U8500_CLKRST6_BASE); From 9bac89e069e2aa7c4602a2d76a76f3d8ba8a3aa3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 10:37:05 +0200 Subject: [PATCH 09/10] ARM: ux500: rename ux500_map_io This function is not mapping any I/O other than for probing the chip ID. Rename it to make the function graspable. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 2 +- arch/arm/mach-ux500/id.c | 2 +- arch/arm/mach-ux500/setup.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index d9359d7b80d7..16913800bbf9 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -46,7 +46,7 @@ static struct prcmu_pdata db8500_prcmu_pdata = { static void __init u8500_map_io(void) { debug_ll_io_init(); - ux500_map_io(); + ux500_setup_id(); } /* diff --git a/arch/arm/mach-ux500/id.c b/arch/arm/mach-ux500/id.c index 392f2fdb37d0..1e81e990044b 100644 --- a/arch/arm/mach-ux500/id.c +++ b/arch/arm/mach-ux500/id.c @@ -72,7 +72,7 @@ static unsigned int partnumber(unsigned int asicid) * DB9540 0x413fc090 0xFFFFDBF4 0x009540xx */ -void __init ux500_map_io(void) +void __init ux500_setup_id(void) { unsigned int cpuid = read_cpuid_id(); unsigned int asicid = 0; diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h index 2dea8b59d222..cf5a8736ea9d 100644 --- a/arch/arm/mach-ux500/setup.h +++ b/arch/arm/mach-ux500/setup.h @@ -18,7 +18,7 @@ void ux500_restart(enum reboot_mode mode, const char *cmd); -void __init ux500_map_io(void); +void __init ux500_setup_id(void); extern void __init ux500_init_irq(void); From 1da4d13912e773523ef095fa05704d6962babe90 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 14 May 2015 10:42:32 +0200 Subject: [PATCH 10/10] ARM: ux500: delete static resource defines These macros were used in the past to define static resources, but are not used anymore and have no future, delete them. Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/setup.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/arch/arm/mach-ux500/setup.h b/arch/arm/mach-ux500/setup.h index cf5a8736ea9d..1fb6ad2789f1 100644 --- a/arch/arm/mach-ux500/setup.h +++ b/arch/arm/mach-ux500/setup.h @@ -26,20 +26,6 @@ extern struct device *ux500_soc_device_init(const char *soc_id); extern void ux500_timer_init(void); -#define __IO_DEV_DESC(x, sz) { \ - .virtual = IO_ADDRESS(x), \ - .pfn = __phys_to_pfn(x), \ - .length = sz, \ - .type = MT_DEVICE, \ -} - -#define __MEM_DEV_DESC(x, sz) { \ - .virtual = IO_ADDRESS(x), \ - .pfn = __phys_to_pfn(x), \ - .length = sz, \ - .type = MT_MEMORY_RWX, \ -} - extern struct smp_operations ux500_smp_ops; extern void ux500_cpu_die(unsigned int cpu);