aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-kirkwood/board-dt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-kirkwood/board-dt.c')
-rw-r--r--arch/arm/mach-kirkwood/board-dt.c310
1 files changed, 163 insertions, 147 deletions
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c
index 6e122ed3282..ff18ff20f71 100644
--- a/arch/arm/mach-kirkwood/board-dt.c
+++ b/arch/arm/mach-kirkwood/board-dt.c
@@ -10,197 +10,213 @@
* warranty of any kind, whether express or implied.
*/
+#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_net.h>
#include <linux/of_platform.h>
-#include <linux/clk-provider.h>
-#include <linux/kexec.h>
+#include <linux/dma-mapping.h>
+#include <linux/irqchip.h>
+#include <asm/hardware/cache-feroceon-l2.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <mach/bridge-regs.h>
-#include <linux/platform_data/usb-ehci-orion.h>
-#include <plat/irq.h>
#include <plat/common.h>
-#include "common.h"
-
-/*
- * There are still devices that doesn't know about DT yet. Get clock
- * gates here and add a clock lookup alias, so that old platform
- * devices still work.
-*/
+#include <plat/pcie.h>
+#include "pm.h"
+
+static struct map_desc kirkwood_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long) KIRKWOOD_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
+ .length = KIRKWOOD_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
-static void __init kirkwood_legacy_clk_init(void)
+static void __init kirkwood_map_io(void)
{
+ iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc));
+}
- struct device_node *np = of_find_compatible_node(
- NULL, NULL, "marvell,kirkwood-gating-clock");
- struct of_phandle_args clkspec;
- struct clk *clk;
-
- clkspec.np = np;
- clkspec.args_count = 1;
+static struct resource kirkwood_cpufreq_resources[] = {
+ [0] = {
+ .start = CPU_CONTROL_PHYS,
+ .end = CPU_CONTROL_PHYS + 3,
+ .flags = IORESOURCE_MEM,
+ },
+};
- clkspec.args[0] = CGC_BIT_PEX0;
- orion_clkdev_add("0", "pcie",
- of_clk_get_from_provider(&clkspec));
+static struct platform_device kirkwood_cpufreq_device = {
+ .name = "kirkwood-cpufreq",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources),
+ .resource = kirkwood_cpufreq_resources,
+};
- clkspec.args[0] = CGC_BIT_PEX1;
- orion_clkdev_add("1", "pcie",
- of_clk_get_from_provider(&clkspec));
+static void __init kirkwood_cpufreq_init(void)
+{
+ platform_device_register(&kirkwood_cpufreq_device);
+}
- clkspec.args[0] = CGC_BIT_SDIO;
- orion_clkdev_add(NULL, "mvsdio",
- of_clk_get_from_provider(&clkspec));
+static struct resource kirkwood_cpuidle_resource[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ .start = DDR_OPERATION_BASE,
+ .end = DDR_OPERATION_BASE + 3,
+ },
+};
- /*
- * The ethernet interfaces forget the MAC address assigned by
- * u-boot if the clocks are turned off. Until proper DT support
- * is available we always enable them for now.
- */
- clkspec.args[0] = CGC_BIT_GE0;
- clk = of_clk_get_from_provider(&clkspec);
- orion_clkdev_add(NULL, "mv643xx_eth_port.0", clk);
- clk_prepare_enable(clk);
-
- clkspec.args[0] = CGC_BIT_GE1;
- clk = of_clk_get_from_provider(&clkspec);
- orion_clkdev_add(NULL, "mv643xx_eth_port.1", clk);
- clk_prepare_enable(clk);
-}
+static struct platform_device kirkwood_cpuidle = {
+ .name = "kirkwood_cpuidle",
+ .id = -1,
+ .resource = kirkwood_cpuidle_resource,
+ .num_resources = 1,
+};
-static void __init kirkwood_of_clk_init(void)
+static void __init kirkwood_cpuidle_init(void)
{
- of_clk_init(NULL);
- kirkwood_legacy_clk_init();
+ platform_device_register(&kirkwood_cpuidle);
}
-static void __init kirkwood_dt_init(void)
+/* Temporary here since mach-mvebu has a function we can use */
+static void kirkwood_restart(enum reboot_mode mode, const char *cmd)
{
- pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk);
-
/*
- * Disable propagation of mbus errors to the CPU local bus,
- * as this causes mbus errors (which can occur for example
- * for PCI aborts) to throw CPU aborts, which we're not set
- * up to deal with.
+ * Enable soft reset to assert RSTOUTn.
*/
- writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
-
- kirkwood_setup_wins();
-
- kirkwood_l2_init();
-
- kirkwood_cpufreq_init();
-
- /* Setup root of clk tree */
- kirkwood_of_clk_init();
-
- kirkwood_cpuidle_init();
-
-#ifdef CONFIG_KEXEC
- kexec_reinit = kirkwood_enable_pcie;
-#endif
-
- if (of_machine_is_compatible("globalscale,dreamplug"))
- dreamplug_init();
-
- if (of_machine_is_compatible("globalscale,guruplug"))
- guruplug_dt_init();
-
- if (of_machine_is_compatible("globalscale,sheevaplug"))
- sheevaplug_dt_init();
-
- if (of_machine_is_compatible("dlink,dns-kirkwood"))
- dnskw_init();
-
- if (of_machine_is_compatible("iom,iconnect"))
- iconnect_init();
+ writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK);
- if (of_machine_is_compatible("raidsonic,ib-nas62x0"))
- ib62x0_init();
-
- if (of_machine_is_compatible("qnap,ts219"))
- qnap_dt_ts219_init();
-
- if (of_machine_is_compatible("seagate,dockstar"))
- dockstar_dt_init();
+ /*
+ * Assert soft reset.
+ */
+ writel(SOFT_RESET, SYSTEM_SOFT_RESET);
- if (of_machine_is_compatible("seagate,goflexnet"))
- goflexnet_init();
+ while (1)
+ ;
+}
- if (of_machine_is_compatible("buffalo,lsxl"))
- lsxl_init();
+#define MV643XX_ETH_MAC_ADDR_LOW 0x0414
+#define MV643XX_ETH_MAC_ADDR_HIGH 0x0418
- if (of_machine_is_compatible("iom,ix2-200"))
- iomega_ix2_200_init();
+static void __init kirkwood_dt_eth_fixup(void)
+{
+ struct device_node *np;
- if (of_machine_is_compatible("keymile,km_kirkwood"))
- km_kirkwood_init();
+ /*
+ * The ethernet interfaces forget the MAC address assigned by u-boot
+ * if the clocks are turned off. Usually, u-boot on kirkwood boards
+ * has no DT support to properly set local-mac-address property.
+ * As a workaround, we get the MAC address from mv643xx_eth registers
+ * and update the port device node if no valid MAC address is set.
+ */
+ for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") {
+ struct device_node *pnp = of_get_parent(np);
+ struct clk *clk;
+ struct property *pmac;
+ void __iomem *io;
+ u8 *macaddr;
+ u32 reg;
+
+ if (!pnp)
+ continue;
+
+ /* skip disabled nodes or nodes with valid MAC address*/
+ if (!of_device_is_available(pnp) || of_get_mac_address(np))
+ goto eth_fixup_skip;
+
+ clk = of_clk_get(pnp, 0);
+ if (IS_ERR(clk))
+ goto eth_fixup_skip;
+
+ io = of_iomap(pnp, 0);
+ if (!io)
+ goto eth_fixup_no_map;
+
+ /* ensure port clock is not gated to not hang CPU */
+ clk_prepare_enable(clk);
+
+ /* store MAC address register contents in local-mac-address */
+ pr_err(FW_INFO "%s: local-mac-address is not set\n",
+ np->full_name);
+
+ pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL);
+ if (!pmac)
+ goto eth_fixup_no_mem;
+
+ pmac->value = pmac + 1;
+ pmac->length = 6;
+ pmac->name = kstrdup("local-mac-address", GFP_KERNEL);
+ if (!pmac->name) {
+ kfree(pmac);
+ goto eth_fixup_no_mem;
+ }
+
+ macaddr = pmac->value;
+ reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH);
+ macaddr[0] = (reg >> 24) & 0xff;
+ macaddr[1] = (reg >> 16) & 0xff;
+ macaddr[2] = (reg >> 8) & 0xff;
+ macaddr[3] = reg & 0xff;
+
+ reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW);
+ macaddr[4] = (reg >> 8) & 0xff;
+ macaddr[5] = reg & 0xff;
+
+ of_update_property(np, pmac);
+
+eth_fixup_no_mem:
+ iounmap(io);
+ clk_disable_unprepare(clk);
+eth_fixup_no_map:
+ clk_put(clk);
+eth_fixup_skip:
+ of_node_put(pnp);
+ }
+}
- if (of_machine_is_compatible("lacie,cloudbox") ||
- of_machine_is_compatible("lacie,inetspace_v2") ||
- of_machine_is_compatible("lacie,netspace_lite_v2") ||
- of_machine_is_compatible("lacie,netspace_max_v2") ||
- of_machine_is_compatible("lacie,netspace_mini_v2") ||
- of_machine_is_compatible("lacie,netspace_v2"))
- ns2_init();
+/*
+ * Disable propagation of mbus errors to the CPU local bus, as this
+ * causes mbus errors (which can occur for example for PCI aborts) to
+ * throw CPU aborts, which we're not set up to deal with.
+ */
+static void __init kirkwood_disable_mbus_error_propagation(void)
+{
+ void __iomem *cpu_config;
- if (of_machine_is_compatible("marvell,db-88f6281-bp") ||
- of_machine_is_compatible("marvell,db-88f6282-bp"))
- db88f628x_init();
+ cpu_config = ioremap(CPU_CONFIG_PHYS, 4);
+ writel(readl(cpu_config) & ~CPU_CONFIG_ERROR_PROP, cpu_config);
+ iounmap(cpu_config);
+}
- if (of_machine_is_compatible("mpl,cec4"))
- mplcec4_init();
+static void __init kirkwood_dt_init(void)
+{
+ kirkwood_disable_mbus_error_propagation();
- if (of_machine_is_compatible("netgear,readynas-duo-v2"))
- netgear_readynas_init();
+ BUG_ON(mvebu_mbus_dt_init(false));
- if (of_machine_is_compatible("plathome,openblocks-a6"))
- openblocks_a6_init();
+#ifdef CONFIG_CACHE_FEROCEON_L2
+ feroceon_of_init();
+#endif
+ kirkwood_cpufreq_init();
+ kirkwood_cpuidle_init();
- if (of_machine_is_compatible("usi,topkick"))
- usi_topkick_init();
+ kirkwood_pm_init();
+ kirkwood_dt_eth_fixup();
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
static const char * const kirkwood_dt_board_compat[] = {
- "globalscale,dreamplug",
- "globalscale,guruplug",
- "globalscale,sheevaplug",
- "dlink,dns-320",
- "dlink,dns-325",
- "iom,iconnect",
- "raidsonic,ib-nas62x0",
- "qnap,ts219",
- "seagate,dockstar",
- "seagate,goflexnet",
- "buffalo,lsxl",
- "iom,ix2-200",
- "keymile,km_kirkwood",
- "lacie,cloudbox",
- "lacie,inetspace_v2",
- "lacie,netspace_lite_v2",
- "lacie,netspace_max_v2",
- "lacie,netspace_mini_v2",
- "lacie,netspace_v2",
- "marvell,db-88f6281-bp",
- "marvell,db-88f6282-bp",
- "mpl,cec4",
- "netgear,readynas-duo-v2",
- "plathome,openblocks-a6",
- "usi,topkick",
- "zyxel,nsa310",
+ "marvell,kirkwood",
NULL
};
DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)")
/* Maintainer: Jason Cooper <jason@lakedaemon.net> */
.map_io = kirkwood_map_io,
- .init_early = kirkwood_init_early,
- .init_irq = orion_dt_init_irq,
- .init_time = kirkwood_timer_init,
.init_machine = kirkwood_dt_init,
.restart = kirkwood_restart,
.dt_compat = kirkwood_dt_board_compat,