summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mvebu
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-23 16:31:31 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-23 16:31:31 -0700
commitf01b9b73f57f4f92d39bba0d9aa4a38f318212df (patch)
treeb815a4477af34f7f6c61dff0c04db6cb975cdd55 /arch/arm/mach-mvebu
parentfde75430278130505cac21997cd9f90b7bb2670a (diff)
parent66314223aa5e862c9d1d068cb7186b4fd58ebeaa (diff)
downloadblackbird-op-linux-f01b9b73f57f4f92d39bba0d9aa4a38f318212df.tar.gz
blackbird-op-linux-f01b9b73f57f4f92d39bba0d9aa4a38f318212df.zip
Merge tag 'newsoc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull support for three new arm SoC types from Arnd Bergmann: - The mvebu platform includes Marvell's Armada XP and Armada 370 chips, made by the mvebu business unit inside of Marvell. Since the same group also made the older but similar platforms we call "orion5x", "kirkwood", "mv78xx0" and "dove", we plan to move all of them into the mach-mvebu directory in the future. - socfpga is Altera's platform based on Cortex-A9 cores and a lot of FPGA space. This is similar to the Xilinx zynq platform we already support. The code is particularly clean, which is helped by the fact that the hardware doesn't do much besides the parts that are expected to get added in the FPGA. - The OMAP subarchitecture gains support for the latest generation, the OMAP5 based on the new Cortex-A15 core. Support is rather rudimentary for now, but will be extended in the future. * tag 'newsoc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (25 commits) ARM: socfpga: initial support for Altera's SOCFPGA platform arm: mvebu: generate DTBs for supported SoCs ARM: mvebu: MPIC: read number of interrupts from control register arm: mach-mvebu: add entry to MAINTAINERS arm: mach-mvebu: add compilation/configuration change arm: mach-mvebu: add defconfig arm: mach-mvebu: add documentation for new device tree bindings arm: mach-mvebu: add support for Armada 370 and Armada XP with DT arm: mach-mvebu: add source files arm: mach-mvebu: add header clocksource: time-armada-370-xp: Marvell Armada 370/XP SoC timer driver ARM: Kconfig update to support additional GPIOs in OMAP5 ARM: OMAP5: Add the build support arm/dts: OMAP5: Add omap5 dts files ARM: OMAP5: board-generic: Add device tree support ARM: omap2+: board-generic: clean up the irq data from board file ARM: OMAP5: Add SMP support ARM: OMAP5: Add the WakeupGen IP updates ARM: OMAP5: l3: Add l3 error handler support for omap5 ARM: OMAP5: gpmc: Update gpmc_init() ... Conflicts: Documentation/devicetree/bindings/arm/omap/omap.txt arch/arm/mach-omap2/Makefile drivers/clocksource/Kconfig drivers/clocksource/Makefile
Diffstat (limited to 'arch/arm/mach-mvebu')
-rw-r--r--arch/arm/mach-mvebu/Kconfig16
-rw-r--r--arch/arm/mach-mvebu/Makefile2
-rw-r--r--arch/arm/mach-mvebu/Makefile.boot3
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.c63
-rw-r--r--arch/arm/mach-mvebu/common.h23
-rw-r--r--arch/arm/mach-mvebu/include/mach/armada-370-xp.h22
-rw-r--r--arch/arm/mach-mvebu/include/mach/debug-macro.S24
-rw-r--r--arch/arm/mach-mvebu/include/mach/timex.h13
-rw-r--r--arch/arm/mach-mvebu/include/mach/uncompress.h43
-rw-r--r--arch/arm/mach-mvebu/irq-armada-370-xp.c133
-rw-r--r--arch/arm/mach-mvebu/system-controller.c105
11 files changed, 447 insertions, 0 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
new file mode 100644
index 000000000000..caa2c5e734fe
--- /dev/null
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -0,0 +1,16 @@
+if ARCH_MVEBU
+
+menu "Marvell SOC with device tree"
+
+config MACH_ARMADA_370_XP
+ bool "Marvell Armada 370 and Aramada XP boards"
+ select ARMADA_370_XP_TIMER
+ select CPU_V7
+ help
+
+ Say 'Y' here if you want your kernel to support boards based on
+ Marvell Armada 370 or Armada XP with device tree.
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
new file mode 100644
index 000000000000..e61d2b8fdf50
--- /dev/null
+++ b/arch/arm/mach-mvebu/Makefile
@@ -0,0 +1,2 @@
+obj-y += system-controller.o
+obj-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-xp.o irq-armada-370-xp.o
diff --git a/arch/arm/mach-mvebu/Makefile.boot b/arch/arm/mach-mvebu/Makefile.boot
new file mode 100644
index 000000000000..2579a2fc2334
--- /dev/null
+++ b/arch/arm/mach-mvebu/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-y := 0x00008000
+dtb-$(CONFIG_MACH_ARMADA_370_XP) += armada-370-db.dtb
+dtb-$(CONFIG_MACH_ARMADA_370_XP) += armada-xp-db.dtb
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
new file mode 100644
index 000000000000..4ef923b032ec
--- /dev/null
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -0,0 +1,63 @@
+/*
+ * Device Tree support for Armada 370 and XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/time-armada-370-xp.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <mach/armada-370-xp.h>
+#include "common.h"
+
+static struct map_desc armada_370_xp_io_desc[] __initdata = {
+ {
+ .virtual = 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)
+{
+ iotable_init(armada_370_xp_io_desc, ARRAY_SIZE(armada_370_xp_io_desc));
+}
+
+struct sys_timer armada_370_xp_timer = {
+ .init = armada_370_xp_timer_init,
+};
+
+static void __init armada_370_xp_dt_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static const char * const armada_370_xp_dt_board_dt_compat[] = {
+ "marvell,a370-db",
+ "marvell,axp-db",
+ NULL,
+};
+
+DT_MACHINE_START(ARMADA_XP_DT, "Marvell Aramada 370/XP (Device Tree)")
+ .init_machine = armada_370_xp_dt_init,
+ .map_io = armada_370_xp_map_io,
+ .init_irq = armada_370_xp_init_irq,
+ .handle_irq = armada_370_xp_handle_irq,
+ .timer = &armada_370_xp_timer,
+ .restart = mvebu_restart,
+ .dt_compat = armada_370_xp_dt_board_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h
new file mode 100644
index 000000000000..02f89eaa25fe
--- /dev/null
+++ b/arch/arm/mach-mvebu/common.h
@@ -0,0 +1,23 @@
+/*
+ * Core functions for Marvell System On Chip
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARCH_MVEBU_COMMON_H
+#define __ARCH_MVEBU_COMMON_H
+
+void mvebu_restart(char mode, const char *cmd);
+
+void armada_370_xp_init_irq(void);
+void armada_370_xp_handle_irq(struct pt_regs *regs);
+
+#endif
diff --git a/arch/arm/mach-mvebu/include/mach/armada-370-xp.h b/arch/arm/mach-mvebu/include/mach/armada-370-xp.h
new file mode 100644
index 000000000000..25f0ca8d7820
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/armada-370-xp.h
@@ -0,0 +1,22 @@
+/*
+ * Generic definitions for Marvell Armada_370_XP SoCs
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#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 0xfeb00000
+#define ARMADA_370_XP_REGS_SIZE SZ_1M
+
+#endif /* __MACH_ARMADA_370_XP_H */
diff --git a/arch/arm/mach-mvebu/include/mach/debug-macro.S b/arch/arm/mach-mvebu/include/mach/debug-macro.S
new file mode 100644
index 000000000000..22825760c7e1
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/debug-macro.S
@@ -0,0 +1,24 @@
+/*
+ * Early serial output macro for Marvell SoC
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory Clement <gregory.clement@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <mach/armada-370-xp.h>
+
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =ARMADA_370_XP_REGS_PHYS_BASE
+ ldr \rv, =ARMADA_370_XP_REGS_VIRT_BASE
+ orr \rp, \rp, #0x00012000
+ orr \rv, \rv, #0x00012000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-mvebu/include/mach/timex.h b/arch/arm/mach-mvebu/include/mach/timex.h
new file mode 100644
index 000000000000..ab324a3748f2
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/timex.h
@@ -0,0 +1,13 @@
+/*
+ * Marvell Armada SoC time definitions
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-mvebu/include/mach/uncompress.h b/arch/arm/mach-mvebu/include/mach/uncompress.h
new file mode 100644
index 000000000000..d6a100ccf302
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/uncompress.h
@@ -0,0 +1,43 @@
+/*
+ * Marvell Armada SoC kernel uncompression UART routines
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/armada-370-xp.h>
+
+#define UART_THR ((volatile unsigned char *)(ARMADA_370_XP_REGS_PHYS_BASE\
+ + 0x12000))
+#define UART_LSR ((volatile unsigned char *)(ARMADA_370_XP_REGS_PHYS_BASE\
+ + 0x12014))
+
+#define LSR_THRE 0x20
+
+static void putc(const char c)
+{
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ /* Transmit fifo not full? */
+ if (*UART_LSR & LSR_THRE)
+ break;
+ }
+
+ *UART_THR = c;
+}
+
+static void flush(void)
+{
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-mvebu/irq-armada-370-xp.c b/arch/arm/mach-mvebu/irq-armada-370-xp.c
new file mode 100644
index 000000000000..5f5f9394b6b2
--- /dev/null
+++ b/arch/arm/mach-mvebu/irq-armada-370-xp.c
@@ -0,0 +1,133 @@
+/*
+ * Marvell Armada 370 and Armada XP SoC IRQ handling
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Ben Dooks <ben.dooks@codethink.co.uk>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <asm/mach/arch.h>
+#include <asm/exception.h>
+
+/* Interrupt Controller Registers Map */
+#define ARMADA_370_XP_INT_SET_MASK_OFFS (0x48)
+#define ARMADA_370_XP_INT_CLEAR_MASK_OFFS (0x4C)
+
+#define ARMADA_370_XP_INT_CONTROL (0x00)
+#define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30)
+#define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34)
+
+#define ARMADA_370_XP_CPU_INTACK_OFFS (0x44)
+
+static void __iomem *per_cpu_int_base;
+static void __iomem *main_int_base;
+static struct irq_domain *armada_370_xp_mpic_domain;
+
+static void armada_370_xp_irq_mask(struct irq_data *d)
+{
+ writel(irqd_to_hwirq(d),
+ per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS);
+}
+
+static void armada_370_xp_irq_unmask(struct irq_data *d)
+{
+ writel(irqd_to_hwirq(d),
+ per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS);
+}
+
+static struct irq_chip armada_370_xp_irq_chip = {
+ .name = "armada_370_xp_irq",
+ .irq_mask = armada_370_xp_irq_mask,
+ .irq_mask_ack = armada_370_xp_irq_mask,
+ .irq_unmask = armada_370_xp_irq_unmask,
+};
+
+static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
+ unsigned int virq, irq_hw_number_t hw)
+{
+ armada_370_xp_irq_mask(irq_get_irq_data(virq));
+ writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS);
+
+ irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip,
+ handle_level_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
+
+ return 0;
+}
+
+static struct irq_domain_ops armada_370_xp_mpic_irq_ops = {
+ .map = armada_370_xp_mpic_irq_map,
+ .xlate = irq_domain_xlate_onecell,
+};
+
+static int __init armada_370_xp_mpic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ u32 control;
+
+ main_int_base = of_iomap(node, 0);
+ per_cpu_int_base = of_iomap(node, 1);
+
+ BUG_ON(!main_int_base);
+ BUG_ON(!per_cpu_int_base);
+
+ control = readl(main_int_base + ARMADA_370_XP_INT_CONTROL);
+
+ armada_370_xp_mpic_domain =
+ irq_domain_add_linear(node, (control >> 2) & 0x3ff,
+ &armada_370_xp_mpic_irq_ops, NULL);
+
+ if (!armada_370_xp_mpic_domain)
+ panic("Unable to add Armada_370_Xp MPIC irq domain (DT)\n");
+
+ irq_set_default_host(armada_370_xp_mpic_domain);
+ return 0;
+}
+
+asmlinkage void __exception_irq_entry armada_370_xp_handle_irq(struct pt_regs
+ *regs)
+{
+ u32 irqstat, irqnr;
+
+ do {
+ irqstat = readl_relaxed(per_cpu_int_base +
+ ARMADA_370_XP_CPU_INTACK_OFFS);
+ irqnr = irqstat & 0x3FF;
+
+ if (irqnr < 1023) {
+ irqnr =
+ irq_find_mapping(armada_370_xp_mpic_domain, irqnr);
+ handle_IRQ(irqnr, regs);
+ continue;
+ }
+
+ break;
+ } while (1);
+}
+
+static const struct of_device_id mpic_of_match[] __initconst = {
+ {.compatible = "marvell,mpic", .data = armada_370_xp_mpic_of_init},
+ {},
+};
+
+void __init armada_370_xp_init_irq(void)
+{
+ of_irq_init(mpic_of_match);
+}
diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c
new file mode 100644
index 000000000000..b8079df8c986
--- /dev/null
+++ b/arch/arm/mach-mvebu/system-controller.c
@@ -0,0 +1,105 @@
+/*
+ * System controller support for Armada 370 and XP platforms.
+ *
+ * Copyright (C) 2012 Marvell
+ *
+ * Lior Amsalem <alior@marvell.com>
+ * Gregory CLEMENT <gregory.clement@free-electrons.com>
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ *
+ * The Armada 370 and Armada XP SoCs both have a range of
+ * miscellaneous registers, that do not belong to a particular device,
+ * but rather provide system-level features. This basic
+ * system-controller driver provides a device tree binding for those
+ * registers, and implements utility functions offering various
+ * features related to those registers.
+ *
+ * For now, the feature set is limited to restarting the platform by a
+ * soft-reset, but it might be extended in the future.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+
+static void __iomem *system_controller_base;
+
+struct mvebu_system_controller {
+ u32 rstoutn_mask_offset;
+ u32 system_soft_reset_offset;
+
+ u32 rstoutn_mask_reset_out_en;
+ u32 system_soft_reset;
+};
+static struct mvebu_system_controller *mvebu_sc;
+
+const struct mvebu_system_controller armada_370_xp_system_controller = {
+ .rstoutn_mask_offset = 0x60,
+ .system_soft_reset_offset = 0x64,
+ .rstoutn_mask_reset_out_en = 0x1,
+ .system_soft_reset = 0x1,
+};
+
+const struct mvebu_system_controller orion_system_controller = {
+ .rstoutn_mask_offset = 0x108,
+ .system_soft_reset_offset = 0x10c,
+ .rstoutn_mask_reset_out_en = 0x4,
+ .system_soft_reset = 0x1,
+};
+
+static struct of_device_id of_system_controller_table[] = {
+ {
+ .compatible = "marvell,orion-system-controller",
+ .data = (void *) &orion_system_controller,
+ }, {
+ .compatible = "marvell,armada-370-xp-system-controller",
+ .data = (void *) &armada_370_xp_system_controller,
+ },
+ { /* end of list */ },
+};
+
+void mvebu_restart(char mode, const char *cmd)
+{
+ if (!system_controller_base) {
+ pr_err("Cannot restart, system-controller not available: check the device tree\n");
+ } else {
+ /*
+ * Enable soft reset to assert RSTOUTn.
+ */
+ writel(mvebu_sc->rstoutn_mask_reset_out_en,
+ system_controller_base +
+ mvebu_sc->rstoutn_mask_offset);
+ /*
+ * Assert soft reset.
+ */
+ writel(mvebu_sc->system_soft_reset,
+ system_controller_base +
+ mvebu_sc->system_soft_reset_offset);
+ }
+
+ while (1)
+ ;
+}
+
+static int __init mvebu_system_controller_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, of_system_controller_table);
+ if (np) {
+ const struct of_device_id *match =
+ of_match_node(of_system_controller_table, np);
+ BUG_ON(!match);
+ system_controller_base = of_iomap(np, 0);
+ mvebu_sc = (struct mvebu_system_controller *)match->data;
+ }
+
+ return 0;
+}
+
+arch_initcall(mvebu_system_controller_init);
OpenPOWER on IntegriCloud