diff options
author | Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | 2012-09-11 08:27:29 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2012-09-21 14:05:18 -0400 |
commit | 74dd80a7b9fe5e8438458bd17cc9352dff8fd6b7 (patch) | |
tree | 677c9fbcdd934c5469ea6f7315ede8543e9cdde6 | |
parent | 87d136415c78c02680dc474cb4093ba7911b07a4 (diff) |
arm: mvebu: add basic address decoding support to Armada 370/XP
This commit adds basic support for address decoding configuration for
the Armada 370 and Armada XP SoCs, re-using the infrastructure
provided in plat-orion.
For now, only a BootROM window is configured on Armada XP, which is
needed to get the non-boot CPUs started and is therefore a requirement
for SMP support.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r-- | arch/arm/mach-mvebu/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/addr-map.c | 134 |
2 files changed, 135 insertions, 1 deletions
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index e61d2b8fdf50..21435581b92b 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | obj-y += system-controller.o | 1 | obj-y += system-controller.o |
2 | obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o | 2 | obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o addr-map.o |
diff --git a/arch/arm/mach-mvebu/addr-map.c b/arch/arm/mach-mvebu/addr-map.c new file mode 100644 index 000000000000..fe454a4430be --- /dev/null +++ b/arch/arm/mach-mvebu/addr-map.c | |||
@@ -0,0 +1,134 @@ | |||
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 << 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 | /* | ||
112 | * Disable, clear and configure windows. | ||
113 | */ | ||
114 | if (of_machine_is_compatible("marvell,armadaxp")) | ||
115 | orion_config_wins(&addr_map_cfg, armada_xp_addr_map_info); | ||
116 | else if (of_machine_is_compatible("marvell,armada370")) | ||
117 | orion_config_wins(&addr_map_cfg, armada_370_addr_map_info); | ||
118 | else { | ||
119 | pr_err("Unsupported SoC\n"); | ||
120 | return -EINVAL; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Setup MBUS dram target info. | ||
125 | */ | ||
126 | orion_setup_cpu_mbus_target(&addr_map_cfg, | ||
127 | sdram_addr_decoding_base); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | /* Using a early_initcall is needed so that this initialization gets | ||
132 | * done before the SMP initialization, which requires the BootROM to | ||
133 | * be remapped. */ | ||
134 | early_initcall(armada_setup_cpu_mbus); | ||