linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/05] ARM: shmobile: r8a73a4 SMP and CPU Hotplug prototype v2
@ 2013-05-30  8:51 Magnus Damm
  2013-05-30  8:52 ` [PATCH 01/05] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4) Magnus Damm
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Magnus Damm @ 2013-05-30  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

ARM: shmobile: r8a73a4 SMP and CPU Hotplug prototype v2

[PATCH 01/05] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4)
[PATCH 02/05] ARM: shmobile: r8a73a4 CPU Hotplug prototype v1 (CA15 x 4)
[PATCH 03/05] ARM: shmobile: r8a73a4 CA15 setup WFE as NOP
[PATCH 04/05] ARM: shmobile: r8a73a4 SMP CA7 prototype (+ CA7 x 4)
[PATCH 05/05] ARM: shmobile: r8a73a4 CA7 setup arch timer

Here's V2 of r8a73a4 SMP prototype support. This time support for
both CA15 and CA7 is included.

It is worth noting that only prototype support for the actual SoC
is included here. It is included as SMP support, but since CA7 cores
perform differently compared to CA15 the system will not behave in a
deterministic way unless either big.LITTLE MP patches are used to
extend the scheduler or c-groups are used to separate CA15 and CA7.

All 8 cores boot up as expected but certainly needs more work.

Not-yet-Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Written against linux.git 7b55eab81ecbbd44e76ac14c67479b82807c261b
 
 arch/arm/boot/dts/r8a73a4.dtsi                |   49 ++++
 arch/arm/mach-shmobile/Makefile               |    1 
 arch/arm/mach-shmobile/board-ape6evm.c        |    1 
 arch/arm/mach-shmobile/include/mach/r8a73a4.h |    1 
 arch/arm/mach-shmobile/setup-r8a73a4.c        |    1 
 arch/arm/mach-shmobile/smp-r8a73a4.c          |  274 ++++++++++++++++++++++++-
 6 files changed, 321 insertions(+), 6 deletions(-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 01/05] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4)
  2013-05-30  8:51 [PATCH 00/05] ARM: shmobile: r8a73a4 SMP and CPU Hotplug prototype v2 Magnus Damm
@ 2013-05-30  8:52 ` Magnus Damm
  2013-06-05  8:29   ` Shinya Kuribayashi
  2013-05-30  8:52 ` [PATCH 02/05] ARM: shmobile: r8a73a4 CPU Hotplug " Magnus Damm
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Magnus Damm @ 2013-05-30  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Magnus Damm <damm@opensource.se>

Add SMP prototype support for r8a73a4 by enabling
4 x Cortex-A15. This patch only adds support for
booting, see the incremental patch for CPU Hotplug.

Needs a rewrite to support more generic handling of
CPU core power domains. Not ready for merge.

Not-yet-Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Developed and tested on top of v3.10-rc2

 arch/arm/boot/dts/r8a73a4.dtsi                |   21 +++++
 arch/arm/mach-shmobile/Makefile               |    1 
 arch/arm/mach-shmobile/board-ape6evm.c        |    1 
 arch/arm/mach-shmobile/include/mach/r8a73a4.h |    1 
 arch/arm/mach-shmobile/setup-r8a73a4.c        |    1 
 arch/arm/mach-shmobile/smp-r8a73a4.c          |   89 +++++++++++++++++++++++++
 6 files changed, 114 insertions(+)

--- 0003/arch/arm/boot/dts/r8a73a4.dtsi
+++ work/arch/arm/boot/dts/r8a73a4.dtsi	2013-05-22 13:21:21.000000000 +0900
@@ -25,6 +25,27 @@
 			reg = <0>;
 			clock-frequency = <1500000000>;
 		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <1>;
+			clock-frequency = <1500000000>;
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <2>;
+			clock-frequency = <1500000000>;
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a15";
+			reg = <3>;
+			clock-frequency = <1500000000>;
+		};
 	};
 
 	gic: interrupt-controller at f1001000 {
--- 0001/arch/arm/mach-shmobile/Makefile
+++ work/arch/arm/mach-shmobile/Makefile	2013-05-22 13:21:21.000000000 +0900
@@ -18,6 +18,7 @@ obj-$(CONFIG_ARCH_EMEV2)	+= setup-emev2.
 # SMP objects
 smp-y				:= platsmp.o headsmp.o
 smp-$(CONFIG_ARCH_SH73A0)	+= smp-sh73a0.o headsmp-scu.o
+smp-$(CONFIG_ARCH_R8A73A4)	+= smp-r8a73a4.o
 smp-$(CONFIG_ARCH_R8A7779)	+= smp-r8a7779.o headsmp-scu.o
 smp-$(CONFIG_ARCH_EMEV2)	+= smp-emev2.o headsmp-scu.o
 
--- 0001/arch/arm/mach-shmobile/board-ape6evm.c
+++ work/arch/arm/mach-shmobile/board-ape6evm.c	2013-05-22 13:21:51.000000000 +0900
@@ -87,6 +87,7 @@ static const char *ape6evm_boards_compat
 };
 
 DT_MACHINE_START(APE6EVM_DT, "ape6evm")
+	.smp		= smp_ops(r8a73a4_smp_ops),
 	.init_irq	= irqchip_init,
 	.init_time	= shmobile_timer_init,
 	.init_machine	= ape6evm_add_standard_devices,
--- 0001/arch/arm/mach-shmobile/include/mach/r8a73a4.h
+++ work/arch/arm/mach-shmobile/include/mach/r8a73a4.h	2013-05-22 13:21:21.000000000 +0900
@@ -4,5 +4,6 @@
 void r8a73a4_add_standard_devices(void);
 void r8a73a4_clock_init(void);
 void r8a73a4_pinmux_init(void);
+extern struct smp_operations r8a73a4_smp_ops;
 
 #endif /* __ASM_R8A73A4_H__ */
--- 0001/arch/arm/mach-shmobile/setup-r8a73a4.c
+++ work/arch/arm/mach-shmobile/setup-r8a73a4.c	2013-05-22 13:21:44.000000000 +0900
@@ -194,6 +194,7 @@ static const char *r8a73a4_boards_compat
 };
 
 DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)")
+	.smp		= smp_ops(r8a73a4_smp_ops),
 	.init_irq	= irqchip_init,
 	.init_machine	= r8a73a4_add_standard_devices_dt,
 	.init_time	= shmobile_timer_init,
--- /dev/null
+++ work/arch/arm/mach-shmobile/smp-r8a73a4.c	2013-05-22 13:21:21.000000000 +0900
@@ -0,0 +1,89 @@
+/*
+ * SMP support for r8a73a4
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@renesas.com>
+ *
+ * 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.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/irqchip/arm-gic.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/smp_plat.h>
+#include <asm/suspend.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+#include <asm/cacheflush.h>
+#include <asm/cp15.h>
+#include <asm/smp_plat.h>
+
+#define SYSC	0xe6180000
+#define CA15BAR	0x6020
+#define RESCNT	0x801c
+
+#define APMU	0xe6150000
+#define CA15WUPCR 0x2010
+
+#define MERAM	0xe8080000
+#define CCI_BASE	0xf0190000
+#define CCI_SLAVE3	0x4000
+#define CCI_SNOOP	0x0000
+#define CCI_STATUS	0x000c
+
+static void __init r8a73a4_smp_prepare_cpus(unsigned int max_cpus)
+{
+	u32 bar;
+	void __iomem *p;
+
+	/* MERAM for jump stub, because BAR requires 256KB aligned address */
+	p = ioremap_nocache(MERAM, 16);
+	memcpy(p, shmobile_secondary_vector, 16);
+	iounmap(p);
+
+	flush_cache_louis();
+
+	/* setup reset vector and disable reset */
+	p = ioremap_nocache(SYSC, 0x9000);
+	bar = (MERAM >> 8) & 0xfffffc00;
+	__raw_writel(bar, p + CA15BAR);
+	__raw_writel(bar | 0x10, p + CA15BAR);
+	__raw_writel(__raw_readl(p + RESCNT) & ~(1 << 10), p + RESCNT);
+	iounmap(p);
+
+	/* enable snoop and DVM */
+	p = ioremap_nocache(CCI_BASE, 0x8000);
+	__raw_writel(3, p + CCI_SLAVE3 + CCI_SNOOP);	/* ca15 */
+	while (__raw_readl(p + CCI_STATUS))
+		/* wait for pending bit low */;
+	iounmap(p);
+}
+
+static int __cpuinit r8a73a4_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+	void __iomem *p;
+
+	/* wake up CPU core */
+	p = ioremap_nocache(APMU, 0x3000);
+	__raw_writel(1 << (cpu_logical_map(cpu) & 3), p + CA15WUPCR);
+	iounmap(p);
+
+	return 0;
+}
+
+struct smp_operations r8a73a4_smp_ops __initdata = {
+	.smp_prepare_cpus	= r8a73a4_smp_prepare_cpus,
+	.smp_boot_secondary	= r8a73a4_boot_secondary,
+};

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 02/05] ARM: shmobile: r8a73a4 CPU Hotplug prototype v1 (CA15 x 4)
  2013-05-30  8:51 [PATCH 00/05] ARM: shmobile: r8a73a4 SMP and CPU Hotplug prototype v2 Magnus Damm
  2013-05-30  8:52 ` [PATCH 01/05] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4) Magnus Damm
@ 2013-05-30  8:52 ` Magnus Damm
  2013-05-30  8:52 ` [PATCH 03/05] ARM: shmobile: r8a73a4 CA15 setup WFE as NOP Magnus Damm
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Magnus Damm @ 2013-05-30  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Magnus Damm <damm@opensource.se>

Add CPU Hotplug prototype support for 4 x Cortex-A15
included in r8a73a4.

Needs a rewrite to support more generic handling of
CPU core power domains. Not ready for merge.

Not-yet-Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Developed and tested on top of v3.10-rc2, depends on
 "[PATCH] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4)"

 arch/arm/mach-shmobile/smp-r8a73a4.c |   88 ++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

--- 0005/arch/arm/mach-shmobile/smp-r8a73a4.c
+++ work/arch/arm/mach-shmobile/smp-r8a73a4.c	2013-05-22 13:34:18.000000000 +0900
@@ -36,6 +36,8 @@
 
 #define APMU	0xe6150000
 #define CA15WUPCR 0x2010
+#define CA15PSTR 0x2040
+#define CA15CPUNCR(n) (0x2100 + (0x10 * (n))) 
 
 #define MERAM	0xe8080000
 #define CCI_BASE	0xf0190000
@@ -83,7 +85,93 @@ static int __cpuinit r8a73a4_boot_second
 	return 0;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int r8a73a4_cpu_kill(unsigned int cpu)
+{
+	void __iomem *p;
+	int ret = 0;
+	int k;
+
+	/* this function is running on another CPU than the offline target,
+	 * here all we need to do is to wait for the SoC to enter sleep mode.
+	 */
+	p = ioremap_nocache(APMU, 0x3000);
+	for (k = 0; k < 1000; k++) {
+		if (((__raw_readl(p + CA15PSTR) >> (cpu * 4)) & 0x03) == 3) {
+			ret = 1;
+			break;
+		}
+
+		mdelay(1);
+	}
+	iounmap(p);
+
+	return ret;
+}
+
+/* nicked from arch/arm/mach-exynos/hotplug.c */
+static inline void cpu_enter_lowpower_a15(void)
+{
+	unsigned int v;
+
+	asm volatile(
+	"	mrc	p15, 0, %0, c1, c0, 0\n"
+	"	bic	%0, %0, %1\n"
+	"	mcr	p15, 0, %0, c1, c0, 0\n"
+	  : "=&r" (v)
+	  : "Ir" (CR_C)
+	  : "cc");
+
+	flush_cache_louis();
+
+	asm volatile(
+	/*
+	* Turn off coherency
+	*/
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	bic	%0, %0, %1\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	: "=&r" (v)
+	: "Ir" (0x40)
+	: "cc");
+
+	isb();
+	dsb();
+}
+
+static int r8a73a4_do_idle_core_standby(unsigned long unused)
+{
+	cpu_do_idle(); /* WFI triggers Core Standby */
+	return 0;
+}
+
+static void r8a73a4_cpu_die(unsigned int cpu)
+{
+	void __iomem *p;
+
+	/* hardware shutdown code running on the CPU that is being offlined */
+
+	/* select CPU shutdown mode */
+	p = ioremap_nocache(APMU, 0x3000);
+	__raw_writel(3, p + CA15CPUNCR(cpu)); /* CA15 Core Standby */
+	iounmap(p);
+
+	cpu_enter_lowpower_a15();
+	cpu_suspend(0, r8a73a4_do_idle_core_standby); /* really needed? */
+}
+
+static int r8a73a4_cpu_disable(unsigned int cpu)
+{
+	return 0; /* hotplug of any CPU is tested OK */
+}
+#endif
+
 struct smp_operations r8a73a4_smp_ops __initdata = {
 	.smp_prepare_cpus	= r8a73a4_smp_prepare_cpus,
 	.smp_boot_secondary	= r8a73a4_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+	.cpu_kill		= r8a73a4_cpu_kill,
+	.cpu_die		= r8a73a4_cpu_die,
+	.cpu_disable		= r8a73a4_cpu_disable,
+#endif
 };

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 03/05] ARM: shmobile: r8a73a4 CA15 setup WFE as NOP
  2013-05-30  8:51 [PATCH 00/05] ARM: shmobile: r8a73a4 SMP and CPU Hotplug prototype v2 Magnus Damm
  2013-05-30  8:52 ` [PATCH 01/05] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4) Magnus Damm
  2013-05-30  8:52 ` [PATCH 02/05] ARM: shmobile: r8a73a4 CPU Hotplug " Magnus Damm
@ 2013-05-30  8:52 ` Magnus Damm
  2013-05-30  8:52 ` [PATCH 04/05] ARM: shmobile: r8a73a4 SMP CA7 prototype (+ CA7 x 4) Magnus Damm
  2013-05-30  8:52 ` [PATCH 05/05] ARM: shmobile: r8a73a4 CA7 setup arch timer Magnus Damm
  4 siblings, 0 replies; 7+ messages in thread
From: Magnus Damm @ 2013-05-30  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Magnus Damm <damm@opensource.se>

Configure CA15 included in r8a73a4 to treat WFE as NOP.

This works around hardware issue found in APE6, needed
for CA7 cluster to work together with CA15 cluster.

Not-yet-Signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/smp-r8a73a4.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

--- 0006/arch/arm/mach-shmobile/smp-r8a73a4.c
+++ work/arch/arm/mach-shmobile/smp-r8a73a4.c	2013-05-22 14:16:59.000000000 +0900
@@ -45,6 +45,20 @@
 #define CCI_SNOOP	0x0000
 #define CCI_STATUS	0x000c
 
+static inline void r8a73a4_execute_wfe_as_nop(void)
+{
+	unsigned int v;
+
+	/* set bit 7 in ACTLR */
+	asm volatile(
+	"	mrc	p15, 0, %0, c1, c0, 1\n"
+	"	orr	%0, %0, #0x40\n"
+	"	mcr	p15, 0, %0, c1, c0, 1\n"
+	  : "=&r" (v)
+	  :
+	  : "cc");
+}
+
 static void __init r8a73a4_smp_prepare_cpus(unsigned int max_cpus)
 {
 	u32 bar;
@@ -71,6 +85,8 @@ static void __init r8a73a4_smp_prepare_c
 	while (__raw_readl(p + CCI_STATUS))
 		/* wait for pending bit low */;
 	iounmap(p);
+
+	r8a73a4_execute_wfe_as_nop();
 }
 
 static int __cpuinit r8a73a4_boot_secondary(unsigned int cpu, struct task_struct *idle)
@@ -85,6 +101,13 @@ static int __cpuinit r8a73a4_boot_second
 	return 0;
 }
 
+static void __cpuinit r8a73a4_secondary_init(unsigned int cpu)
+{
+	/* CA15 need SW workaround */
+	if (cpu_logical_map(cpu) < 4)
+		r8a73a4_execute_wfe_as_nop();
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static int r8a73a4_cpu_kill(unsigned int cpu)
 {
@@ -169,6 +192,7 @@ static int r8a73a4_cpu_disable(unsigned
 struct smp_operations r8a73a4_smp_ops __initdata = {
 	.smp_prepare_cpus	= r8a73a4_smp_prepare_cpus,
 	.smp_boot_secondary	= r8a73a4_boot_secondary,
+	.smp_secondary_init	= r8a73a4_secondary_init,
 #ifdef CONFIG_HOTPLUG_CPU
 	.cpu_kill		= r8a73a4_cpu_kill,
 	.cpu_die		= r8a73a4_cpu_die,

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 04/05] ARM: shmobile: r8a73a4 SMP CA7 prototype (+ CA7 x 4)
  2013-05-30  8:51 [PATCH 00/05] ARM: shmobile: r8a73a4 SMP and CPU Hotplug prototype v2 Magnus Damm
                   ` (2 preceding siblings ...)
  2013-05-30  8:52 ` [PATCH 03/05] ARM: shmobile: r8a73a4 CA15 setup WFE as NOP Magnus Damm
@ 2013-05-30  8:52 ` Magnus Damm
  2013-05-30  8:52 ` [PATCH 05/05] ARM: shmobile: r8a73a4 CA7 setup arch timer Magnus Damm
  4 siblings, 0 replies; 7+ messages in thread
From: Magnus Damm @ 2013-05-30  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Magnus Damm <damm@opensource.se>

Prototype code to enable 4 x CA7 found in r8a73a4.

To test on APE6EVM boot with maxcpus=4 and use CPU Hotplug
for boot and shut down. Not ready for merge.

Not-yet-Signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/boot/dts/r8a73a4.dtsi       |   28 ++++++++++++++++++++++++++
 arch/arm/mach-shmobile/smp-r8a73a4.c |   36 +++++++++++++++++++++++++++++-----
 2 files changed, 59 insertions(+), 5 deletions(-)

--- 0002/arch/arm/boot/dts/r8a73a4.dtsi
+++ work/arch/arm/boot/dts/r8a73a4.dtsi	2013-05-30 16:13:11.000000000 +0900
@@ -46,6 +46,34 @@
 			reg = <3>;
 			clock-frequency = <1500000000>;
 		};
+
+		cpu4: cpu at 4 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x100>;
+			clock-frequency = <1000000000>; 
+		};
+
+		cpu5: cpu at 5 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x101>;
+			clock-frequency = <1000000000>; 
+		};
+
+		cpu6: cpu at 6 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x102>;
+			clock-frequency = <1000000000>; 
+		};
+
+		cpu7: cpu at 7 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0x103>;
+			clock-frequency = <1000000000>; 
+		};
 	};
 
 	gic: interrupt-controller at f1001000 {
--- 0004/arch/arm/mach-shmobile/smp-r8a73a4.c
+++ work/arch/arm/mach-shmobile/smp-r8a73a4.c	2013-05-30 16:18:40.000000000 +0900
@@ -31,17 +31,22 @@
 #include <asm/smp_plat.h>
 
 #define SYSC	0xe6180000
+#define CA7BAR	0x4020
 #define CA15BAR	0x6020
 #define RESCNT	0x801c
 
 #define APMU	0xe6150000
+#define CA7WUPCR 0x1010
 #define CA15WUPCR 0x2010
+#define CA7PSTR	0x1040
 #define CA15PSTR 0x2040
+#define CA7CPUNCR(n) (0x1100 + (0x10 * (n))) 
 #define CA15CPUNCR(n) (0x2100 + (0x10 * (n))) 
 
 #define MERAM	0xe8080000
 #define CCI_BASE	0xf0190000
 #define CCI_SLAVE3	0x4000
+#define CCI_SLAVE4	0x5000
 #define CCI_SNOOP	0x0000
 #define CCI_STATUS	0x000c
 
@@ -75,13 +80,16 @@ static void __init r8a73a4_smp_prepare_c
 	p = ioremap_nocache(SYSC, 0x9000);
 	bar = (MERAM >> 8) & 0xfffffc00;
 	__raw_writel(bar, p + CA15BAR);
+	__raw_writel(bar, p + CA7BAR);
 	__raw_writel(bar | 0x10, p + CA15BAR);
+	__raw_writel(bar | 0x10, p + CA7BAR);
 	__raw_writel(__raw_readl(p + RESCNT) & ~(1 << 10), p + RESCNT);
 	iounmap(p);
 
 	/* enable snoop and DVM */
 	p = ioremap_nocache(CCI_BASE, 0x8000);
 	__raw_writel(3, p + CCI_SLAVE3 + CCI_SNOOP);	/* ca15 */
+	__raw_writel(3, p + CCI_SLAVE4 + CCI_SNOOP);	/* ca7 */
 	while (__raw_readl(p + CCI_STATUS))
 		/* wait for pending bit low */;
 	iounmap(p);
@@ -92,10 +100,14 @@ static void __init r8a73a4_smp_prepare_c
 static int __cpuinit r8a73a4_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	void __iomem *p;
+	int cluster_cpu = cpu_logical_map(cpu) & 3;
 
 	/* wake up CPU core */
 	p = ioremap_nocache(APMU, 0x3000);
-	__raw_writel(1 << (cpu_logical_map(cpu) & 3), p + CA15WUPCR);
+	if (cpu_logical_map(cpu) < 4) 
+		__raw_writel(1 << cluster_cpu, p + CA15WUPCR);
+	else
+		__raw_writel(1 << cluster_cpu, p + CA7WUPCR);
 	iounmap(p);
 
 	return 0;
@@ -112,6 +124,7 @@ static void __cpuinit r8a73a4_secondary_
 static int r8a73a4_cpu_kill(unsigned int cpu)
 {
 	void __iomem *p;
+	int offs;
 	int ret = 0;
 	int k;
 
@@ -120,9 +133,18 @@ static int r8a73a4_cpu_kill(unsigned int
 	 */
 	p = ioremap_nocache(APMU, 0x3000);
 	for (k = 0; k < 1000; k++) {
-		if (((__raw_readl(p + CA15PSTR) >> (cpu * 4)) & 0x03) == 3) {
-			ret = 1;
-			break;
+		if (cpu < 4) { /* CA15 Core Standby */
+			offs = cpu * 4;
+			if (((__raw_readl(p + CA15PSTR) >> offs) & 0x03) == 3) {
+				ret = 1;
+				break;
+			}
+		} else { /* CA7 Core Standby */
+			offs = (cpu - 4) * 4;
+			if (((__raw_readl(p + CA7PSTR) >> offs) & 0x03) == 3) {
+				ret = 1;
+				break;
+			}
 		}
 
 		mdelay(1);
@@ -176,7 +198,11 @@ static void r8a73a4_cpu_die(unsigned int
 
 	/* select CPU shutdown mode */
 	p = ioremap_nocache(APMU, 0x3000);
-	__raw_writel(3, p + CA15CPUNCR(cpu)); /* CA15 Core Standby */
+	if (cpu < 4)
+		__raw_writel(3, p + CA15CPUNCR(cpu)); /* CA15 Core Standby */
+	else
+		__raw_writel(3, p + CA7CPUNCR(cpu - 4)); /* CA7 Core Standby */
+
 	iounmap(p);
 
 	cpu_enter_lowpower_a15();

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 05/05] ARM: shmobile: r8a73a4 CA7 setup arch timer
  2013-05-30  8:51 [PATCH 00/05] ARM: shmobile: r8a73a4 SMP and CPU Hotplug prototype v2 Magnus Damm
                   ` (3 preceding siblings ...)
  2013-05-30  8:52 ` [PATCH 04/05] ARM: shmobile: r8a73a4 SMP CA7 prototype (+ CA7 x 4) Magnus Damm
@ 2013-05-30  8:52 ` Magnus Damm
  4 siblings, 0 replies; 7+ messages in thread
From: Magnus Damm @ 2013-05-30  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

From: Magnus Damm <damm@opensource.se>

Setup the CA7 arch timer in r8a73a4 at boot up. Thanks to
Kevin Bracey at Renesas Mobile for initial implementation.

We need to discuss if some of this can be moved into the
common arch timer driver or not. It may also need to be
shared with R-Car H2. So this is not ready for merge.

Without this patch the interrupt count for the per-cpu arch
timers for CA7 are stuck at zero.

Not-yet-Signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/smp-r8a73a4.c |   37 +++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

--- 0005/arch/arm/mach-shmobile/smp-r8a73a4.c
+++ work/arch/arm/mach-shmobile/smp-r8a73a4.c	2013-05-30 17:13:01.000000000 +0900
@@ -50,6 +50,8 @@
 #define CCI_SNOOP	0x0000
 #define CCI_STATUS	0x000c
 
+#define CNTFID0	0xe6080020
+
 static inline void r8a73a4_execute_wfe_as_nop(void)
 {
 	unsigned int v;
@@ -64,6 +66,32 @@ static inline void r8a73a4_execute_wfe_a
 	  : "cc");
 }
 
+static u32 r8a73a4_arch_freq;
+
+static inline void r8a73a4_reset_arch_timer(void)
+{
+	/* Program CNTFRQ from the frequency table */
+	asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (r8a73a4_arch_freq));
+
+	/* CNTVOFF has to be initialized either from non-secure Hypervisor
+	 * mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled
+	 * then it should be handled by the secure code
+	 */
+	asm volatile(
+	"cps	0x16				@ Monitor mode"
+	"mrc	p15, 0, r1, c1, c1, 0"
+	"orr	r0, r1, #1			@ Set SCR.NS (non-secure)"
+	"mcr	p15, 0, r0, c1, c1, 0"
+	"isb"
+	"mov	r0, #0"
+	"mcrr	p15, 4, r0, r0, c14		@ CNTVOFF"
+	"isb"
+	"mcr	p15, 0, r1, c1, c1, 0		@ Restore SCR"
+	"isb"
+	"cps	0x13				@ Back to SVC mode"
+	: : : "r0", "r1");
+}
+
 static void __init r8a73a4_smp_prepare_cpus(unsigned int max_cpus)
 {
 	u32 bar;
@@ -94,6 +122,11 @@ static void __init r8a73a4_smp_prepare_c
 		/* wait for pending bit low */;
 	iounmap(p);
 
+	/* Retrieve frequency to be able to later program CNTFRQ */
+	p = ioremap_nocache(CNTFID0, 16);
+	r8a73a4_arch_freq = __raw_readl(p);
+	iounmap(p);
+
 	r8a73a4_execute_wfe_as_nop();
 }
 
@@ -115,9 +148,11 @@ static int __cpuinit r8a73a4_boot_second
 
 static void __cpuinit r8a73a4_secondary_init(unsigned int cpu)
 {
-	/* CA15 need SW workaround */
+	/* CA15 and CA7 need SW workaround */
 	if (cpu_logical_map(cpu) < 4)
 		r8a73a4_execute_wfe_as_nop();
+	else
+		r8a73a4_reset_arch_timer();
 }
 
 #ifdef CONFIG_HOTPLUG_CPU

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 01/05] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4)
  2013-05-30  8:52 ` [PATCH 01/05] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4) Magnus Damm
@ 2013-06-05  8:29   ` Shinya Kuribayashi
  0 siblings, 0 replies; 7+ messages in thread
From: Shinya Kuribayashi @ 2013-06-05  8:29 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Magnus,

On 5/30/2013 5:52 PM, Magnus Damm wrote:
> --- 0003/arch/arm/boot/dts/r8a73a4.dtsi
> +++ work/arch/arm/boot/dts/r8a73a4.dtsi	2013-05-22 13:21:21.000000000 +0900
> @@ -25,6 +25,27 @@
>  			reg = <0>;
>  			clock-frequency = <1500000000>;
>  		};
> +
> +		cpu1: cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a15";
> +			reg = <1>;
> +			clock-frequency = <1500000000>;
> +		};
> +
> +		cpu2: cpu at 2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a15";
> +			reg = <2>;
> +			clock-frequency = <1500000000>;
> +		};
> +
> +		cpu3: cpu at 3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a15";
> +			reg = <3>;
> +			clock-frequency = <1500000000>;
> +		};
>  	};

The frequency of the EXTAL on APE6EVM machine is 26MHz, and the Generic
Timers are clocked at EXTAL x1/2 (=13MHz).  Do not copy-and-paste wrong
clock-frequency properties currently we have, but fix cpu0 along with
adding cpu1..3, please.

Furthermore you don't have (should not) to use clock-frequency property
if you set up CNTFRQ to an appropriate value one by one in PATCH 05/05.
--
Shinya Kuribayashi
Renesas Electronics

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-06-05  8:29 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-30  8:51 [PATCH 00/05] ARM: shmobile: r8a73a4 SMP and CPU Hotplug prototype v2 Magnus Damm
2013-05-30  8:52 ` [PATCH 01/05] ARM: shmobile: r8a73a4 SMP prototype v1 (CA15 x 4) Magnus Damm
2013-06-05  8:29   ` Shinya Kuribayashi
2013-05-30  8:52 ` [PATCH 02/05] ARM: shmobile: r8a73a4 CPU Hotplug " Magnus Damm
2013-05-30  8:52 ` [PATCH 03/05] ARM: shmobile: r8a73a4 CA15 setup WFE as NOP Magnus Damm
2013-05-30  8:52 ` [PATCH 04/05] ARM: shmobile: r8a73a4 SMP CA7 prototype (+ CA7 x 4) Magnus Damm
2013-05-30  8:52 ` [PATCH 05/05] ARM: shmobile: r8a73a4 CA7 setup arch timer Magnus Damm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).