From patchwork Sat Jun 7 16:10:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Pitre X-Patchwork-Id: 4315731 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 8C6EB9F392 for ; Sat, 7 Jun 2014 16:14:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8CEBB201F7 for ; Sat, 7 Jun 2014 16:14:08 +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 A0E202018A for ; Sat, 7 Jun 2014 16:14:07 +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 1WtJCo-0000v2-1H; Sat, 07 Jun 2014 16:10:54 +0000 Received: from mail-qg0-f48.google.com ([209.85.192.48]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WtJCl-0000tA-6X for linux-arm-kernel@lists.infradead.org; Sat, 07 Jun 2014 16:10:52 +0000 Received: by mail-qg0-f48.google.com with SMTP id i50so6894419qgf.7 for ; Sat, 07 Jun 2014 09:10:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:in-reply-to:message-id :references:user-agent:mime-version:content-type; bh=WwgKERIC78pIv4s4ntFfPfxi8LrzO9sqWBH4FGpZceE=; b=PzZD2Uw+eqrjODHXQtKtiPYH/QWBYBsilF4DtFz569eCJewTlNnzub5kfoV+6coE7R AqK4qAwfgWVUyek39w3uNEgH64rUnKoziv0uPowMUwkA5UTecTt6FgjmOslc/GsyhAAX 0xrGZ5RVEj5m3Vs0ZliwXRNJRWlDfHxSyNoOrJ+d5QnNQ3gdy/AEmi5VGHLQZxhcf6mA Ed5Z8mxdgFxTANVcsDoLzAyeNW3tcdGQ57NtE2cTjnckp0dedUEFcQvqavMj/kF/Wjyg Oj5J9uvvGUspvas5Rc2cQhqjLM7RMTp0Sx1w0ZfObzQcCwNTY/J4OiJ+V04JDTPL28zn OxoA== X-Gm-Message-State: ALoCoQl558xFX+QywwpPEcKHkvhRS5loJxDSQYFZJQmVruCrai0/6iST4b3/BKzM35NGsG/etpgF X-Received: by 10.224.162.210 with SMTP id w18mr18199503qax.21.1402157429162; Sat, 07 Jun 2014 09:10:29 -0700 (PDT) Received: from xanadu.home (modemcable177.143-130-66.mc.videotron.ca. [66.130.143.177]) by mx.google.com with ESMTPSA id h78sm8018114qgd.10.2014.06.07.09.10.27 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 07 Jun 2014 09:10:28 -0700 (PDT) Date: Sat, 7 Jun 2014 12:10:27 -0400 (EDT) From: Nicolas Pitre To: Abhilash Kesavan Subject: Re: Problems booting exynos5420 with >1 CPU In-Reply-To: Message-ID: References: <539145B4.5000200@gmail.com> User-Agent: Alpine 2.11 (LFD 23 2013-08-11) MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140607_091051_365939_84706A25 X-CRM114-Status: GOOD ( 24.22 ) X-Spam-Score: -0.0 (/) Cc: Tushar Behera , "Turquette, Mike" , Kevin Hilman , Doug Anderson , linux-samsung-soc , Thomas Abraham , Arun Kumar , Olof Johansson , Sonny Rao , Javier Martinez Canillas , linux-arm-kernel 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-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, 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 On Sat, 7 Jun 2014, Abhilash Kesavan wrote: > Hi Nicolas, > > The first man of the incoming cluster enables its snoops via the > power_up_setup function. During secondary boot-up, this does not occur > for the boot cluster. Hence, I enable the snoops for the boot cluster > as a one-time setup from the u-boot prompt. After secondary boot-up > there is no modification that I do. OK that's good. > Where should this be ideally done ? If I remember correctly, the CCI can be safely activated only when the cache is disabled. So that means the CCI should ideally be turned on for the boot cluster (and *only* for the boot CPU) by the bootloader. Now... If you _really_ prefer to do it from the kernel to avoid difficulties with bootloader updates, then it should be possible to do it from the kernel by temporarily turning the cache off. This is not a small thing but the MCPM infrastructure can be leveraged. Here's what I tried on a TC2 which might just work for you as well: Of course it is not because I'm helping you sidestepping firmware problems that I'll stop shaming those who came up with that firmware design. ;-) Nicolas diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c index 86fd60fefb..1cc49de308 100644 --- a/arch/arm/common/mcpm_entry.c +++ b/arch/arm/common/mcpm_entry.c @@ -12,11 +12,13 @@ #include #include #include +#include #include #include #include #include +#include extern unsigned long mcpm_entry_vectors[MAX_NR_CLUSTERS][MAX_CPUS_PER_CLUSTER]; @@ -146,6 +148,44 @@ int mcpm_cpu_powered_up(void) return 0; } +static int go_down(unsigned long _arg) +{ + void (*cache_disable)(void) = (void *)_arg; + unsigned int mpidr = read_cpuid_mpidr(); + unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + phys_reset_t phys_reset; + + mcpm_set_entry_vector(cpu, cluster, cpu_resume); + setup_mm_for_reboot(); + + __mcpm_cpu_going_down(cpu, cluster); + BUG_ON(!__mcpm_outbound_enter_critical(cpu, cluster)); + cache_disable(); + __mcpm_outbound_leave_critical(cluster, CLUSTER_DOWN); + __mcpm_cpu_down(cpu, cluster); + + phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset); + phys_reset(virt_to_phys(mcpm_entry_point)); + BUG(); +} + +int mcpm_loopback(void (*cache_disable)(void)) +{ + int ret; + + local_irq_disable(); + local_fiq_disable(); + ret = cpu_pm_enter(); + if (!ret) { + ret = cpu_suspend((unsigned long)cache_disable, go_down); + cpu_pm_exit(); + } + local_fiq_enable(); + local_irq_enable(); + return ret; +} + struct sync_struct mcpm_sync; /* diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c index 29e7785a54..abecdd734f 100644 --- a/arch/arm/mach-vexpress/tc2_pm.c +++ b/arch/arm/mach-vexpress/tc2_pm.c @@ -323,6 +323,26 @@ static void __naked tc2_pm_power_up_setup(unsigned int affinity_level) " b cci_enable_port_for_self "); } +int mcpm_loopback(void (*cache_disable)(void)); + +static void tc2_cache_down(void) +{ + pr_warn("TC2: disabling cache\n"); + if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A15) { + /* + * On the Cortex-A15 we need to disable + * L2 prefetching before flushing the cache. + */ + asm volatile( + "mcr p15, 1, %0, c15, c0, 3 \n\t" + "isb \n\t" + "dsb " + : : "r" (0x400) ); + } + v7_exit_coherency_flush(all); + cci_disable_port_by_cpu(read_cpuid_mpidr()); +} + static int __init tc2_pm_init(void) { int ret, irq; @@ -370,6 +390,7 @@ static int __init tc2_pm_init(void) ret = mcpm_platform_register(&tc2_pm_power_ops); if (!ret) { mcpm_sync_init(tc2_pm_power_up_setup); + BUG_ON(mcpm_loopback(tc2_cache_down) != 0); pr_info("TC2 power management initialized\n"); } return ret;