From patchwork Mon Jul 2 15:39:29 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 1147311 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id AC23F40AEE for ; Mon, 2 Jul 2012 15:47:14 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1SlilN-0002zw-2D; Mon, 02 Jul 2012 15:42:11 +0000 Received: from mail.free-electrons.com ([88.190.12.23]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1SlijS-0002td-Lb for linux-arm-kernel@lists.infradead.org; Mon, 02 Jul 2012 15:40:16 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id 1CDEE329; Mon, 2 Jul 2012 17:40:03 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-2.7 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham version=3.3.1 Received: from localhost (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id 6B5A932A; Mon, 2 Jul 2012 17:39:42 +0200 (CEST) From: Thomas Petazzoni To: Arnd Bergmann , Olof Johansson Subject: [PATCH 4/9] arm: mach-mvebu: add support for Armada 370 and Armada XP with DT Date: Mon, 2 Jul 2012 17:39:29 +0200 Message-Id: <1341243574-3258-5-git-send-email-thomas.petazzoni@free-electrons.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1341243574-3258-1-git-send-email-thomas.petazzoni@free-electrons.com> References: <1341243574-3258-1-git-send-email-thomas.petazzoni@free-electrons.com> X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Lior Amsalem , Andrew Lunn , Yehuda Yitschak , Jason Cooper , Tawfik Bayouk , Nicolas Pitre , Jon Masters , David Marlin , Eran Ben-Avi , Nadav Haklai , Maen Suleiman , Ben Dooks , Shadi Ammouri , Ben Dooks , Gregory Clement , Eric Miao , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org [ben.dooks@codethink.co.uk: ensure error check on of_property_read_u32] [ben.dooks@codethink.co.uk: use mpic address instead of bus-unit's ] [ben.dooks@codethink.co.uk: BUG_ON() if the of_iomap() fails for mpic] [ben.dooks@codethink.co.uk: move mpic per-cpu register base ] [ben.dooks@codethink.co.uk: number fetch should use irqd_to_hwirq()] Signed-off-by: Gregory CLEMENT Signed-off-by: Thomas Petazzoni Signed-off-by: Lior Amsalem Signed-off-by: Ben Dooks Acked-by: Andrew Lunn --- arch/arm/boot/dts/armada-370-db.dts | 42 +++++++ arch/arm/boot/dts/armada-370-xp.dtsi | 68 +++++++++++ arch/arm/boot/dts/armada-370.dtsi | 35 ++++++ arch/arm/boot/dts/armada-xp-db.dts | 50 +++++++++ arch/arm/boot/dts/armada-xp.dtsi | 55 +++++++++ arch/arm/mach-mvebu/Kconfig | 9 ++ arch/arm/mach-mvebu/Makefile | 1 + arch/arm/mach-mvebu/armada-370-xp.c | 63 +++++++++++ arch/arm/mach-mvebu/common.h | 3 + arch/arm/mach-mvebu/include/mach/armada-370-xp.h | 22 ++++ arch/arm/mach-mvebu/irq-armada-370-xp.c | 130 ++++++++++++++++++++++ 11 files changed, 478 insertions(+) create mode 100644 arch/arm/boot/dts/armada-370-db.dts create mode 100644 arch/arm/boot/dts/armada-370-xp.dtsi create mode 100644 arch/arm/boot/dts/armada-370.dtsi create mode 100644 arch/arm/boot/dts/armada-xp-db.dts create mode 100644 arch/arm/boot/dts/armada-xp.dtsi create mode 100644 arch/arm/mach-mvebu/armada-370-xp.c create mode 100644 arch/arm/mach-mvebu/include/mach/armada-370-xp.h create mode 100644 arch/arm/mach-mvebu/irq-armada-370-xp.c diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts new file mode 100644 index 0000000..fffd5c2 --- /dev/null +++ b/arch/arm/boot/dts/armada-370-db.dts @@ -0,0 +1,42 @@ +/* + * Device Tree file for Marvell Armada 370 evaluation board + * (DB-88F6710-BP-DDR3) + * + * Copyright (C) 2012 Marvell + * + * Lior Amsalem + * Gregory CLEMENT + * Thomas Petazzoni + * + * 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. + */ + +/dts-v1/; +/include/ "armada-370.dtsi" + +/ { + model = "Marvell Armada 370 Evaluation Board"; + compatible = "marvell,a370-db", "marvell,armada370", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; /* 512 MB */ + }; + + soc { + serial@d0012000 { + clock-frequency = <200000000>; + status = "okay"; + }; + timer@d0020300 { + clock-frequency = <600000000>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi new file mode 100644 index 0000000..9b55f01 --- /dev/null +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -0,0 +1,68 @@ +/* + * Device Tree Include file for Marvell Armada 370 and Armada XP SoC + * + * Copyright (C) 2012 Marvell + * + * Lior Amsalem + * Gregory CLEMENT + * Thomas Petazzoni + * Ben Dooks + * + * 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. + * + * This file contains the definitions that are common to the Armada + * 370 and Armada XP SoC. + */ + +/include/ "skeleton.dtsi" + +/ { + model = "Marvell Armada 370 and XP SoC"; + compatible = "marvell,armada_370_xp"; + + cpus { + cpu@0 { + compatible = "marvell,sheeva-v7"; + }; + }; + + mpic: interrupt-controller@d0020000 { + compatible = "marvell,mpic"; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + interrupt-controller; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&mpic>; + ranges; + + serial@d0012000 { + compatible = "ns16550"; + reg = <0xd0012000 0x100>; + reg-shift = <2>; + interrupts = <41>; + status = "disabled"; + }; + serial@d0012100 { + compatible = "ns16550"; + reg = <0xd0012100 0x100>; + reg-shift = <2>; + interrupts = <42>; + status = "disabled"; + }; + + timer@d0020300 { + compatible = "marvell,timer"; + reg = <0xd0020300 0x30>; + interrupts = <37>, <38>, <39>, <40>; + }; + }; +}; + diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi new file mode 100644 index 0000000..3228ccc --- /dev/null +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -0,0 +1,35 @@ +/* + * Device Tree Include file for Marvell Armada 370 family SoC + * + * Copyright (C) 2012 Marvell + * + * Lior Amsalem + * Gregory CLEMENT + * Thomas Petazzoni + * + * 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. + * + * Contains definitions specific to the Armada 370 SoC that are not + * common to all Armada SoCs. + */ + +/include/ "armada-370-xp.dtsi" + +/ { + model = "Marvell Armada 370 family SoC"; + compatible = "marvell,armada370", "marvell,armada-370-xp"; + + mpic: interrupt-controller@d0020000 { + reg = <0xd0020a00 0x1d0>, + <0xd0021870 0x58>; + }; + + soc { + system-controller@d0018200 { + compatible = "marvell,armada-370-xp-system-controller"; + reg = <0xd0018200 0x100>; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts new file mode 100644 index 0000000..f97040d --- /dev/null +++ b/arch/arm/boot/dts/armada-xp-db.dts @@ -0,0 +1,50 @@ +/* + * Device Tree file for Marvell Armada XP evaluation board + * (DB-78460-BP) + * + * Copyright (C) 2012 Marvell + * + * Lior Amsalem + * Gregory CLEMENT + * Thomas Petazzoni + * + * 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. + */ + +/dts-v1/; +/include/ "armada-xp.dtsi" + +/ { + model = "Marvell Armada XP Evaluation Board"; + compatible = "marvell,axp-db", "marvell,armadaxp", "marvell,armada-370-xp"; + + chosen { + bootargs = "console=ttyS0,115200 earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x80000000>; /* 2 GB */ + }; + + soc { + serial@d0012000 { + clock-frequency = <250000000>; + status = "okay"; + }; + serial@d0012100 { + clock-frequency = <250000000>; + status = "okay"; + }; + serial@d0012200 { + clock-frequency = <250000000>; + status = "okay"; + }; + serial@d0012300 { + clock-frequency = <250000000>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi new file mode 100644 index 0000000..e1fa7e6 --- /dev/null +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -0,0 +1,55 @@ +/* + * Device Tree Include file for Marvell Armada XP family SoC + * + * Copyright (C) 2012 Marvell + * + * Lior Amsalem + * Gregory CLEMENT + * Thomas Petazzoni + * Ben Dooks + * + * 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. + * + * Contains definitions specific to the Armada 370 SoC that are not + * common to all Armada SoCs. + */ + +/include/ "armada-370-xp.dtsi" + +/ { + model = "Marvell Armada XP family SoC"; + compatible = "marvell,armadaxp", "marvell,armada-370-xp"; + + mpic: interrupt-controller@d0020000 { + reg = <0xd0020a00 0x1d0>, + <0xd0021870 0x58>; + }; + + soc { + serial@d0012200 { + compatible = "ns16550"; + reg = <0xd0012200 0x100>; + reg-shift = <2>; + interrupts = <43>; + status = "disabled"; + }; + serial@d0012300 { + compatible = "ns16550"; + reg = <0xd0012300 0x100>; + reg-shift = <2>; + interrupts = <44>; + status = "disabled"; + }; + + timer@d0020300 { + marvell,timer-25Mhz; + }; + + system-controller@d0018200 { + compatible = "marvell,armada-370-xp-system-controller"; + reg = <0xd0018200 0x500>; + }; + }; +}; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 72d39e5..caa2c5e 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -2,6 +2,15 @@ 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 index 7366ae7..e61d2b8 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -1 +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/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c new file mode 100644 index 0000000..4ef923b --- /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 + * Gregory CLEMENT + * Thomas Petazzoni + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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 index f0eaa21..02f89ea 100644 --- a/arch/arm/mach-mvebu/common.h +++ b/arch/arm/mach-mvebu/common.h @@ -17,4 +17,7 @@ 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 0000000..25f0ca8 --- /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 + * Gregory CLEMENT + * Thomas Petazzoni + * + * 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/irq-armada-370-xp.c b/arch/arm/mach-mvebu/irq-armada-370-xp.c new file mode 100644 index 0000000..645a8d3 --- /dev/null +++ b/arch/arm/mach-mvebu/irq-armada-370-xp.c @@ -0,0 +1,130 @@ +/* + * Marvell Armada 370 and Armada XP SoC IRQ handling + * + * Copyright (C) 2012 Marvell + * + * Lior Amsalem + * Gregory CLEMENT + * Thomas Petazzoni + * Ben Dooks + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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_SET_ENABLE_OFFS (0x30) +#define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34) + +#define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) + +#define ARMADA_370_XP_NR_IRQS (115) + +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) +{ + 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); + + armada_370_xp_mpic_domain = + irq_domain_add_linear(node, ARMADA_370_XP_NR_IRQS, + &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); +}