From patchwork Tue Dec 14 07:57:11 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 409041 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBE7rXcD016319 for ; Tue, 14 Dec 2010 07:53:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752912Ab0LNHxc (ORCPT ); Tue, 14 Dec 2010 02:53:32 -0500 Received: from mail-pz0-f46.google.com ([209.85.210.46]:44163 "EHLO mail-pz0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752542Ab0LNHxb (ORCPT ); Tue, 14 Dec 2010 02:53:31 -0500 Received: by pzk6 with SMTP id 6so54772pzk.19 for ; Mon, 13 Dec 2010 23:53:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:date:message-id :in-reply-to:references:subject; bh=wi9bexy1dap/jYIZnvL7qF2x2U+P+rizr/K8EdAzMws=; b=w1Cqutn92zd6si6hf8F4am4O1FHHpURlmBeWL9CAuk30JOlmi1ga2S4aaiu87WgkH0 FE3tZdKHPTSdv28OcrYTKbIEPIdgHA24Fip/pRvFpXdwcCC5AyswbxksNOTEBIbQ4m8r uXQ2Qd+w4QRLcm1o5hsT8avQ3OkVyyCuNsCQQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:date:message-id:in-reply-to:references:subject; b=e9D11ZJYpZG/rEk4mUq/RiRmODCCsJIBX+bQoGqP4zSwy2JNxiwrhMGw92wHDe7LoM neTkoFNJ8oJkFc9m1sY3EFmWNXSrtEKWehLssVuut3KahOPtqG3ZXHDPoFpUe1X7vQ/V hSYD8gPC9zCs4ngz/qht9asMi8kv5Cd8xvlV8= Received: by 10.142.156.15 with SMTP id d15mr2516799wfe.394.1292313211229; Mon, 13 Dec 2010 23:53:31 -0800 (PST) Received: from [127.0.0.1] (49.14.32.202.bf.2iij.net [202.32.14.49]) by mx.google.com with ESMTPS id w42sm10020540wfh.3.2010.12.13.23.53.29 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 13 Dec 2010 23:53:30 -0800 (PST) From: Magnus Damm To: linux-sh@vger.kernel.org Cc: Magnus Damm , lethal@linux-sh.org, linux@arm.linux.org.uk, linux-arm-kernel@lists.infradead.org Date: Tue, 14 Dec 2010 16:57:11 +0900 Message-Id: <20101214075711.11275.31475.sendpatchset@t400s> In-Reply-To: <20101214075647.11275.25933.sendpatchset@t400s> References: <20101214075647.11275.25933.sendpatchset@t400s> Subject: [PATCH 03/03] ARM: mach-shmobile: sh73a0 SMP support Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 14 Dec 2010 07:53:33 +0000 (UTC) --- 0007/arch/arm/mach-shmobile/Makefile +++ work/arch/arm/mach-shmobile/Makefile 2010-12-14 14:36:41.000000000 +0900 @@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_SH73A0) += setup-sh73a smp-y := platsmp.o headsmp.o smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o +smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o # Pinmux setup pfc-y := --- 0007/arch/arm/mach-shmobile/include/mach/common.h +++ work/arch/arm/mach-shmobile/include/mach/common.h 2010-12-14 14:36:41.000000000 +0900 @@ -38,4 +38,9 @@ extern void sh73a0_pinmux_init(void); extern struct clk sh73a0_extal1_clk; extern struct clk sh73a0_extal2_clk; +extern unsigned int sh73a0_get_core_count(void); +extern void sh73a0_secondary_init(unsigned int cpu); +extern int sh73a0_boot_secondary(unsigned int cpu); +extern void sh73a0_smp_prepare_cpus(void); + #endif /* __ARCH_MACH_COMMON_H */ --- 0007/arch/arm/mach-shmobile/platsmp.c +++ work/arch/arm/mach-shmobile/platsmp.c 2010-12-14 14:36:41.000000000 +0900 @@ -16,25 +16,37 @@ #include #include #include +#include +#include static unsigned int __init shmobile_smp_get_core_count(void) { + if (machine_is_ag5evm()) + return sh73a0_get_core_count(); + return 1; } static void __init shmobile_smp_prepare_cpus(void) { - /* do nothing for now */ + if (machine_is_ag5evm()) + sh73a0_smp_prepare_cpus(); } void __cpuinit platform_secondary_init(unsigned int cpu) { trace_hardirqs_off(); + + if (machine_is_ag5evm()) + sh73a0_secondary_init(cpu); } int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { + if (machine_is_ag5evm()) + return sh73a0_boot_secondary(cpu); + return -ENOSYS; } --- /dev/null +++ work/arch/arm/mach-shmobile/smp-sh73a0.c 2010-12-14 14:40:54.000000000 +0900 @@ -0,0 +1,98 @@ +/* + * SMP support for R-Mobile / SH-Mobile - sh73a0 portion + * + * Copyright (C) 2010 Magnus Damm + * Copyright (C) 2010 Takashi Yoshii + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WUPCR 0xe6151010 +#define SRESCR 0xe6151018 +#define PSTR 0xe6151040 +#define SBAR 0xe6180020 +#define APARMBAREA 0xe6f10020 + +static void __iomem *scu_base_addr(void) +{ + return (void __iomem *)0xf0000000; +} + +static DEFINE_SPINLOCK(scu_lock); +static unsigned long tmp; + +static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) +{ + void __iomem *scu_base = scu_base_addr(); + + spin_lock(&scu_lock); + tmp = __raw_readl(scu_base + 8); + tmp &= ~clr; + tmp |= set; + spin_unlock(&scu_lock); + + /* disable cache coherency after releasing the lock */ + __raw_writel(tmp, scu_base + 8); +} + +unsigned int __init sh73a0_get_core_count(void) +{ + void __iomem *scu_base = scu_base_addr(); + + return scu_get_core_count(scu_base); +} + +void __cpuinit sh73a0_secondary_init(unsigned int cpu) +{ + gic_cpu_init(0, __io(0xf0000100)); +} + +int __cpuinit sh73a0_boot_secondary(unsigned int cpu) +{ + /* enable cache coherency */ + modify_scu_cpu_psr(0, 3 << (cpu * 8)); + + if (((__raw_readw(__io(PSTR)) >> (4 * cpu)) & 3) == 3) + __raw_writel(1 << cpu, __io(WUPCR)); /* wake up */ + else + __raw_writel(1 << cpu, __io(SRESCR)); /* reset */ + + return 0; +} + +void __init sh73a0_smp_prepare_cpus(void) +{ +#ifdef CONFIG_HAVE_ARM_TWD + twd_base = (void __iomem *)0xf0000600; +#endif + + scu_enable(scu_base_addr()); + + /* Map the reset vector (in headsmp.S) */ + __raw_writel(0, __io(APARMBAREA)); /* 4k */ + __raw_writel(__pa(shmobile_secondary_vector), __io(SBAR)); + + /* enable cache coherency on CPU0 */ + modify_scu_cpu_psr(0, 3 << (0 * 8)); +} +