diff options
Diffstat (limited to 'arch/arm/mach-mvebu')
-rw-r--r-- | arch/arm/mach-mvebu/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada-370-xp.c | 64 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada-370-xp.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/coherency.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/coherency.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/coherency_ll.S | 16 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/common.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/headsmp.S | 16 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/platsmp.c | 10 |
9 files changed, 87 insertions, 88 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index e11acbb0a46..9eb63d72460 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -10,11 +10,11 @@ config ARCH_MVEBU select PLAT_ORION select SPARSE_IRQ select CLKDEV_LOOKUP - select MVEBU_CLK_CORE - select MVEBU_CLK_CPU - select MVEBU_CLK_GATING select MVEBU_MBUS select ZONE_DMA if ARM_LPAE + select ARCH_REQUIRE_GPIOLIB + select MIGHT_HAVE_PCI + select PCI_QUIRKS if PCI if ARCH_MVEBU @@ -29,6 +29,7 @@ config MACH_ARMADA_370_XP config MACH_ARMADA_370 bool "Marvell Armada 370 boards" + select ARMADA_370_CLK select MACH_ARMADA_370_XP select PINCTRL_ARMADA_370 help @@ -37,6 +38,7 @@ config MACH_ARMADA_370 config MACH_ARMADA_XP bool "Marvell Armada XP boards" + select ARMADA_XP_CLK select MACH_ARMADA_370_XP select PINCTRL_ARMADA_XP help diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c index 42a4cb3087e..97cbb802191 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/armada-370-xp.c @@ -14,13 +14,13 @@ #include <linux/kernel.h> #include <linux/init.h> +#include <linux/clk-provider.h> +#include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/io.h> #include <linux/time-armada-370-xp.h> -#include <linux/clk/mvebu.h> #include <linux/dma-mapping.h> #include <linux/mbus.h> -#include <linux/irqchip.h> #include <asm/hardware/cache-l2x0.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -29,52 +29,49 @@ #include "common.h" #include "coherency.h" -static struct map_desc armada_370_xp_io_desc[] __initdata = { - { - .virtual = (unsigned long) ARMADA_370_XP_REGS_VIRT_BASE, - .pfn = __phys_to_pfn(ARMADA_370_XP_REGS_PHYS_BASE), - .length = ARMADA_370_XP_REGS_SIZE, - .type = MT_DEVICE, - }, -}; - -void __init armada_370_xp_map_io(void) +static void __init armada_370_xp_map_io(void) { - iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc)); + debug_ll_io_init(); } -void __init armada_370_xp_timer_and_clk_init(void) -{ - mvebu_clocks_init(); - armada_370_xp_timer_init(); -} +/* + * This initialization will be replaced by a DT-based + * initialization once the mvebu-mbus driver gains DT support. + */ + +#define ARMADA_370_XP_MBUS_WINS_OFFS 0x20000 +#define ARMADA_370_XP_MBUS_WINS_SIZE 0x100 +#define ARMADA_370_XP_SDRAM_WINS_OFFS 0x20180 +#define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20 -void __init armada_370_xp_init_early(void) +static void __init armada_370_xp_mbus_init(void) { char *mbus_soc_name; + struct device_node *dn; + const __be32 mbus_wins_offs = cpu_to_be32(ARMADA_370_XP_MBUS_WINS_OFFS); + const __be32 sdram_wins_offs = cpu_to_be32(ARMADA_370_XP_SDRAM_WINS_OFFS); - /* - * Some Armada 370/XP devices allocate their coherent buffers - * from atomic context. Increase size of atomic coherent pool - * to make sure such the allocations won't fail. - */ - init_dma_coherent_pool_size(SZ_1M); - - /* - * This initialization will be replaced by a DT-based - * initialization once the mvebu-mbus driver gains DT support. - */ if (of_machine_is_compatible("marvell,armada370")) mbus_soc_name = "marvell,armada370-mbus"; else mbus_soc_name = "marvell,armadaxp-mbus"; + dn = of_find_node_by_name(NULL, "internal-regs"); + BUG_ON(!dn); + mvebu_mbus_init(mbus_soc_name, - ARMADA_370_XP_MBUS_WINS_BASE, + of_translate_address(dn, &mbus_wins_offs), ARMADA_370_XP_MBUS_WINS_SIZE, - ARMADA_370_XP_SDRAM_WINS_BASE, + of_translate_address(dn, &sdram_wins_offs), ARMADA_370_XP_SDRAM_WINS_SIZE); +} +static void __init armada_370_xp_timer_and_clk_init(void) +{ + of_clk_init(NULL); + armada_370_xp_timer_init(); + coherency_init(); + armada_370_xp_mbus_init(); #ifdef CONFIG_CACHE_L2X0 l2x0_of_init(0, ~0UL); #endif @@ -83,7 +80,6 @@ void __init armada_370_xp_init_early(void) static void __init armada_370_xp_dt_init(void) { of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); - coherency_init(); } static const char * const armada_370_xp_dt_compat[] = { @@ -95,8 +91,6 @@ DT_MACHINE_START(ARMADA_XP_DT, "Marvell Armada 370/XP (Device Tree)") .smp = smp_ops(armada_xp_smp_ops), .init_machine = armada_370_xp_dt_init, .map_io = armada_370_xp_map_io, - .init_early = armada_370_xp_init_early, - .init_irq = irqchip_init, .init_time = armada_370_xp_timer_and_clk_init, .restart = mvebu_restart, .dt_compat = armada_370_xp_dt_compat, diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h index 2070e1b4f34..c612b2c4ed6 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.h +++ b/arch/arm/mach-mvebu/armada-370-xp.h @@ -15,16 +15,6 @@ #ifndef __MACH_ARMADA_370_XP_H #define __MACH_ARMADA_370_XP_H -#define ARMADA_370_XP_REGS_PHYS_BASE 0xd0000000 -#define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfec00000) -#define ARMADA_370_XP_REGS_SIZE SZ_1M - -/* These defines can go away once mvebu-mbus has a DT binding */ -#define ARMADA_370_XP_MBUS_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000) -#define ARMADA_370_XP_MBUS_WINS_SIZE 0x100 -#define ARMADA_370_XP_SDRAM_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20180) -#define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20 - #ifdef CONFIG_SMP #include <linux/cpumask.h> diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 8278960066c..be117591f7f 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -25,16 +25,11 @@ #include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <asm/smp_plat.h> +#include <asm/cacheflush.h> #include "armada-370-xp.h" -/* - * Some functions in this file are called very early during SMP - * initialization. At that time the device tree framework is not yet - * ready, and it is not possible to get the register address to - * ioremap it. That's why the pointer below is given with an initial - * value matching its virtual mapping - */ -static void __iomem *coherency_base = ARMADA_370_XP_REGS_VIRT_BASE + 0x20200; +unsigned long __cpuinitdata coherency_phys_base; +static void __iomem *coherency_base; static void __iomem *coherency_cpu_base; /* Coherency fabric registers */ @@ -47,18 +42,6 @@ static struct of_device_id of_coherency_table[] = { { /* end of list */ }, }; -#ifdef CONFIG_SMP -int coherency_get_cpu_count(void) -{ - int reg, cnt; - - reg = readl(coherency_base + COHERENCY_FABRIC_CFG_OFFSET); - cnt = (reg & 0xF) + 1; - - return cnt; -} -#endif - /* Function defined in coherency_ll.S */ int ll_set_cpu_coherent(void __iomem *base_addr, unsigned int hw_cpu_id); @@ -143,13 +126,31 @@ int __init coherency_init(void) np = of_find_matching_node(NULL, of_coherency_table); if (np) { + struct resource res; pr_info("Initializing Coherency fabric\n"); + of_address_to_resource(np, 0, &res); + coherency_phys_base = res.start; + /* + * Ensure secondary CPUs will see the updated value, + * which they read before they join the coherency + * fabric, and therefore before they are coherent with + * the boot CPU cache. + */ + sync_cache_w(&coherency_phys_base); coherency_base = of_iomap(np, 0); coherency_cpu_base = of_iomap(np, 1); set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); - bus_register_notifier(&platform_bus_type, - &mvebu_hwcc_platform_nb); } return 0; } + +static int __init coherency_late_init(void) +{ + if (of_find_matching_node(NULL, of_coherency_table)) + bus_register_notifier(&platform_bus_type, + &mvebu_hwcc_platform_nb); + return 0; +} + +postcore_initcall(coherency_late_init); diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h index 2f428137f6f..df33ad8a6c0 100644 --- a/arch/arm/mach-mvebu/coherency.h +++ b/arch/arm/mach-mvebu/coherency.h @@ -14,10 +14,6 @@ #ifndef __MACH_370_XP_COHERENCY_H #define __MACH_370_XP_COHERENCY_H -#ifdef CONFIG_SMP -int coherency_get_cpu_count(void); -#endif - int set_cpu_coherent(int cpu_id, int smp_group_id); int coherency_init(void); diff --git a/arch/arm/mach-mvebu/coherency_ll.S b/arch/arm/mach-mvebu/coherency_ll.S index 53e8391192c..5476669ba90 100644 --- a/arch/arm/mach-mvebu/coherency_ll.S +++ b/arch/arm/mach-mvebu/coherency_ll.S @@ -32,15 +32,21 @@ ENTRY(ll_set_cpu_coherent) /* Add CPU to SMP group - Atomic */ add r3, r0, #ARMADA_XP_CFB_CTL_REG_OFFSET - ldr r2, [r3] +1: + ldrex r2, [r3] orr r2, r2, r1 - str r2, [r3] + strex r0, r2, [r3] + cmp r0, #0 + bne 1b /* Enable coherency on CPU - Atomic */ - add r3, r0, #ARMADA_XP_CFB_CFG_REG_OFFSET - ldr r2, [r3] + add r3, r3, #ARMADA_XP_CFB_CFG_REG_OFFSET +1: + ldrex r2, [r3] orr r2, r2, r1 - str r2, [r3] + strex r0, r2, [r3] + cmp r0, #0 + bne 1b dsb diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h index aa27bc2ffb6..98defd5e92c 100644 --- a/arch/arm/mach-mvebu/common.h +++ b/arch/arm/mach-mvebu/common.h @@ -15,6 +15,8 @@ #ifndef __ARCH_MVEBU_COMMON_H #define __ARCH_MVEBU_COMMON_H +#define ARMADA_XP_MAX_CPUS 4 + void mvebu_restart(char mode, const char *cmd); void armada_370_xp_init_irq(void); diff --git a/arch/arm/mach-mvebu/headsmp.S b/arch/arm/mach-mvebu/headsmp.S index a06e0ede8c0..7147300c8af 100644 --- a/arch/arm/mach-mvebu/headsmp.S +++ b/arch/arm/mach-mvebu/headsmp.S @@ -21,12 +21,6 @@ #include <linux/linkage.h> #include <linux/init.h> -/* - * At this stage the secondary CPUs don't have acces yet to the MMU, so - * we have to provide physical addresses - */ -#define ARMADA_XP_CFB_BASE 0xD0020200 - __CPUINIT /* @@ -35,15 +29,21 @@ * startup */ ENTRY(armada_xp_secondary_startup) + /* Get coherency fabric base physical address */ + adr r0, 1f + ldr r1, [r0] + ldr r0, [r0, r1] /* Read CPU id */ mrc p15, 0, r1, c0, c0, 5 and r1, r1, #0xF /* Add CPU to coherency fabric */ - ldr r0, =ARMADA_XP_CFB_BASE - bl ll_set_cpu_coherent b secondary_startup ENDPROC(armada_xp_secondary_startup) + + .align 2 +1: + .long coherency_phys_base - . diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index 875ea748391..93f2f3ab45f 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c @@ -88,8 +88,16 @@ static int __cpuinit armada_xp_boot_secondary(unsigned int cpu, static void __init armada_xp_smp_init_cpus(void) { + struct device_node *np; unsigned int i, ncores; - ncores = coherency_get_cpu_count(); + + np = of_find_node_by_name(NULL, "cpus"); + if (!np) + panic("No 'cpus' node found\n"); + + ncores = of_get_child_count(np); + if (ncores == 0 || ncores > ARMADA_XP_MAX_CPUS) + panic("Invalid number of CPUs in DT\n"); /* Limit possible CPUs to defconfig */ if (ncores > nr_cpu_ids) { |