From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 583DAC433E7 for ; Sat, 10 Oct 2020 00:28:49 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B90FD20678 for ; Sat, 10 Oct 2020 00:28:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="rCxdUfcj"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="csx9wD9x" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B90FD20678 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:References:Message-ID: Subject:To:From:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=YCd6iL6kbTu4CFWC+ZEoxJ/6OKh9/4SWNxjqkMALySM=; b=rCxdUfcjLDWFItUbsw0wgz0ss KRejaNAHa/tKvvModTnCY2b7KLB6PMS96Gr2Ymo6dr1j0OCFwcrOtiY91WnK+QfQ73qKNOsE2KG7l zLopGNpc44+JcRsxp5M4047o6PYNhbOenw1+vsGBYvrdx1ZrEEPvVpAZ+IdcnmL5uaFLKLfkqtLl8 HiWMBLC4pgJF/HFAMh0lx1hsuUPpSdhmL5WmXqXko05X8w5LHHmexz0528mXQIwz5x8mVwq3+Ogps vXd8id2KgGSL0QQqdsxSrnNGNZC8Enf8MKlSOm5/XhTGzpZNI8xKY2Vt77Us9Ebx/je/xT8xMTLr+ YJ+iYmxng==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kR2j4-0007qS-Bp; Sat, 10 Oct 2020 00:27:06 +0000 Received: from perceval.ideasonboard.com ([213.167.242.64]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kR2j1-0007ps-AP for linux-arm-kernel@lists.infradead.org; Sat, 10 Oct 2020 00:27:04 +0000 Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 40007528; Sat, 10 Oct 2020 02:27:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1602289621; bh=bQZLXW/lgvx4ivOlOd5viEeCFAKnjyXc725ML79Qmog=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=csx9wD9x2wF5vwxUfXE07h5RaxKHkq0caHEELfHxNx3F+cBsyussXbo7E73YX3BN8 zO71s5ASlOekHTaqCXujqq1cDRjLVpoLMql0s+uWmdANgqvHWymvXoBgUPiBHTF+c9 1SkUxVu7zTe/Z4spexgN+AbWj6MSYnNOMCiKektY= Date: Sat, 10 Oct 2020 03:26:17 +0300 From: Laurent Pinchart To: Marek Vasut Subject: Re: [PATCH] [RFC] ARM: imx: add smp support for imx7d Message-ID: <20201010002617.GA27426@pendragon.ideasonboard.com> References: <20200917160814.97995-1-marex@denx.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20200917160814.97995-1-marex@denx.de> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201009_202703_602015_8EEA8FEA X-CRM114-Status: GOOD ( 34.21 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Shawn Guo , Arulpandiyan Vadivel , Anson Huang , Leonard Crestez , Fabio Estevam , linux-arm-kernel@lists.infradead.org, NXP Linux Team Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Hi Marek, Thank you for the patch. On Thu, Sep 17, 2020 at 06:08:14PM +0200, Marek Vasut wrote: > From: Anson Huang > > Add SMP support for i.MX7D, including CPU hotplug support, for > systems where TFA is not present. > > The arm,cpu-registers-not-fw-configured is required, otherwise the > timer does not work correctly. > > Signed-off-by: Anson Huang > Signed-off-by: Arulpandiyan Vadivel # Fix merge conflicts > Signed-off-by: Leonard Crestez > Signed-off-by: Marek Vasut # heavy cleanup > Cc: Fabio Estevam > Cc: NXP Linux Team > Cc: Shawn Guo > To: linux-arm-kernel@lists.infradead.org [ 0.133746] CPU: Testing write buffer coherency: ok [ 0.139920] CPU0: update cpu_capacity 1024 [ 0.144078] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 [ 0.167964] smp: Bringing up secondary CPUs ... [ 0.176286] CPU1: update cpu_capacity 1024 [ 0.176299] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 [ 0.177840] smp: Brought up 1 node, 2 CPUs [ 0.191990] SMP: Total of 2 processors activated (96.00 BogoMIPS). [ 0.198374] CPU: All CPU(s) started in SVC mode. \o/ Glad to finally get SMP support on the i.MX7D :-) Tested-by: Laurent Pinchart > --- > arch/arm/boot/dts/imx7s.dtsi | 1 + > arch/arm/mach-imx/Makefile | 2 +- > arch/arm/mach-imx/common.h | 3 ++ > arch/arm/mach-imx/headsmp.S | 9 ++++ > arch/arm/mach-imx/hotplug.c | 3 ++ > arch/arm/mach-imx/mach-imx7d.c | 3 +- > arch/arm/mach-imx/platsmp.c | 26 +++++++++++ > arch/arm/mach-imx/src.c | 79 ++++++++++++++++++++++++++++++---- > 8 files changed, 115 insertions(+), 11 deletions(-) > > diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi > index 1cfaf410aa43..e878c3a9deed 100644 > --- a/arch/arm/boot/dts/imx7s.dtsi > +++ b/arch/arm/boot/dts/imx7s.dtsi > @@ -149,6 +149,7 @@ replicator_in_port0: endpoint { > > timer { > compatible = "arm,armv7-timer"; > + arm,cpu-registers-not-fw-configured; > interrupt-parent = <&intc>; > interrupts = , > , > diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile > index e7364e6c8c6b..c1e3a428d71b 100644 > --- a/arch/arm/mach-imx/Makefile > +++ b/arch/arm/mach-imx/Makefile > @@ -72,7 +72,7 @@ obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o > obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o > obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o > obj-$(CONFIG_HAVE_IMX_SRC) += src.o > -ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_LS1021A),) > +ifneq ($(CONFIG_SOC_IMX6)$(CONFIG_SOC_IMX7D_CA7)$(CONFIG_SOC_LS1021A),) > AFLAGS_headsmp.o :=-Wa,-march=armv7-a > obj-$(CONFIG_SMP) += headsmp.o platsmp.o > obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o > diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h > index 72c3fcc32910..de4383aa6a08 100644 > --- a/arch/arm/mach-imx/common.h > +++ b/arch/arm/mach-imx/common.h > @@ -84,11 +84,13 @@ void imx_set_cpu_arg(int cpu, u32 arg); > void v7_secondary_startup(void); > void imx_scu_map_io(void); > void imx_smp_prepare(void); > +void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn); > #else > static inline void imx_scu_map_io(void) {} > static inline void imx_smp_prepare(void) {} > #endif > void imx_src_init(void); > +void imx7_src_init(void); > void imx_gpc_pre_suspend(bool arm_power_off); > void imx_gpc_post_resume(void); > void imx_gpc_mask_all(void); > @@ -148,6 +150,7 @@ static inline void imx_init_l2cache(void) {} > #endif > > extern const struct smp_operations imx_smp_ops; > +extern const struct smp_operations imx7_smp_ops; > extern const struct smp_operations ls1021a_smp_ops; > > #endif > diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S > index 766dbdb2ae27..fcba58be8e79 100644 > --- a/arch/arm/mach-imx/headsmp.S > +++ b/arch/arm/mach-imx/headsmp.S > @@ -21,6 +21,15 @@ diag_reg_offset: > > ENTRY(v7_secondary_startup) > ARM_BE8(setend be) @ go BE8 if entered LE > + mrc p15, 0, r0, c0, c0, 0 > + lsl r0, r0, #16 > + lsr r0, r0, #20 > + /* 0xc07 is cortex A7's ID */ > + mov r1, #0xc00 > + orr r1, #0x7 > + cmp r0, r1 > + beq secondary_startup > + > set_diag_reg > b secondary_startup > ENDPROC(v7_secondary_startup) > diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c > index 82e22398d43d..e24a46dc5703 100644 > --- a/arch/arm/mach-imx/hotplug.c > +++ b/arch/arm/mach-imx/hotplug.c > @@ -11,6 +11,7 @@ > #include > > #include "common.h" > +#include "hardware.h" > > /* > * platform-specific code to shutdown a CPU > @@ -40,5 +41,7 @@ int imx_cpu_kill(unsigned int cpu) > return 0; > imx_enable_cpu(cpu, false); > imx_set_cpu_arg(cpu, 0); > + if (cpu_is_imx7d()) > + imx_gpcv2_set_core1_pdn_pup_by_software(true); > return 1; > } > diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c > index 879c35929a13..1eeb194fab65 100644 > --- a/arch/arm/mach-imx/mach-imx7d.c > +++ b/arch/arm/mach-imx/mach-imx7d.c > @@ -91,7 +91,7 @@ static void __init imx7d_init_late(void) > static void __init imx7d_init_irq(void) > { > imx_init_revision_from_anatop(); > - imx_src_init(); > + imx7_src_init(); > irqchip_init(); > } > > @@ -102,6 +102,7 @@ static const char *const imx7d_dt_compat[] __initconst = { > }; > > DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)") > + .smp = smp_ops(imx7_smp_ops), > .init_irq = imx7d_init_irq, > .init_machine = imx7d_init_machine, > .init_late = imx7d_init_late, > diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c > index cf4e9335831c..972639038be5 100644 > --- a/arch/arm/mach-imx/platsmp.c > +++ b/arch/arm/mach-imx/platsmp.c > @@ -92,6 +92,32 @@ const struct smp_operations imx_smp_ops __initconst = { > #endif > }; > > +/* > + * Initialise the CPU possible map early - this describes the CPUs > + * which may be present or become present in the system. > + */ > +static void __init imx7_smp_init_cpus(void) > +{ > + struct device_node *np; > + int i, ncores = 0; > + > + /* The iMX7D SCU does not report core count, get it from DT */ > + for_each_of_cpu_node(np) > + ncores++; > + > + for (i = ncores; i < NR_CPUS; i++) > + set_cpu_possible(i, false); > +} > + > +const struct smp_operations imx7_smp_ops __initconst = { > + .smp_init_cpus = imx7_smp_init_cpus, > + .smp_boot_secondary = imx_boot_secondary, > +#ifdef CONFIG_HOTPLUG_CPU > + .cpu_die = imx_cpu_die, > + .cpu_kill = imx_cpu_kill, > +#endif > +}; > + > #define DCFG_CCSR_SCRATCHRW1 0x200 > > static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle) > diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c > index f52f371292ac..326c7097fc25 100644 > --- a/arch/arm/mach-imx/src.c > +++ b/arch/arm/mach-imx/src.c > @@ -12,9 +12,12 @@ > #include > #include > #include "common.h" > +#include "hardware.h" > > #define SRC_SCR 0x000 > -#define SRC_GPR1 0x020 > +#define SRC_GPR1_V1 0x020 > +#define SRC_GPR1_V2 0x074 > +#define SRC_GPR1(v) ((gpr_v2) ? SRC_GPR1_V2 : SRC_GPR1_V1) > #define BP_SRC_SCR_WARM_RESET_ENABLE 0 > #define BP_SRC_SCR_SW_GPU_RST 1 > #define BP_SRC_SCR_SW_VPU_RST 2 > @@ -23,9 +26,18 @@ > #define BP_SRC_SCR_SW_IPU2_RST 12 > #define BP_SRC_SCR_CORE1_RST 14 > #define BP_SRC_SCR_CORE1_ENABLE 22 > +/* below is for i.MX7D */ > +#define SRC_A7RCR1 0x008 > +#define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1 > +#define GPC_CPU_PGC_SW_PUP_REQ 0xf0 > +#define GPC_CPU_PGC_SW_PDN_REQ 0xfc > +#define GPC_PGC_C1 0x840 > +#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2 > > static void __iomem *src_base; > static DEFINE_SPINLOCK(scr_lock); > +static bool gpr_v2; > +static void __iomem *gpc_base; > > static const int sw_reset_bits[5] = { > BP_SRC_SCR_SW_GPU_RST, > @@ -73,17 +85,48 @@ static struct reset_controller_dev imx_reset_controller = { > .nr_resets = ARRAY_SIZE(sw_reset_bits), > }; > > +void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset) > +{ > + writel_relaxed(enable, gpc_base + offset); > +} > + > +void imx_gpcv2_set_core1_pdn_pup_by_software(bool pdn) > +{ > + u32 reg = pdn ? GPC_CPU_PGC_SW_PDN_REQ : GPC_CPU_PGC_SW_PUP_REQ; > + u32 val; > + > + val = readl_relaxed(gpc_base + reg); > + imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1); > + val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7; > + writel_relaxed(val, gpc_base + reg); > + > + while (readl_relaxed(gpc_base + reg) & BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7) > + ; > + > + imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1); > +} > + > void imx_enable_cpu(int cpu, bool enable) > { > u32 mask, val; > > cpu = cpu_logical_map(cpu); > - mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); > spin_lock(&scr_lock); > - val = readl_relaxed(src_base + SRC_SCR); > - val = enable ? val | mask : val & ~mask; > - val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1); > - writel_relaxed(val, src_base + SRC_SCR); > + if (gpr_v2) { > + if (enable) > + imx_gpcv2_set_core1_pdn_pup_by_software(false); > + > + mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1); > + val = readl_relaxed(src_base + SRC_A7RCR1); > + val = enable ? val | mask : val & ~mask; > + writel_relaxed(val, src_base + SRC_A7RCR1); > + } else { > + mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); > + val = readl_relaxed(src_base + SRC_SCR); > + val = enable ? val | mask : val & ~mask; > + val |= 1 << (BP_SRC_SCR_CORE1_RST + cpu - 1); > + writel_relaxed(val, src_base + SRC_SCR); > + } > spin_unlock(&scr_lock); > } > > @@ -91,19 +134,19 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) > { > cpu = cpu_logical_map(cpu); > writel_relaxed(__pa_symbol(jump_addr), > - src_base + SRC_GPR1 + cpu * 8); > + src_base + SRC_GPR1(gpr_v2) + cpu * 8); > } > > u32 imx_get_cpu_arg(int cpu) > { > cpu = cpu_logical_map(cpu); > - return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); > + return readl_relaxed(src_base + SRC_GPR1(gpr_v2) + cpu * 8 + 4); > } > > void imx_set_cpu_arg(int cpu, u32 arg) > { > cpu = cpu_logical_map(cpu); > - writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); > + writel_relaxed(arg, src_base + SRC_GPR1(gpr_v2) + cpu * 8 + 4); > } > > void __init imx_src_init(void) > @@ -131,3 +174,21 @@ void __init imx_src_init(void) > writel_relaxed(val, src_base + SRC_SCR); > spin_unlock(&scr_lock); > } > + > +void __init imx7_src_init(void) > +{ > + struct device_node *np; > + gpr_v2 = true; > + > + np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-src"); > + if (!np) > + return; > + src_base = of_iomap(np, 0); > + WARN_ON(!src_base); > + > + np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-gpc"); > + if (WARN_ON(!np)) > + return; > + gpc_base = of_iomap(np, 0); > + WARN_ON(!gpc_base); > +} -- Regards, Laurent Pinchart _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel