From patchwork Thu Feb 20 00:01:01 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 3683531 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 5D394BF13A for ; Thu, 20 Feb 2014 00:00:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4235D201FE for ; Thu, 20 Feb 2014 00:00:26 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (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 0111E201F0 for ; Thu, 20 Feb 2014 00:00:24 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WGH3o-0007Zz-Is; Thu, 20 Feb 2014 00:00:16 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WGH3m-0004ev-4H; Thu, 20 Feb 2014 00:00:14 +0000 Received: from mail-pa0-x22d.google.com ([2607:f8b0:400e:c03::22d]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WGH3i-0004eP-A0 for linux-arm-kernel@lists.infradead.org; Thu, 20 Feb 2014 00:00:11 +0000 Received: by mail-pa0-f45.google.com with SMTP id lf10so1090567pab.18 for ; Wed, 19 Feb 2014 15:59:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:date:message-id:subject; bh=BybklourY4ALty0YmqNTjWdEQgttHufKdmkweilgGpg=; b=BznItv6RNmlDN81vXsD2r1A/H0ffmMeljXz2Av2girx+E/kkDipaew9BTCqhjt7HQ0 sOEB71SHiV+4Qbpox67168qF/FTz8SiMmWRMWCzmzdL2w+lyOriD6n9XFryw0io8ZsJ3 SQzKAIMz/XuWq8Y42xSpvHeT21wNBeTjWUHh/nBHzVqBJmc8IFNeexv9J9N3p5NaHfa+ 8Ff2rGpfSprCev/rbsOr5sdVPIYOKaVAXnlqd5CNPPX37bkJiFyf8c4WY/W6ZlfQCpIM elgaTq01B2H9MY5kSum2jnfomjny7oJYy5lEs4Jk6ozZsubsnmpQa0CckkO+J1NIREQj izeg== X-Received: by 10.66.141.231 with SMTP id rr7mr5343902pab.41.1392854385342; Wed, 19 Feb 2014 15:59:45 -0800 (PST) Received: from [127.0.0.1] (s214090.ppp.asahi-net.or.jp. [220.157.214.90]) by mx.google.com with ESMTPSA id un5sm11669793pab.3.2014.02.19.15.59.43 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Feb 2014 15:59:44 -0800 (PST) From: Magnus Damm To: linux-sh@vger.kernel.org Date: Thu, 20 Feb 2014 09:01:01 +0900 Message-Id: <20140220000101.3595.13281.sendpatchset@w520> Subject: [PATCH] ARM: shmobile: MCPM and CCI prototype X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140219_190010_527800_A54FAE3A X-CRM114-Status: GOOD ( 18.87 ) X-Spam-Score: -2.0 (--) Cc: horms@verge.net.au, Magnus Damm , 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: , 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.6 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable 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 From: Magnus Damm This is a prototype hack to tie in the CCI driver via MCPM on r8a7790 and the Lager platform. Needs much more work especially when it comes to combined RST and APMU support which is needed for JTAG support. Not-yet-signed-off-by: Magnus Damm --- arch/arm/boot/dts/r8a7790.dtsi | 28 +++++++ arch/arm/mach-shmobile/Kconfig | 2 arch/arm/mach-shmobile/headsmp.S | 7 + arch/arm/mach-shmobile/include/mach/common.h | 1 arch/arm/mach-shmobile/platsmp-apmu.c | 93 +++++++++++++++++++++++++- arch/arm/mach-shmobile/platsmp.c | 4 + 6 files changed, 132 insertions(+), 3 deletions(-) --- 0001/arch/arm/boot/dts/r8a7790.dtsi +++ work/arch/arm/boot/dts/r8a7790.dtsi 2014-02-20 08:30:37.000000000 +0900 @@ -34,6 +34,7 @@ compatible = "arm,cortex-a15"; reg = <0>; clock-frequency = <1300000000>; + cci-control-port = <&cci_control1>; }; cpu1: cpu@1 { @@ -41,6 +42,7 @@ compatible = "arm,cortex-a15"; reg = <1>; clock-frequency = <1300000000>; + cci-control-port = <&cci_control1>; }; cpu2: cpu@2 { @@ -48,6 +50,7 @@ compatible = "arm,cortex-a15"; reg = <2>; clock-frequency = <1300000000>; + cci-control-port = <&cci_control1>; }; cpu3: cpu@3 { @@ -55,6 +58,7 @@ compatible = "arm,cortex-a15"; reg = <3>; clock-frequency = <1300000000>; + cci-control-port = <&cci_control1>; }; cpu4: cpu@4 { @@ -62,6 +66,7 @@ compatible = "arm,cortex-a7"; reg = <0x100>; clock-frequency = <780000000>; + cci-control-port = <&cci_control2>; }; cpu5: cpu@5 { @@ -69,6 +74,7 @@ compatible = "arm,cortex-a7"; reg = <0x101>; clock-frequency = <780000000>; + cci-control-port = <&cci_control2>; }; cpu6: cpu@6 { @@ -76,6 +82,7 @@ compatible = "arm,cortex-a7"; reg = <0x102>; clock-frequency = <780000000>; + cci-control-port = <&cci_control2>; }; cpu7: cpu@7 { @@ -83,6 +90,7 @@ compatible = "arm,cortex-a7"; reg = <0x103>; clock-frequency = <780000000>; + cci-control-port = <&cci_control2>; }; }; @@ -98,6 +106,26 @@ interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; }; + cci@f0090000 { + compatible = "arm,cci-400"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0 0xf0090000 0 0x1000>; + ranges = <0x0 0x0 0xf0090000 0x10000>; + + cci_control1: slave-if@4000 { + compatible = "arm,cci-400-ctrl-if"; + interface-type = "ace"; + reg = <0x4000 0x1000>; + }; + + cci_control2: slave-if@5000 { + compatible = "arm,cci-400-ctrl-if"; + interface-type = "ace"; + reg = <0x5000 0x1000>; + }; + }; + gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; --- 0001/arch/arm/mach-shmobile/Kconfig +++ work/arch/arm/mach-shmobile/Kconfig 2014-02-20 08:30:37.000000000 +0900 @@ -32,10 +32,12 @@ config ARCH_R7S72100 config ARCH_R8A7790 bool "R-Car H2 (R8A77900)" select RENESAS_IRQC + select ARM_CCI config ARCH_R8A7791 bool "R-Car M2 (R8A77910)" select RENESAS_IRQC + select ARM_CCI comment "Renesas ARM SoCs Board Type" --- 0001/arch/arm/mach-shmobile/headsmp.S +++ work/arch/arm/mach-shmobile/headsmp.S 2014-02-20 08:30:37.000000000 +0900 @@ -19,6 +19,13 @@ ENTRY(shmobile_invalidate_start) b secondary_startup ENDPROC(shmobile_invalidate_start) +#ifdef CONFIG_MCPM +ENTRY(shmobile_invalidate_mcpm_entry) + bl v7_invalidate_l1 + b mcpm_entry_point +ENDPROC(shmobile_invalidate_mcpm_entry) +#endif + /* * Reset vector for secondary CPUs. * This will be mapped at address 0 by SBAR register. --- 0001/arch/arm/mach-shmobile/include/mach/common.h +++ work/arch/arm/mach-shmobile/include/mach/common.h 2014-02-20 08:30:37.000000000 +0900 @@ -16,6 +16,7 @@ extern void shmobile_smp_hook(unsigned i unsigned long arg); extern int shmobile_smp_cpu_disable(unsigned int cpu); extern void shmobile_invalidate_start(void); +extern void shmobile_invalidate_mcpm_entry(void); extern void shmobile_boot_scu(void); extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); extern void shmobile_smp_scu_cpu_die(unsigned int cpu); --- 0001/arch/arm/mach-shmobile/platsmp-apmu.c +++ work/arch/arm/mach-shmobile/platsmp-apmu.c 2014-02-20 08:56:01.000000000 +0900 @@ -7,22 +7,28 @@ * 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 #include #include #include +#include #include #include -static struct { +static struct apmu_cpu { void __iomem *iomem; int bit; } apmu_cpus[CONFIG_NR_CPUS]; +#define MAX_NR_CLUSTERS 2 +static struct apmu_cpu *apmu_clst2cpu[MAX_NR_CLUSTERS][CONFIG_NR_CPUS]; + #define WUPCR_OFFS 0x10 #define PSTR_OFFS 0x40 #define CPUNCR_OFFS(n) (0x100 + (0x10 * (n))) @@ -69,14 +75,23 @@ static int apmu_wrap(int cpu, int (*fn)( static void apmu_init_cpu(struct resource *res, int cpu, int bit) { + u32 id; + int mcpm_cpu, mcpm_cluster; + if (apmu_cpus[cpu].iomem) return; apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res)); apmu_cpus[cpu].bit = bit; - pr_debug("apmu ioremap %d %d 0x%08x 0x%08x\n", cpu, bit, - res->start, resource_size(res)); + id = cpu_logical_map(cpu); + mcpm_cpu = MPIDR_AFFINITY_LEVEL(id, 0); + mcpm_cluster = MPIDR_AFFINITY_LEVEL(id, 1); + + pr_debug("apmu ioremap %d %d 0x%08x 0x%08x %d %d\n", cpu, bit, + res->start, resource_size(res), mcpm_cluster, mcpm_cpu); + + apmu_clst2cpu[mcpm_cluster][mcpm_cpu] = &apmu_cpus[cpu]; } static struct { @@ -124,6 +139,75 @@ static void apmu_parse_cfg(void (*fn)(st } } +#ifdef CONFIG_MCPM +/* + * Enable cluster-level coherency, in preparation for turning on the MMU. + */ +static void __naked apmu_power_up_setup(unsigned int affinity_level) +{ + asm volatile (" \n" +" cmp r0, #1 \n" +" bxne lr \n" +" b cci_enable_port_for_self "); +} + +static int __init foo_pm_init(void) +{ + if (!cci_probed()) + return -ENODEV; + + mcpm_sync_init(apmu_power_up_setup); + return 0; +} + +early_initcall(foo_pm_init); /* FIXME: special init ordering really needed? */ + +static int apmu_power_up(unsigned int cpu, unsigned int cluster) +{ + struct apmu_cpu *ac = apmu_clst2cpu[cluster][cpu]; + + pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); + + if (!ac) + return -EINVAL; + + shmobile_smp_hook(ac - &apmu_cpus[0], + virt_to_phys(shmobile_invalidate_mcpm_entry), 0); + + return apmu_wrap(ac - &apmu_cpus[0], apmu_power_on); +} + +static const struct mcpm_platform_ops apmu_pm_power_ops = { + .power_up = apmu_power_up, +}; + +static void __init shmobile_smp_apmu_mcpm_hook(void) +{ + /* + * The best way to detect a multi-cluster configuration at the moment + * is to look for the presence of a CCI in the system. + * Override the default smp_ops if so. + */ + struct device_node *node; + int ret; + + node = of_find_compatible_node(NULL, NULL, "arm,cci-400"); + if (!node && !of_device_is_available(node)) + return; + + mcpm_smp_set_ops(); + + ret = mcpm_platform_register(&apmu_pm_power_ops); + if (!ret) + pr_info("APMU MCPM power management initialized\n"); +} + +#else +static void __init shmobile_smp_apmu_mcpm_hook(void) +{ +} +#endif + void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) { /* install boot code shared by all CPUs */ @@ -132,6 +216,9 @@ void __init shmobile_smp_apmu_prepare_cp /* perform per-cpu setup */ apmu_parse_cfg(apmu_init_cpu); + + /* hook in MCPM if needed */ + shmobile_smp_apmu_mcpm_hook(); } int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) --- 0001/arch/arm/mach-shmobile/platsmp.c +++ work/arch/arm/mach-shmobile/platsmp.c 2014-02-20 08:30:37.000000000 +0900 @@ -28,6 +28,10 @@ void shmobile_smp_hook(unsigned int cpu, shmobile_smp_fn[cpu] = fn; shmobile_smp_arg[cpu] = arg; flush_cache_all(); + + sync_cache_w(&shmobile_smp_mpidr[cpu]); + sync_cache_w(&shmobile_smp_fn[cpu]); + sync_cache_w(&shmobile_smp_arg[cpu]); } #ifdef CONFIG_HOTPLUG_CPU