ARM: shmobile: sh73a0, r8a7779 and emev2 SMP SCU rework
Magnus Damm
maintainercover ARM: shmobile: sh73a0, r8a7779 and emev2 SMP SCU rework
ARM: shmobile: sh73a0, r8a7779 and emev2 SMP SCU rework
[PATCH 01/07] ARM: shmobile: Introduce shared SCU SMP boot code [PATCH 02/07] ARM: shmobile: Use shared SCU SMP boot code on sh73a0 [PATCH 03/07] ARM: shmobile: Use shared SCU SMP boot code on r8a7779 [PATCH 04/07] ARM: shmobile: Use shared SCU SMP boot code on emev2 [PATCH 05/07] ARM: shmobile: Add shared SCU CPU Hotplug code [PATCH 06/07] ARM: shmobile: Use shared SCU CPU Hotplug code on sh73a0 [PATCH 07/07] ARM: shmobile: Use shared SCU CPU Hotplug code on r8a7779
This series consolidates mach-shmobile SMP code into SCU specific code for SMP boot and CPU Hotplug. The shared SCU code will in the future hook into some low level assembly code that provides SMP boot and sleep functionality, so this is is also preparations for future work.
---
Written against renesas.git renesas-devel-20130731
Requires "[PATCH] ARM: Fix memblock_reserve() to include stext" during run time to allow test of CPU Hotplug with v3.11-rc kernels.
arch/arm/mach-shmobile/Makefile | 6 +- arch/arm/mach-shmobile/include/mach/common.h | 5 + arch/arm/mach-shmobile/platsmp-scu.c | 76 ++++++++++++++++++++++++++ arch/arm/mach-shmobile/smp-emev2.c | 19 +++--- arch/arm/mach-shmobile/smp-r8a7779.c | 64 +++++---------------- arch/arm/mach-shmobile/smp-sh73a0.c | 67 +++++----------------- 6 files changed, 126 insertions(+), 111 deletions(-)
Magnus Damm
maintainerPATCH 1/7 ARM: shmobile: Introduce shared SCU SMP boot code
From: Magnus Damm <[email protected]>
Add SMP boot functions for SCU equipped mach-shmobile SoCs.
At this point shmobile_smp_scu_prepare_cpus() controls the SCU and installs boot fn and arg, while shmobile_smp_scu_boot_secondary() currently does nothing. In the future the boot function and arg install code will be reworked, so the empty function is ground work for that.
---
arch/arm/mach-shmobile/include/mach/common.h | 3 ++ arch/arm/mach-shmobile/platsmp-scu.c | 31 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+)
arch/arm/mach-shmobile/include/mach/common.h +3 -0
@@ -11,6 +11,9 @@ extern void shmobile_boot_vector(void);extern unsigned long shmobile_boot_fn;extern unsigned long shmobile_boot_arg;extern void shmobile_boot_scu (void ); +extern void shmobile_smp_scu_prepare_cpus (unsigned int max_cpus); +extern int shmobile_smp_scu_boot_secondary (unsigned int cpu, +struct task_struct *idle);struct clk ;extern int shmobile_clk_init (void );extern void shmobile_handle_irq_intc (struct pt_regs *);
arch/arm/mach-shmobile/platsmp-scu.c new file +31 -0
@@ -0,0 +1,31 @@ +/* +* SMP support for SoCs with SCU covered by mach-shmobile +* +* Copyright (C) 2013 Magnus Damm +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ +#include <linux/init.h> +#include <linux/io.h> +#include <linux/smp.h> +#include <asm/smp_plat.h> +#include <asm/smp_scu.h> +#include <mach/common.h> + +void __init shmobile_smp_scu_prepare_cpus (unsigned int max_cpus) +{ + shmobile_boot_fn =virt_to_phys (shmobile_boot_scu); + shmobile_boot_arg = (unsigned long )shmobile_scu_base; + +/* enable SCU and cache coherency on booting CPU */ +scu_enable (shmobile_scu_base); +scu_power_mode (shmobile_scu_base,SCU_PM_NORMAL ); +} + +int shmobile_smp_scu_boot_secondary (unsigned int cpu,struct task_struct *idle) +{ +/* do nothing for now */ +return 0 ; +}
Magnus Damm
maintainerPATCH 2/7 ARM: shmobile: Use shared SCU SMP boot code on sh73a0
In reply to Magnus DammFrom: Magnus Damm <[email protected]>
Use shared SCU code on sh73a0 for SMP boot.
---
arch/arm/mach-shmobile/Makefile | 2 +- arch/arm/mach-shmobile/smp-sh73a0.c | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-)
arch/arm/mach-shmobile/Makefile +1 -1
@@ -17,7 +17,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_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o
arch/arm/mach-shmobile/smp-sh73a0.c +13 -13
@@ -50,30 +50,30 @@ void __init sh73a0_register_twd(void)static int __cpuinit sh73a0_boot_secondary (unsigned int cpu,struct task_struct *idle) { - cpu =cpu_logical_map (cpu); +unsigned int lcpu =cpu_logical_map (cpu); +int ret; -if (((__raw_readl (PSTR ) >> (4 * cpu)) &3 ) ==3 ) -__raw_writel (1 << cpu,WUPCR );/* wake up */ + ret =shmobile_smp_scu_boot_secondary (cpu, idle); +if (ret) +return ret; + +if (((__raw_readl (PSTR ) >> (4 * lcpu)) &3 ) ==3 ) +__raw_writel (1 << lcpu,WUPCR );/* wake up */ else -__raw_writel (1 << cpu,SRESCR );/* reset */ +__raw_writel (1 << lcpu,SRESCR );/* reset */ return 0 ; }static void __init sh73a0_smp_prepare_cpus (unsigned int max_cpus) { -/* setup sh73a0 specific SCU base */ - shmobile_scu_base =IOMEM (SH73A0_SCU_BASE ); -scu_enable (shmobile_scu_base); - -/* Map the reset vector (in headsmp-scu.S, headsmp.S) */ +/* Map the reset vector (in headsmp.S) */ __raw_writel (0 ,APARMBAREA );/* 4k */ __raw_writel (__pa (shmobile_boot_vector),SBAR ); - shmobile_boot_fn =virt_to_phys (shmobile_boot_scu); - shmobile_boot_arg = (unsigned long )shmobile_scu_base; -/* enable cache coherency on booting CPU */ -scu_power_mode (shmobile_scu_base,SCU_PM_NORMAL ); +/* setup sh73a0 specific SCU bits */ + shmobile_scu_base =IOMEM (SH73A0_SCU_BASE ); +shmobile_smp_scu_prepare_cpus (max_cpus); }#ifdef CONFIG_HOTPLUG_CPU
Magnus Damm
maintainerPATCH 3/7 ARM: shmobile: Use shared SCU SMP boot code on r8a7779
In reply to Magnus DammFrom: Magnus Damm <[email protected]>
Use shared SCU code on r8a7779 for SMP boot.
---
arch/arm/mach-shmobile/Makefile | 2 +- arch/arm/mach-shmobile/smp-r8a7779.c | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-)
arch/arm/mach-shmobile/Makefile +1 -1
@@ -33,7 +33,7 @@ endif # SMP objects smp-y := platsmp.o headsmp.o smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o -smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o +smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o # IRQ objects
arch/arm/mach-shmobile/smp-r8a7779.c +12 -11
@@ -84,33 +84,34 @@ static int r8a7779_platform_cpu_kill(unsstatic int r8a7779_boot_secondary (unsigned int cpu,struct task_struct *idle) {struct r8a7779_pm_ch *ch =NULL ; -int ret = -EIO ; +unsigned int lcpu =cpu_logical_map (cpu); +int ret; - cpu =cpu_logical_map (cpu); + ret =shmobile_smp_scu_boot_secondary (cpu, idle); +if (ret) +return ret; -if (cpu <ARRAY_SIZE (r8a7779_ch_cpu)) - ch = r8a7779_ch_cpu[cpu]; +if (lcpu <ARRAY_SIZE (r8a7779_ch_cpu)) + ch = r8a7779_ch_cpu[lcpu];if (ch) ret =r8a7779_sysc_power_up (ch); +else + ret = -EIO ;return ret; }static void __init r8a7779_smp_prepare_cpus (unsigned int max_cpus) { - -/* setup r8a7779 specific SCU base */ - shmobile_scu_base =IOMEM (R8A7779_SCU_BASE ); -scu_enable (shmobile_scu_base); -/* Map the reset vector (in headsmp-scu.S, headsmp.S) */ __raw_writel (__pa (shmobile_boot_vector),AVECR ); shmobile_boot_fn =virt_to_phys (shmobile_boot_scu); shmobile_boot_arg = (unsigned long )shmobile_scu_base; -/* enable cache coherency on booting CPU */ -scu_power_mode (shmobile_scu_base,SCU_PM_NORMAL ); +/* setup r8a7779 specific SCU bits */ + shmobile_scu_base =IOMEM (R8A7779_SCU_BASE ); +shmobile_smp_scu_prepare_cpus (max_cpus);r8a7779_pm_init ();
Magnus Damm
maintainerPATCH 4/7 ARM: shmobile: Use shared SCU SMP boot code on emev2
In reply to Magnus DammFrom: Magnus Damm <[email protected]>
Use shared SCU code on emev2 for SMP boot.
---
arch/arm/mach-shmobile/Makefile | 2 +- arch/arm/mach-shmobile/smp-emev2.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-)
arch/arm/mach-shmobile/Makefile +1 -1
@@ -34,7 +34,7 @@ endif smp-y := platsmp.o headsmp.o smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o -smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o +smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o # IRQ objects obj-$(CONFIG_ARCH_SH7372) += entry-intc.o
arch/arm/mach-shmobile/smp-emev2.c +10 -9
@@ -34,6 +34,12 @@static int emev2_boot_secondary (unsigned int cpu,struct task_struct *idle) { +int ret; + + ret =shmobile_smp_scu_boot_secondary (cpu, idle); +if (ret) +return ret; +arch_send_wakeup_ipi_mask (cpumask_of (cpu_logical_map (cpu)));return 0 ; }
@@ -42,21 +48,16 @@ static void __init emev2_smp_prepare_cpu {void __iomem *smu; -/* setup EMEV2 specific SCU base, enable */ - shmobile_scu_base =ioremap (EMEV2_SCU_BASE ,PAGE_SIZE ); -scu_enable (shmobile_scu_base); - -/* Tell ROM loader about our vector (in headsmp-scu.S, headsmp.S) */ +/* Tell ROM loader about our vector (in headsmp.S) */ smu =ioremap (EMEV2_SMU_BASE ,PAGE_SIZE );if (smu) {iowrite32 (__pa (shmobile_boot_vector), smu +SMU_GENERAL_REG0 );iounmap (smu); } - shmobile_boot_fn =virt_to_phys (shmobile_boot_scu); - shmobile_boot_arg = (unsigned long )shmobile_scu_base; -/* enable cache coherency on booting CPU */ -scu_power_mode (shmobile_scu_base,SCU_PM_NORMAL ); +/* setup EMEV2 specific SCU bits */ + shmobile_scu_base =ioremap (EMEV2_SCU_BASE ,PAGE_SIZE ); +shmobile_smp_scu_prepare_cpus (max_cpus); }struct smp_operations emev2_smp_ops__initdata = {
Magnus Damm
maintainerPATCH 5/7 ARM: shmobile: Add shared SCU CPU Hotplug code
In reply to Magnus DammFrom: Magnus Damm <[email protected]>
Add CPU Hotplug functions for SCU equipped mach-shmobile SoCs.
The functions shmobile_smp_scu_cpu_die() together with shmobile_smp_scu_cpu_kill() perform basic shutdown and allows checking of shutdown status. These are written to work together with SMP boot code in headsmp-scu.S.
---
arch/arm/mach-shmobile/include/mach/common.h | 2 + arch/arm/mach-shmobile/platsmp-scu.c | 45 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+)
arch/arm/mach-shmobile/include/mach/common.h +2 -0
@@ -14,6 +14,8 @@ extern void shmobile_boot_scu(void);extern void shmobile_smp_scu_prepare_cpus (unsigned int max_cpus);extern int shmobile_smp_scu_boot_secondary (unsigned int cpu,struct task_struct *idle); +extern void shmobile_smp_scu_cpu_die (unsigned int cpu); +extern int shmobile_smp_scu_cpu_kill (unsigned int cpu);struct clk ;extern int shmobile_clk_init (void );extern void shmobile_handle_irq_intc (struct pt_regs *);
arch/arm/mach-shmobile/platsmp-scu.c +45 -0
57 lines not on this page · raw message
Magnus Damm
maintainerPATCH 6/7 ARM: shmobile: Use shared SCU CPU Hotplug code on sh73a0
In reply to Magnus DammFrom: Magnus Damm <[email protected]>
Update the sh73a0 specific CPU Hotplug code to make use of the recently introduced shared SCU functions. The sh73a0 power control hardware relies on SCU_PM_POWEROFF with WFI so the shared SCU code will as-is power down the hardware as expected.
---
arch/arm/mach-shmobile/smp-sh73a0.c | 41 ++--------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-)
arch/arm/mach-shmobile/smp-sh73a0.c +3 -38
@@ -20,14 +20,11 @@#include <linux/kernel.h> #include <linux/init.h> #include <linux/smp.h> -#include <linux/spinlock.h> #include <linux/io.h> #include <linux/delay.h> #include <mach/common.h> -#include <asm/cacheflush.h> -#include <asm/smp_plat.h> #include <mach/sh73a0.h> -#include <asm/smp_scu.h> +#include <asm/smp_plat.h> #include <asm/smp_twd.h> #define WUPCR IOMEM(0xe6151010)
@@ -36,8 +33,6 @@#define SBAR IOMEM(0xe6180020)#define APARMBAREA IOMEM(0xe6f10020) -#define PSTR_SHUTDOWN_MODE 3 -#define SH73A0_SCU_BASE 0xf0000000#ifdef CONFIG_HAVE_ARM_TWD
@@ -77,36 +72,6 @@ static void __init sh73a0_smp_prepare_cp }#ifdef CONFIG_HOTPLUG_CPU -static int sh73a0_cpu_kill (unsigned int cpu) -{ - -int k; -u32 pstr; - -/* -* wait until the power status register confirms the shutdown of the -* offline target -*/ -for (k =0 ; k <1000 ; k++) { - pstr = (__raw_readl (PSTR ) >> (4 * cpu)) &3 ; -if (pstr ==PSTR_SHUTDOWN_MODE ) -return 1 ; - -mdelay (1 ); - } - -return 0 ; -} - -static void sh73a0_cpu_die (unsigned int cpu) -{ -/* Set power off mode. This takes the CPU out of the MP cluster */ -scu_power_mode (shmobile_scu_base,SCU_PM_POWEROFF ); - -/* Enter shutdown mode */ -cpu_do_idle (); -} -static int sh73a0_cpu_disable (unsigned int cpu) {return 0 ;/* CPU0 and CPU1 supported */
@@ -117,8 +82,8 @@ struct smp_operations sh73a0_smp_ops __i .smp_prepare_cpus = sh73a0_smp_prepare_cpus, .smp_boot_secondary = sh73a0_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU - .cpu_kill = sh73a0_cpu_kill, - .cpu_die = sh73a0_cpu_die, .cpu_disable = sh73a0_cpu_disable, + .cpu_die = shmobile_smp_scu_cpu_die, + .cpu_kill = shmobile_smp_scu_cpu_kill, #endif };
Magnus Damm
maintainerPATCH 7/7 ARM: shmobile: Use shared SCU CPU Hotplug code on r8a7779
In reply to Magnus DammFrom: Magnus Damm <[email protected]>
Update the r8a7779 specific CPU Hotplug code to make use of the recently introduced shared SCU functions. The r8a7779 power domain hardware requires special power down handling at ->kill() time.
---
arch/arm/mach-shmobile/smp-r8a7779.c | 41 +++------------------------------- 1 file changed, 4 insertions(+), 37 deletions(-)
arch/arm/mach-shmobile/smp-r8a7779.c +4 -37
@@ -122,47 +122,14 @@ static void __init r8a7779_smp_prepare_c }#ifdef CONFIG_HOTPLUG_CPU -static int r8a7779_scu_psr_core_disabled (int cpu) -{ -unsigned long mask =3 << (cpu *8 ); - -if ((__raw_readl (shmobile_scu_base +8 ) & mask) == mask) -return 1 ; - -return 0 ; -} -static int r8a7779_cpu_kill (unsigned int cpu) { -int k; - -/* this function is running on another CPU than the offline target, -* here we need wait for shutdown code in platform_cpu_die() to -* finish before asking SoC-specific code to power off the CPU core. -*/ -for (k =0 ; k <1000 ; k++) { -if (r8a7779_scu_psr_core_disabled (cpu)) -return r8a7779_platform_cpu_kill (cpu); - -mdelay (1 ); - } +if (shmobile_smp_scu_cpu_kill (cpu)) +return r8a7779_platform_cpu_kill (cpu);return 0 ; } -static void r8a7779_cpu_die (unsigned int cpu) -{ -dsb (); -flush_cache_all (); - -/* disable cache coherency */ -scu_power_mode (shmobile_scu_base,SCU_PM_POWEROFF ); - -/* Endless loop until power off from r8a7779_cpu_kill() */ -while (1 ) -cpu_do_idle (); -} -static int r8a7779_cpu_disable (unsigned int cpu) {/* only CPU1->3 have power domains, do not allow hotplug of CPU0 */
@@ -174,8 +141,8 @@ struct smp_operations r8a7779_smp_ops _ .smp_prepare_cpus = r8a7779_smp_prepare_cpus, .smp_boot_secondary = r8a7779_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU - .cpu_kill = r8a7779_cpu_kill, - .cpu_die = r8a7779_cpu_die, .cpu_disable = r8a7779_cpu_disable, + .cpu_die = shmobile_smp_scu_cpu_die, + .cpu_kill = r8a7779_cpu_kill, #endif };
cover ARM: shmobile: sh73a0, r8a7779 and emev2 SMP SCU rework
In reply to Magnus DammQuoted 15 lines · Magnus Damm
ARM: shmobile: sh73a0, r8a7779 and emev2 SMP SCU rework
[PATCH 01/07] ARM: shmobile: Introduce shared SCU SMP boot code [PATCH 02/07] ARM: shmobile: Use shared SCU SMP boot code on sh73a0 [PATCH 03/07] ARM: shmobile: Use shared SCU SMP boot code on r8a7779 [PATCH 04/07] ARM: shmobile: Use shared SCU SMP boot code on emev2 [PATCH 05/07] ARM: shmobile: Add shared SCU CPU Hotplug code [PATCH 06/07] ARM: shmobile: Use shared SCU CPU Hotplug code on sh73a0 [PATCH 07/07] ARM: shmobile: Use shared SCU CPU Hotplug code on r8a7779
This series consolidates mach-shmobile SMP code into SCU specific code for SMP boot and CPU Hotplug. The shared SCU code will in the future hook into some low level assembly code that provides SMP boot and sleep functionality, so this is is also preparations for future work.
Quoted 7 lines
Signed-off-by Magnus Damm <[email protected]>---
Written against renesas.git renesas-devel-20130731
Requires "[PATCH] ARM: Fix
memblock_reserve()to include stext" during run time to allow test of CPU Hotplug with v3.11-rc kernels.
I guess we need to wait for Russell's alternate fix to hit a stable branch.