From patchwork Mon Jun 2 09:21:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Antoine Tenart X-Patchwork-Id: 4280901 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 93BF3BEEA7 for ; Mon, 2 Jun 2014 09:23:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A3249200CF for ; Mon, 2 Jun 2014 09:23:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A7715203AB for ; Mon, 2 Jun 2014 09:23:34 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WrORI-0003GN-Ar; Mon, 02 Jun 2014 09:21:56 +0000 Received: from top.free-electrons.com ([176.31.233.9] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WrOQr-0002rf-KI for linux-arm-kernel@lists.infradead.org; Mon, 02 Jun 2014 09:21:30 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id F23EE808; Mon, 2 Jun 2014 11:21:14 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (col31-4-88-188-83-94.fbx.proxad.net [88.188.83.94]) by mail.free-electrons.com (Postfix) with ESMTPSA id 558337B5; Mon, 2 Jun 2014 11:21:14 +0200 (CEST) From: =?UTF-8?q?Antoine=20T=C3=A9nart?= To: sebastian.hesselbarth@gmail.com Subject: [PATCH 1/5] ARM: berlin: add SMP support Date: Mon, 2 Jun 2014 11:21:02 +0200 Message-Id: <1401700866-24804-2-git-send-email-antoine.tenart@free-electrons.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1401700866-24804-1-git-send-email-antoine.tenart@free-electrons.com> References: <1401700866-24804-1-git-send-email-antoine.tenart@free-electrons.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140602_022129_972513_4BC2270E X-CRM114-Status: GOOD ( 17.98 ) X-Spam-Score: 0.3 (/) Cc: thomas.petazzoni@free-electrons.com, zmxu@marvell.com, devicetree@vger.kernel.org, =?UTF-8?q?Antoine=20T=C3=A9nart?= , linux-kernel@vger.kernel.org, alexandre.belloni@free-electrons.com, jszhang@marvell.com, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Adds SMP support for Berlin SoCs. Secondary CPUs are reseted, then execute the instruction we put in the reset exception register, setting the pc at the address contained in the software reset address register, which is the physical address of the Berlin secondary startup. This implementation avoid using the pen lock mechanism. Signed-off-by: Antoine Ténart --- arch/arm/mach-berlin/Kconfig | 3 ++ arch/arm/mach-berlin/Makefile | 3 +- arch/arm/mach-berlin/headsmp.S | 30 +++++++++++++ arch/arm/mach-berlin/platsmp.c | 99 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-berlin/headsmp.S create mode 100644 arch/arm/mach-berlin/platsmp.c diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig index d3c5f14dc142..e3733692f67a 100644 --- a/arch/arm/mach-berlin/Kconfig +++ b/arch/arm/mach-berlin/Kconfig @@ -4,6 +4,7 @@ config ARCH_BERLIN select GENERIC_IRQ_CHIP select DW_APB_ICTL select DW_APB_TIMER_OF + select SMP if ARCH_BERLIN @@ -13,6 +14,7 @@ config MACH_BERLIN_BG2 bool "Marvell Armada 1500 (BG2)" select CACHE_L2X0 select CPU_PJ4B + select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP config MACH_BERLIN_BG2CD @@ -24,6 +26,7 @@ config MACH_BERLIN_BG2Q bool "Marvell Armada 1500 Pro (BG2-Q)" select CACHE_L2X0 select CPU_V7 + select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP select HAVE_SMP diff --git a/arch/arm/mach-berlin/Makefile b/arch/arm/mach-berlin/Makefile index ab69fe956f49..c0719ecd1890 100644 --- a/arch/arm/mach-berlin/Makefile +++ b/arch/arm/mach-berlin/Makefile @@ -1 +1,2 @@ -obj-y += berlin.o +obj-y += berlin.o +obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/mach-berlin/headsmp.S b/arch/arm/mach-berlin/headsmp.S new file mode 100644 index 000000000000..d295b5185598 --- /dev/null +++ b/arch/arm/mach-berlin/headsmp.S @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Ténart + * + * 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 +#include +#include + +ENTRY(berlin_secondary_startup) + ARM_BE8(setend be) + bl v7_invalidate_l1 + b secondary_startup +ENDPROC(berlin_secondary_startup) + +/* + * If the following instruction is set in the reset exception register, CPUs + * will fetch the value of the software reset address register when being + * reseted. + */ +.global boot_inst +boot_inst: + ldr pc, [pc, #140] + + .align diff --git a/arch/arm/mach-berlin/platsmp.c b/arch/arm/mach-berlin/platsmp.c new file mode 100644 index 000000000000..c04c90b81ae3 --- /dev/null +++ b/arch/arm/mach-berlin/platsmp.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Ténart + * + * 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 +#include +#include +#include + +#include +#include +#include + +#define CPU_RESET 0x00 + +#define RESET_VECT 0x00 +#define SW_RESET_ADDR 0x94 + +extern void berlin_secondary_startup(void); +extern u32 boot_inst; + +static void __iomem *cpu_ctrl; + +static inline void berlin_reset_cpu(unsigned int cpu) +{ + u32 val; + + val = readl(cpu_ctrl + CPU_RESET); + val |= BIT(cpu_logical_map(cpu)); + writel(val, cpu_ctrl + CPU_RESET); +} + +static int berlin_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + if (!cpu_ctrl) + return -EFAULT; + + /* + * Reset the CPU, making it to execute the instruction in the reset + * exception register. + */ + berlin_reset_cpu(cpu); + + return 0; +} + +static void __init berlin_smp_prepare_cpus(unsigned int max_cpus) +{ + struct device_node *np; + void __iomem *scu_base; + void __iomem *vectors_base; + + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); + scu_base = of_iomap(np, 0); + of_node_put(np); + if (!scu_base) + return; + + np = of_find_compatible_node(NULL, NULL, "marvell,berlin-cpu-ctrl"); + cpu_ctrl = of_iomap(np, 0); + of_node_put(np); + if (!cpu_ctrl) + goto unmap_scu; + + vectors_base = ioremap(CONFIG_VECTORS_BASE, SZ_32K); + if (!vectors_base) + goto unmap_scu; + + scu_enable(scu_base); + flush_cache_all(); + + /* + * Write the first instruction the CPU will execute after being reseted + * in the reset exception register. + */ + writel(boot_inst, vectors_base + RESET_VECT); + + /* + * Write the secondary startup address into the SW reset address + * register. This is used by boot_inst. + */ + writel(virt_to_phys(berlin_secondary_startup), vectors_base + SW_RESET_ADDR); + + iounmap(vectors_base); +unmap_scu: + iounmap(scu_base); +} + +static struct smp_operations berlin_smp_ops __initdata = { + .smp_prepare_cpus = berlin_smp_prepare_cpus, + .smp_boot_secondary = berlin_boot_secondary, +}; +CPU_METHOD_OF_DECLARE(berlin_smp, "marvell,berlin-smp", &berlin_smp_ops);