From patchwork Thu Dec 20 02:30:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Lo X-Patchwork-Id: 1898321 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 3FCF83FC81 for ; Thu, 20 Dec 2012 02:33:50 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TlVtt-0005Yl-03; Thu, 20 Dec 2012 02:30:21 +0000 Received: from hqemgate04.nvidia.com ([216.228.121.35]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TlVto-0005X6-5j for linux-arm-kernel@lists.infradead.org; Thu, 20 Dec 2012 02:30:16 +0000 Received: from hqnvupgp06.nvidia.com (Not Verified[216.228.121.13]) by hqemgate04.nvidia.com id ; Wed, 19 Dec 2012 18:29:53 -0800 Received: from hqemhub03.nvidia.com ([172.17.108.22]) by hqnvupgp06.nvidia.com (PGP Universal service); Wed, 19 Dec 2012 18:28:36 -0800 X-PGP-Universal: processed; by hqnvupgp06.nvidia.com on Wed, 19 Dec 2012 18:28:36 -0800 Received: from localhost.localdomain (172.20.144.16) by hqemhub03.nvidia.com (172.20.150.15) with Microsoft SMTP Server (TLS) id 8.3.279.1; Wed, 19 Dec 2012 18:30:11 -0800 From: Joseph Lo To: Stephen Warren Subject: [PATCH] ARM: tegra30: fix power up sequence for boot_secondary Date: Thu, 20 Dec 2012 10:30:03 +0800 Message-ID: <1355970603-28531-1-git-send-email-josephl@nvidia.com> X-Mailer: git-send-email 1.7.0.4 X-NVConfidentiality: public MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20121219_213016_449534_9E1865D8 X-CRM114-Status: GOOD ( 18.90 ) X-Spam-Score: -7.6 (-------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-7.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [216.228.121.35 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: linux-tegra@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Joseph Lo X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org The power up sequence is different on the cold boot CPU and the CPU that resumed from the hotplug. For the cold boot CPU, it was been power gated as default. To power up the cold boot CPU, the power should be un-gated by un toggling the power gate register manually. For the CPU that resumed from the hotplug, after un-halted the CPU. The flow controller will un-gate the power of the CPU. No need to manually control, just wait the power be resumed and continue the power up sequence after the CPU power is ready. Based on the work by: Varun Wadekar Signed-off-by: Joseph Lo Acked-by: Peter De Schrijver --- arch/arm/mach-tegra/platsmp.c | 31 ++++++++++++++++++++++++++++++- 1 files changed, 30 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 6cedb3e..9bd4898 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -36,6 +37,7 @@ extern void tegra_secondary_startup(void); +static cpumask_t tegra_cpu_init_mask; static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); #define EVP_CPU_RESET_VECTOR \ @@ -50,6 +52,7 @@ static void __cpuinit tegra_secondary_init(unsigned int cpu) */ gic_secondary_init(0); + cpumask_set_cpu(cpu, &tegra_cpu_init_mask); } static int tegra20_power_up_cpu(unsigned int cpu) @@ -72,7 +75,27 @@ static int tegra30_power_up_cpu(unsigned int cpu) if (pwrgateid < 0) return pwrgateid; - /* If this is the first boot, toggle powergates directly. */ + /* + * If the CPU had booted and went through here after CPU + * had been already un-gated by flow controller. Wait + * for confirmation that the CPU is powered then remove + * the IO clamps. On the cold boot entry, do not wait. + */ + if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { + timeout = jiffies + 5; + do { + if (!tegra_powergate_is_powered(pwrgateid)) + goto remove_clamps; + udelay(10); + } while (time_before(jiffies, timeout)); + } + + /* + * The power status of the cold boot CPU is power gating as + * default. To power up the cold boot CPU, the power should + * be un-gated by un-toggling the power gate register + * manually. + */ if (!tegra_powergate_is_powered(pwrgateid)) { ret = tegra_powergate_power_on(pwrgateid); if (ret) @@ -87,6 +110,7 @@ static int tegra30_power_up_cpu(unsigned int cpu) } } +remove_clamps: /* CPU partition is powered. Enable the CPU clock. */ tegra_enable_cpu_clock(cpu); udelay(10); @@ -105,6 +129,8 @@ static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct * { int status; + cpu = cpu_logical_map(cpu); + /* * Force the CPU into reset. The CPU must remain in reset when the * flow controller state is cleared (which will cause the flow @@ -165,6 +191,9 @@ static void __init tegra_smp_init_cpus(void) static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) { + /* Always mark the boot CPU (CPU0) as initialized. */ + cpumask_set_cpu(0, &tegra_cpu_init_mask); + tegra_cpu_reset_handler_init(); scu_enable(scu_base); }