From patchwork Tue Dec 23 21:13:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Packham X-Patchwork-Id: 5535521 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9D66F9F1CD for ; Tue, 23 Dec 2014 21:17:18 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8B7C220120 for ; Tue, 23 Dec 2014 21:17:17 +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 8721A20108 for ; Tue, 23 Dec 2014 21:17:16 +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 1Y3WnZ-0005DS-6A; Tue, 23 Dec 2014 21:15:21 +0000 Received: from gate2.alliedtelesis.co.nz ([2001:df5:b000:5::4]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Y3Wmx-0003td-QK for linux-arm-kernel@lists.infradead.org; Tue, 23 Dec 2014 21:14:46 +0000 Received: from mmarshal3.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id E835F806A8; Wed, 24 Dec 2014 10:14:16 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail; t=1419369256; bh=A1uhMm5MqLR84gSxq47Jf/2Qkna95Fq62xIfFGUNjBY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=X+umdrv0y2FStySJlP5HGGLJxL/6v+oPZgcA1ukWM0PPRvbfYBLHdtkL13EpCFkw+ lhRZadzHhUapCzSZycB+BcW/9a17Hi2N1tOUiqBASushS6kW39fVZLtefZFQLBxXy/ bhM+1riWfy+e9xmJyQHiPIlxbXk7R0CKab6MsisY= Received: from alliedtelesyn.co.nz (Not Verified[10.32.16.32]) by mmarshal3.atlnz.lc with Trustwave SEG (v7, 3, 0, 7277) id ; Wed, 24 Dec 2014 10:14:13 +1300 Received: from MAIL/SpoolDir by alliedtelesyn.co.nz (Mercury 1.48); 24 Dec 14 10:14:51 +1300 Received: from SpoolDir by MAIL (Mercury 1.48); 24 Dec 14 10:14:50 +1300 Received: from chrisp-dl.ws.atlnz.lc (10.33.22.30) by alliedtelesyn.co.nz (Mercury 1.48) with ESMTP; 24 Dec 14 10:14:42 +1300 Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id 9BC5280DF8; Wed, 24 Dec 2014 10:14:02 +1300 (NZDT) From: Chris Packham To: linux-arm-kernel@lists.infradead.org Subject: [RFC/PATCHv2 5/5] ARM: mvebu: Custom smp_ops for 98DX4251 Date: Wed, 24 Dec 2014 10:13:32 +1300 Message-Id: <1419369212-17047-6-git-send-email-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.2.0.rc0 In-Reply-To: <1419369212-17047-1-git-send-email-chris.packham@alliedtelesis.co.nz> References: <1419369212-17047-1-git-send-email-chris.packham@alliedtelesis.co.nz> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141223_131444_465829_A9EB18F9 X-CRM114-Status: GOOD ( 19.46 ) X-Spam-Score: -0.1 (/) Cc: Andrew Lunn , Jason Cooper , Boris Brezillon , Chris Packham , Ezequiel Garcia , Gregory Clement , Maxime Ripard , Sebastian Hesselbarth X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Compared to the armada-xp the 98DX4251 uses different registers to set the boot address for the secondary CPU. This seems to contradict the datasheet which lists the same PMSU registers. This could be an error in the datasheet since it is likely to reproduce much of the armada-xp information. Or it could be an artifact of the early silicon revision being used. Signed-off-by: Chris Packham --- I wasn't sure about the name "pmsu-98dx4251" originally I called this "msys" but following previous conversations on the subject I've opted to go with something specific to the chip I'm dealing with. I could fold this into pmsu.c so it was alongside mvebu_pmsu_set_cpu_boot_addr if people think that would be better. arch/arm/boot/dts/rd-dxbc2.dts | 9 +++++ arch/arm/mach-mvebu/Makefile | 1 + arch/arm/mach-mvebu/common.h | 2 ++ arch/arm/mach-mvebu/platsmp.c | 28 +++++++++++++++ arch/arm/mach-mvebu/pmsu-98dx4251.c | 68 +++++++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+) create mode 100644 arch/arm/mach-mvebu/pmsu-98dx4251.c diff --git a/arch/arm/boot/dts/rd-dxbc2.dts b/arch/arm/boot/dts/rd-dxbc2.dts index 97a72d4..5763c4f 100644 --- a/arch/arm/boot/dts/rd-dxbc2.dts +++ b/arch/arm/boot/dts/rd-dxbc2.dts @@ -28,6 +28,10 @@ model = "Marvell Bobcat2 Evaluation Board"; compatible = "marvell,axp-db", "marvell,armadaxp-mv78260", "marvell,armadaxp", "marvell,armada-370-xp"; + cpus { + enable-method = "marvell,98dx4251-smp"; + }; + chosen { bootargs = "console=ttyS0,115200 earlyprintk"; }; @@ -104,6 +108,11 @@ xor@f0900 { status = "disabled"; }; + + resume@20980 { + compatible = "marvell,98dx4251-resume-ctrl"; + reg = <0x20980 0x10>; + }; }; }; }; diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index e24136b..866822e 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o ifeq ($(CONFIG_MACH_MVEBU_V7),y) obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o +obj-y += pmsu-98dx4251.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o endif diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h index 3ccb40c..5064ac5 100644 --- a/arch/arm/mach-mvebu/common.h +++ b/arch/arm/mach-mvebu/common.h @@ -25,4 +25,6 @@ int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev); void __iomem *mvebu_get_scu_base(void); +void mv98dx4251_resume_set_cpu_boot_addr(int hw_cpu, void *boot_addr); + #endif diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index 895dc37..2a2ed65d 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c @@ -180,5 +180,33 @@ struct smp_operations armada_xp_smp_ops __initdata = { #endif }; +static int mv98dx4251_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + int ret, hw_cpu; + + pr_info("Booting CPU %d\n", cpu); + + hw_cpu = cpu_logical_map(cpu); + mv98dx4251_resume_set_cpu_boot_addr(hw_cpu, armada_xp_secondary_startup); + ret = mvebu_cpu_reset_deassert(hw_cpu); + if (ret) { + pr_warn("unable to boot CPU: %d\n", ret); + return ret; + } + + return 0; +} + +struct smp_operations mv98dx4251_smp_ops __initdata = { + .smp_init_cpus = armada_xp_smp_init_cpus, + .smp_prepare_cpus = armada_xp_smp_prepare_cpus, + .smp_boot_secondary = mv98dx4251_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = armada_xp_cpu_die, +#endif +}; + CPU_METHOD_OF_DECLARE(armada_xp_smp, "marvell,armada-xp-smp", &armada_xp_smp_ops); +CPU_METHOD_OF_DECLARE(mv98dx4251_smp, "marvell,98dx4251-smp", + &mv98dx4251_smp_ops); diff --git a/arch/arm/mach-mvebu/pmsu-98dx4251.c b/arch/arm/mach-mvebu/pmsu-98dx4251.c new file mode 100644 index 0000000..e4d3ad46 --- /dev/null +++ b/arch/arm/mach-mvebu/pmsu-98dx4251.c @@ -0,0 +1,68 @@ +/** + * CPU resume support for 98DX4521 internal CPU (a.k.a. MSYS). + */ + +#define pr_fmt(fmt) "mv98dx4251-resume: " fmt + +#include +#include +#include +#include +#include "common.h" + +static void __iomem *mv98dx4251_resume_base; +#define MV98DX4251_CPU_RESUME_CTRL_OFFSET 0x08 +#define MV98DX4251_CPU_RESUME_ADDR_OFFSET 0x04 + +static struct of_device_id of_mv98dx4251_resume_table[] = { + {.compatible = "marvell,98dx4251-resume-ctrl",}, + { /* end of list */ }, +}; + +void mv98dx4251_resume_set_cpu_boot_addr(int hw_cpu, void *boot_addr) +{ + WARN_ON(hw_cpu != 1); + + writel(0, mv98dx4251_resume_base + MV98DX4251_CPU_RESUME_CTRL_OFFSET); + writel(virt_to_phys(boot_addr), mv98dx4251_resume_base + + MV98DX4251_CPU_RESUME_ADDR_OFFSET); +} + +static int __init mv98dx4251_resume_init(void) +{ + struct device_node *np; + struct resource res; + int ret = 0; + + np = of_find_matching_node(NULL, of_mv98dx4251_resume_table); + if (!np) + return 0; + + pr_info("Initializing 98DX4521 Resume\n"); + + if (of_address_to_resource(np, 0, &res)) { + pr_err("unable to get resource\n"); + ret = -ENOENT; + goto out; + } + + if (!request_mem_region(res.start, resource_size(&res), np->full_name)) { + pr_err("unable to request region\n"); + ret = -EBUSY; + goto out; + } + + mv98dx4251_resume_base = ioremap(res.start, resource_size(&res)); + if (!mv98dx4251_resume_base) { + pr_err("unable to map registers\n"); + release_mem_region(res.start, resource_size(&res)); + ret = -ENOMEM; + goto out; + } + +out: + of_node_put(np); + return ret; +} + +early_initcall(mv98dx4251_resume_init);