From patchwork Thu Dec 20 09:44:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hiroshi Doyu X-Patchwork-Id: 207635 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 37F8B2C00F3 for ; Thu, 20 Dec 2012 20:46:42 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752202Ab2LTJqe (ORCPT ); Thu, 20 Dec 2012 04:46:34 -0500 Received: from hqemgate03.nvidia.com ([216.228.121.140]:14422 "EHLO hqemgate03.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750956Ab2LTJq0 (ORCPT ); Thu, 20 Dec 2012 04:46:26 -0500 Received: from hqnvupgp06.nvidia.com (Not Verified[216.228.121.13]) by hqemgate03.nvidia.com id ; Thu, 20 Dec 2012 01:49:07 -0800 Received: from hqemhub03.nvidia.com ([172.17.108.22]) by hqnvupgp06.nvidia.com (PGP Universal service); Thu, 20 Dec 2012 01:43:54 -0800 X-PGP-Universal: processed; by hqnvupgp06.nvidia.com on Thu, 20 Dec 2012 01:43:54 -0800 Received: from hqnvemgw02.nvidia.com (172.16.227.111) by HQEMHUB03.nvidia.com (172.20.150.15) with Microsoft SMTP Server id 8.3.279.1; Thu, 20 Dec 2012 01:45:31 -0800 Received: from daphne.nvidia.com (Not Verified[172.16.212.96]) by hqnvemgw02.nvidia.com with MailMarshal (v6,7,2,8378) id ; Thu, 20 Dec 2012 01:45:31 -0800 Received: from oreo.Nvidia.com (dhcp-10-21-25-186.nvidia.com [10.21.25.186]) by daphne.nvidia.com (8.13.8+Sun/8.8.8) with ESMTP id qBK9inJ6013509; Thu, 20 Dec 2012 01:45:27 -0800 (PST) From: Hiroshi Doyu To: CC: Hiroshi Doyu , Grant Likely , Rob Herring , Rob Landley , Russell King , Stephen Warren , John Stultz , Thomas Gleixner , Olof Johansson , Jason Cooper , Shawn Guo , Andrew Lunn , Jean-Christophe PLAGNIOL-VILLARD , , , , Subject: [PATCH 3/9] ARM: tegra: # of CPU cores detection w/ & w/o HAVE_ARM_SCU Date: Thu, 20 Dec 2012 11:44:01 +0200 Message-ID: <1355996654-6579-4-git-send-email-hdoyu@nvidia.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1355996654-6579-1-git-send-email-hdoyu@nvidia.com> References: <1355996654-6579-1-git-send-email-hdoyu@nvidia.com> MIME-Version: 1.0 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org The method to detect the number of CPU cores on Cortex-A9 MPCore and Cortex-A15 MPCore is different. On Cortex-A9 MPCore we can get this information from the Snoop Control Unit(SCU). On Cortex-A15 MPCore we have to read it from the system coprocessor(CP15), because the SCU on Cortex-A15 MPCore does not have software readable registers. This patch selects the correct method at runtime based on the CPU ID. Signed-off-by: Hiroshi Doyu --- arch/arm/mach-tegra/platsmp.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index 1b926df..68e76ef 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -34,9 +35,13 @@ #include "common.h" #include "iomap.h" +#define CPU_MASK 0xff0ffff0 +#define CPU_CORTEX_A9 0x410fc090 +#define CPU_CORTEX_A15 0x410fc0f0 + extern void tegra_secondary_startup(void); -static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE); +static void __iomem *scu_base; #define EVP_CPU_RESET_VECTOR \ (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100) @@ -149,7 +154,26 @@ done: */ static void __init tegra_smp_init_cpus(void) { - unsigned int i, ncores = scu_get_core_count(scu_base); + unsigned int i, cpu_id, ncores; + u32 l2ctlr; + phys_addr_t pa; + + cpu_id = read_cpuid(CPUID_ID) & CPU_MASK; + switch (cpu_id) { + case CPU_CORTEX_A15: + asm("mrc p15, 1, %0, c9, c0, 2\n" : "=r" (l2ctlr)); + ncores = ((l2ctlr >> 24) & 3) + 1; + break; + case CPU_CORTEX_A9: + /* Get SCU physical base */ + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (pa)); + scu_base = IO_ADDRESS(pa); + ncores = scu_get_core_count(scu_base); + break; + default: + BUG(); + break; + } if (ncores > nr_cpu_ids) { pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", @@ -166,7 +190,8 @@ static void __init tegra_smp_init_cpus(void) static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) { tegra_cpu_reset_handler_init(); - scu_enable(scu_base); + if (scu_base) + scu_enable(scu_base); } struct smp_operations tegra_smp_ops __initdata = {