* [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 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
* [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