ARM: mvebu: Add ARCH_MULTI_V7 to SoCs
[deliverable/linux.git] / arch / arm / mach-kirkwood / board-dt.c
CommitLineData
3d468b6d
JC
1/*
2 * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net>
3 *
4 * arch/arm/mach-kirkwood/board-dt.c
5 *
6fa6b878 6 * Flattened Device Tree board initialization
3d468b6d
JC
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
e3e8e588 13#include <linux/clk.h>
3d468b6d
JC
14#include <linux/kernel.h>
15#include <linux/init.h>
3d468b6d 16#include <linux/of.h>
ebd7d3ab
SH
17#include <linux/of_address.h>
18#include <linux/of_net.h>
3d468b6d 19#include <linux/of_platform.h>
2326f043
SH
20#include <linux/dma-mapping.h>
21#include <linux/irqchip.h>
a7ac56de 22#include <linux/kexec.h>
3d468b6d 23#include <asm/mach/arch.h>
dab7dfb6 24#include <asm/mach/map.h>
2b45e05f 25#include <mach/bridge-regs.h>
1611f872 26#include <plat/common.h>
dab7dfb6
AL
27#include <plat/cache-feroceon-l2.h>
28#include <plat/pcie.h>
c3b6144a 29#include "pm.h"
3d468b6d 30
dab7dfb6
AL
31static struct map_desc kirkwood_io_desc[] __initdata = {
32 {
33 .virtual = (unsigned long) KIRKWOOD_REGS_VIRT_BASE,
34 .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
35 .length = KIRKWOOD_REGS_SIZE,
36 .type = MT_DEVICE,
37 },
38};
39
40static void __init kirkwood_map_io(void)
41{
42 iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
43}
44
45static void __init kirkwood_l2_init(void)
46{
47#ifdef CONFIG_CACHE_FEROCEON_L2
48#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH
49 writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG);
50 feroceon_l2_init(1);
51#else
52 writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG);
53 feroceon_l2_init(0);
54#endif
55#endif
56}
57
58static struct resource kirkwood_cpufreq_resources[] = {
59 [0] = {
60 .start = CPU_CONTROL_PHYS,
61 .end = CPU_CONTROL_PHYS + 3,
62 .flags = IORESOURCE_MEM,
63 },
64};
65
66static struct platform_device kirkwood_cpufreq_device = {
67 .name = "kirkwood-cpufreq",
68 .id = -1,
69 .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources),
70 .resource = kirkwood_cpufreq_resources,
71};
72
73static void __init kirkwood_cpufreq_init(void)
74{
75 platform_device_register(&kirkwood_cpufreq_device);
76}
77
78static struct resource kirkwood_cpuidle_resource[] = {
79 {
80 .flags = IORESOURCE_MEM,
81 .start = DDR_OPERATION_BASE,
82 .end = DDR_OPERATION_BASE + 3,
83 },
84};
85
86static struct platform_device kirkwood_cpuidle = {
87 .name = "kirkwood_cpuidle",
88 .id = -1,
89 .resource = kirkwood_cpuidle_resource,
90 .num_resources = 1,
91};
92
93static void __init kirkwood_cpuidle_init(void)
94{
95 platform_device_register(&kirkwood_cpuidle);
96}
97
98/* Temporary here since mach-mvebu has a function we can use */
99static void kirkwood_restart(enum reboot_mode mode, const char *cmd)
100{
101 /*
102 * Enable soft reset to assert RSTOUTn.
103 */
104 writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
105
106 /*
107 * Assert soft reset.
108 */
109 writel(SOFT_RESET, SYSTEM_SOFT_RESET);
110
111 while (1)
112 ;
113}
114
ebd7d3ab
SH
115#define MV643XX_ETH_MAC_ADDR_LOW 0x0414
116#define MV643XX_ETH_MAC_ADDR_HIGH 0x0418
117
118static void __init kirkwood_dt_eth_fixup(void)
119{
120 struct device_node *np;
121
122 /*
123 * The ethernet interfaces forget the MAC address assigned by u-boot
124 * if the clocks are turned off. Usually, u-boot on kirkwood boards
125 * has no DT support to properly set local-mac-address property.
126 * As a workaround, we get the MAC address from mv643xx_eth registers
127 * and update the port device node if no valid MAC address is set.
128 */
129 for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") {
130 struct device_node *pnp = of_get_parent(np);
131 struct clk *clk;
132 struct property *pmac;
133 void __iomem *io;
134 u8 *macaddr;
135 u32 reg;
136
137 if (!pnp)
138 continue;
139
140 /* skip disabled nodes or nodes with valid MAC address*/
141 if (!of_device_is_available(pnp) || of_get_mac_address(np))
142 goto eth_fixup_skip;
143
144 clk = of_clk_get(pnp, 0);
145 if (IS_ERR(clk))
146 goto eth_fixup_skip;
147
148 io = of_iomap(pnp, 0);
149 if (!io)
150 goto eth_fixup_no_map;
151
152 /* ensure port clock is not gated to not hang CPU */
153 clk_prepare_enable(clk);
154
155 /* store MAC address register contents in local-mac-address */
156 pr_err(FW_INFO "%s: local-mac-address is not set\n",
157 np->full_name);
158
159 pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL);
160 if (!pmac)
161 goto eth_fixup_no_mem;
162
163 pmac->value = pmac + 1;
164 pmac->length = 6;
165 pmac->name = kstrdup("local-mac-address", GFP_KERNEL);
166 if (!pmac->name) {
167 kfree(pmac);
168 goto eth_fixup_no_mem;
169 }
170
171 macaddr = pmac->value;
172 reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH);
173 macaddr[0] = (reg >> 24) & 0xff;
174 macaddr[1] = (reg >> 16) & 0xff;
175 macaddr[2] = (reg >> 8) & 0xff;
176 macaddr[3] = reg & 0xff;
177
178 reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW);
179 macaddr[4] = (reg >> 8) & 0xff;
180 macaddr[5] = reg & 0xff;
181
182 of_update_property(np, pmac);
183
184eth_fixup_no_mem:
185 iounmap(io);
186 clk_disable_unprepare(clk);
187eth_fixup_no_map:
188 clk_put(clk);
189eth_fixup_skip:
190 of_node_put(pnp);
191 }
192}
193
7f28fd6e
AL
194/*
195 * Disable propagation of mbus errors to the CPU local bus, as this
196 * causes mbus errors (which can occur for example for PCI aborts) to
197 * throw CPU aborts, which we're not set up to deal with.
198 */
199static void __init kirkwood_disable_mbus_error_propagation(void)
200{
201 void __iomem *cpu_config;
202
203 cpu_config = ioremap(CPU_CONFIG_PHYS, 4);
204 writel(readl(cpu_config) & ~CPU_CONFIG_ERROR_PROP, cpu_config);
205 iounmap(cpu_config);
206}
207
3d468b6d
JC
208static void __init kirkwood_dt_init(void)
209{
7f28fd6e 210 kirkwood_disable_mbus_error_propagation();
2b45e05f 211
0789d0b2 212 BUG_ON(mvebu_mbus_dt_init());
2b45e05f 213
2b45e05f 214 kirkwood_l2_init();
2b45e05f 215
0e2ee0c0 216 kirkwood_cpufreq_init();
ebd7d3ab 217 kirkwood_cpuidle_init();
2b45e05f 218
e1cb367d 219 kirkwood_pm_init();
ebd7d3ab 220 kirkwood_dt_eth_fixup();
9cfc94eb 221
2b45e05f
JC
222#ifdef CONFIG_KEXEC
223 kexec_reinit = kirkwood_enable_pcie;
224#endif
3d468b6d 225
3207792e 226 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
3d468b6d
JC
227}
228
98adf932 229static const char * const kirkwood_dt_board_compat[] = {
a977e18e 230 "marvell,kirkwood",
3d468b6d
JC
231 NULL
232};
233
234DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
235 /* Maintainer: Jason Cooper <jason@lakedaemon.net> */
236 .map_io = kirkwood_map_io,
3d468b6d
JC
237 .init_machine = kirkwood_dt_init,
238 .restart = kirkwood_restart,
239 .dt_compat = kirkwood_dt_board_compat,
240MACHINE_END
This page took 0.094959 seconds and 5 git commands to generate.