diff options
author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2013-03-21 12:59:15 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2013-04-15 10:06:16 -0400 |
commit | 87e1bed4067e33a4636bffc03689ffb045d586d6 (patch) | |
tree | dbc92ffcfd5e90fbdce15689cf0f6113a05d7e24 /arch/arm/mach-mvebu | |
parent | a33dc586c90ef8eee273280782b43b40cd43ad7e (diff) |
arm: mach-mvebu: convert to use mvebu-mbus driver
The changes needed to migrate the mach-mvebu (Armada 370 and Armada
XP) to the mvebu-mbus driver are fairly minimal, since not many
devices currently supported on those SoCs use address decoding
windows. The only one being the BootROM window, used to bring up
secondary CPUs.
However, this BootROM window needed for SMP brings an important
requirement: the mvebu-mbus driver must be initialized at the
->early_init() time, otherwise the BootROM window cannot be setup
early enough to be ready before the secondary CPUs are started.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'arch/arm/mach-mvebu')
-rw-r--r-- | arch/arm/mach-mvebu/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/addr-map.c | 137 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada-370-xp.c | 18 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada-370-xp.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/platsmp.c | 2 |
6 files changed, 28 insertions, 138 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 440b13ef1fed..c3715a536d87 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig | |||
@@ -13,6 +13,7 @@ config ARCH_MVEBU | |||
13 | select MVEBU_CLK_CORE | 13 | select MVEBU_CLK_CORE |
14 | select MVEBU_CLK_CPU | 14 | select MVEBU_CLK_CPU |
15 | select MVEBU_CLK_GATING | 15 | select MVEBU_CLK_GATING |
16 | select MVEBU_MBUS | ||
16 | 17 | ||
17 | if ARCH_MVEBU | 18 | if ARCH_MVEBU |
18 | 19 | ||
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index da93bcbc74c1..ba769e082ad4 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile | |||
@@ -5,6 +5,6 @@ AFLAGS_coherency_ll.o := -Wa,-march=armv7-a | |||
5 | 5 | ||
6 | obj-y += system-controller.o | 6 | obj-y += system-controller.o |
7 | obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o | 7 | obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o |
8 | obj-$(CONFIG_ARCH_MVEBU) += addr-map.o coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o | 8 | obj-$(CONFIG_ARCH_MVEBU) += coherency.o coherency_ll.o pmsu.o irq-armada-370-xp.o |
9 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 9 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
10 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 10 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
diff --git a/arch/arm/mach-mvebu/addr-map.c b/arch/arm/mach-mvebu/addr-map.c deleted file mode 100644 index ab9b3bd4fef5..000000000000 --- a/arch/arm/mach-mvebu/addr-map.c +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | * Address map functions for Marvell 370 / XP SoCs | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/mbus.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <plat/addr-map.h> | ||
20 | |||
21 | /* | ||
22 | * Generic Address Decode Windows bit settings | ||
23 | */ | ||
24 | #define ARMADA_XP_TARGET_DEV_BUS 1 | ||
25 | #define ARMADA_XP_ATTR_DEV_BOOTROM 0x1D | ||
26 | #define ARMADA_XP_TARGET_ETH1 3 | ||
27 | #define ARMADA_XP_TARGET_PCIE_0_2 4 | ||
28 | #define ARMADA_XP_TARGET_ETH0 7 | ||
29 | #define ARMADA_XP_TARGET_PCIE_1_3 8 | ||
30 | |||
31 | #define ARMADA_370_TARGET_DEV_BUS 1 | ||
32 | #define ARMADA_370_ATTR_DEV_BOOTROM 0x1D | ||
33 | #define ARMADA_370_TARGET_PCIE_0 4 | ||
34 | #define ARMADA_370_TARGET_PCIE_1 8 | ||
35 | |||
36 | #define ARMADA_WINDOW_8_PLUS_OFFSET 0x90 | ||
37 | #define ARMADA_SDRAM_ADDR_DECODING_OFFSET 0x180 | ||
38 | |||
39 | static const struct __initdata orion_addr_map_info | ||
40 | armada_xp_addr_map_info[] = { | ||
41 | /* | ||
42 | * Window for the BootROM, needed for SMP on Armada XP | ||
43 | */ | ||
44 | { 0, 0xfff00000, SZ_1M, ARMADA_XP_TARGET_DEV_BUS, | ||
45 | ARMADA_XP_ATTR_DEV_BOOTROM, -1 }, | ||
46 | /* End marker */ | ||
47 | { -1, 0, 0, 0, 0, 0 }, | ||
48 | }; | ||
49 | |||
50 | static const struct __initdata orion_addr_map_info | ||
51 | armada_370_addr_map_info[] = { | ||
52 | /* End marker */ | ||
53 | { -1, 0, 0, 0, 0, 0 }, | ||
54 | }; | ||
55 | |||
56 | static struct of_device_id of_addr_decoding_controller_table[] = { | ||
57 | { .compatible = "marvell,armada-addr-decoding-controller" }, | ||
58 | { /* end of list */ }, | ||
59 | }; | ||
60 | |||
61 | static void __iomem * | ||
62 | armada_cfg_base(const struct orion_addr_map_cfg *cfg, int win) | ||
63 | { | ||
64 | unsigned int offset; | ||
65 | |||
66 | /* The register layout is a bit annoying and the below code | ||
67 | * tries to cope with it. | ||
68 | * - At offset 0x0, there are the registers for the first 8 | ||
69 | * windows, with 4 registers of 32 bits per window (ctrl, | ||
70 | * base, remap low, remap high) | ||
71 | * - Then at offset 0x80, there is a hole of 0x10 bytes for | ||
72 | * the internal registers base address and internal units | ||
73 | * sync barrier register. | ||
74 | * - Then at offset 0x90, there the registers for 12 | ||
75 | * windows, with only 2 registers of 32 bits per window | ||
76 | * (ctrl, base). | ||
77 | */ | ||
78 | if (win < 8) | ||
79 | offset = (win << 4); | ||
80 | else | ||
81 | offset = ARMADA_WINDOW_8_PLUS_OFFSET + ((win - 8) << 3); | ||
82 | |||
83 | return cfg->bridge_virt_base + offset; | ||
84 | } | ||
85 | |||
86 | static struct __initdata orion_addr_map_cfg addr_map_cfg = { | ||
87 | .num_wins = 20, | ||
88 | .remappable_wins = 8, | ||
89 | .win_cfg_base = armada_cfg_base, | ||
90 | }; | ||
91 | |||
92 | static int __init armada_setup_cpu_mbus(void) | ||
93 | { | ||
94 | struct device_node *np; | ||
95 | void __iomem *mbus_unit_addr_decoding_base; | ||
96 | void __iomem *sdram_addr_decoding_base; | ||
97 | |||
98 | np = of_find_matching_node(NULL, of_addr_decoding_controller_table); | ||
99 | if (!np) | ||
100 | return -ENODEV; | ||
101 | |||
102 | mbus_unit_addr_decoding_base = of_iomap(np, 0); | ||
103 | BUG_ON(!mbus_unit_addr_decoding_base); | ||
104 | |||
105 | sdram_addr_decoding_base = | ||
106 | mbus_unit_addr_decoding_base + | ||
107 | ARMADA_SDRAM_ADDR_DECODING_OFFSET; | ||
108 | |||
109 | addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base; | ||
110 | |||
111 | if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric")) | ||
112 | addr_map_cfg.hw_io_coherency = 1; | ||
113 | |||
114 | /* | ||
115 | * Disable, clear and configure windows. | ||
116 | */ | ||
117 | if (of_machine_is_compatible("marvell,armadaxp")) | ||
118 | orion_config_wins(&addr_map_cfg, armada_xp_addr_map_info); | ||
119 | else if (of_machine_is_compatible("marvell,armada370")) | ||
120 | orion_config_wins(&addr_map_cfg, armada_370_addr_map_info); | ||
121 | else { | ||
122 | pr_err("Unsupported SoC\n"); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Setup MBUS dram target info. | ||
128 | */ | ||
129 | orion_setup_cpu_mbus_target(&addr_map_cfg, | ||
130 | sdram_addr_decoding_base); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | /* Using a early_initcall is needed so that this initialization gets | ||
135 | * done before the SMP initialization, which requires the BootROM to | ||
136 | * be remapped. */ | ||
137 | early_initcall(armada_setup_cpu_mbus); | ||
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c index a5ea616d6d12..12d3655830d1 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.c +++ b/arch/arm/mach-mvebu/armada-370-xp.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/time-armada-370-xp.h> | 19 | #include <linux/time-armada-370-xp.h> |
20 | #include <linux/clk/mvebu.h> | 20 | #include <linux/clk/mvebu.h> |
21 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
22 | #include <linux/mbus.h> | ||
22 | #include <asm/mach/arch.h> | 23 | #include <asm/mach/arch.h> |
23 | #include <asm/mach/map.h> | 24 | #include <asm/mach/map.h> |
24 | #include <asm/mach/time.h> | 25 | #include <asm/mach/time.h> |
@@ -48,12 +49,29 @@ void __init armada_370_xp_timer_and_clk_init(void) | |||
48 | 49 | ||
49 | void __init armada_370_xp_init_early(void) | 50 | void __init armada_370_xp_init_early(void) |
50 | { | 51 | { |
52 | char *mbus_soc_name; | ||
53 | |||
51 | /* | 54 | /* |
52 | * Some Armada 370/XP devices allocate their coherent buffers | 55 | * Some Armada 370/XP devices allocate their coherent buffers |
53 | * from atomic context. Increase size of atomic coherent pool | 56 | * from atomic context. Increase size of atomic coherent pool |
54 | * to make sure such the allocations won't fail. | 57 | * to make sure such the allocations won't fail. |
55 | */ | 58 | */ |
56 | init_dma_coherent_pool_size(SZ_1M); | 59 | init_dma_coherent_pool_size(SZ_1M); |
60 | |||
61 | /* | ||
62 | * This initialization will be replaced by a DT-based | ||
63 | * initialization once the mvebu-mbus driver gains DT support. | ||
64 | */ | ||
65 | if (of_machine_is_compatible("marvell,armada370")) | ||
66 | mbus_soc_name = "marvell,armada370-mbus"; | ||
67 | else | ||
68 | mbus_soc_name = "marvell,armadaxp-mbus"; | ||
69 | |||
70 | mvebu_mbus_init(mbus_soc_name, | ||
71 | ARMADA_370_XP_MBUS_WINS_BASE, | ||
72 | ARMADA_370_XP_MBUS_WINS_SIZE, | ||
73 | ARMADA_370_XP_SDRAM_WINS_BASE, | ||
74 | ARMADA_370_XP_SDRAM_WINS_SIZE); | ||
57 | } | 75 | } |
58 | 76 | ||
59 | static void __init armada_370_xp_dt_init(void) | 77 | static void __init armada_370_xp_dt_init(void) |
diff --git a/arch/arm/mach-mvebu/armada-370-xp.h b/arch/arm/mach-mvebu/armada-370-xp.h index c6a7d74fddfe..978308717284 100644 --- a/arch/arm/mach-mvebu/armada-370-xp.h +++ b/arch/arm/mach-mvebu/armada-370-xp.h | |||
@@ -19,6 +19,12 @@ | |||
19 | #define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000) | 19 | #define ARMADA_370_XP_REGS_VIRT_BASE IOMEM(0xfeb00000) |
20 | #define ARMADA_370_XP_REGS_SIZE SZ_1M | 20 | #define ARMADA_370_XP_REGS_SIZE SZ_1M |
21 | 21 | ||
22 | /* These defines can go away once mvebu-mbus has a DT binding */ | ||
23 | #define ARMADA_370_XP_MBUS_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20000) | ||
24 | #define ARMADA_370_XP_MBUS_WINS_SIZE 0x100 | ||
25 | #define ARMADA_370_XP_SDRAM_WINS_BASE (ARMADA_370_XP_REGS_PHYS_BASE + 0x20180) | ||
26 | #define ARMADA_370_XP_SDRAM_WINS_SIZE 0x20 | ||
27 | |||
22 | #ifdef CONFIG_SMP | 28 | #ifdef CONFIG_SMP |
23 | #include <linux/cpumask.h> | 29 | #include <linux/cpumask.h> |
24 | 30 | ||
diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index fe16aaf7c19c..875ea748391c 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/mbus.h> | ||
24 | #include <asm/cacheflush.h> | 25 | #include <asm/cacheflush.h> |
25 | #include <asm/smp_plat.h> | 26 | #include <asm/smp_plat.h> |
26 | #include "common.h" | 27 | #include "common.h" |
@@ -109,6 +110,7 @@ void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) | |||
109 | set_secondary_cpus_clock(); | 110 | set_secondary_cpus_clock(); |
110 | flush_cache_all(); | 111 | flush_cache_all(); |
111 | set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); | 112 | set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); |
113 | mvebu_mbus_add_window("bootrom", 0xfff00000, SZ_1M); | ||
112 | } | 114 | } |
113 | 115 | ||
114 | struct smp_operations armada_xp_smp_ops __initdata = { | 116 | struct smp_operations armada_xp_smp_ops __initdata = { |