PM Fixes for exynos5
cover PM Fixes for exynos5
This patchset comprises fixes to properly enable PM support on exynos5. Based on git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git
for-next branch.
Patches 1 and 4 are re-posts of patches sent earlier by Changhwan Youn and Inderpal Singh respectively. Links follow:
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-May/098930.html
http://permalink.gmane.org/gmane.linux.kernel.samsung-soc/10947
Patch 2 is a fix in cpuidle while patch 3 enables the RTC alarm as a wake up source.
Patch 5 adds a machine specific "flush_cache_all" as it is no longer part of the core suspend routine. This was suggested by Lorenzo Pieralisi.
These patches have been tested on SMDK5250.
Abhilash Kesavan (3):
ARM: EXYNOS: fix the hotplug for Cortex-A15
ARM: EXYNOS5: Remove scu_enable from cpuidle
ARM: EXYNOS5: Add flush_cache_all in suspend finisher
Inderpal Singh (2):
ARM: EXYNOS5: Add support for rtc wakeup
ARM: EXYNOS: Fix soft reboot hang after suspend/resume
arch/arm/mach-exynos/common.c | 2 + arch/arm/mach-exynos/cpuidle.c | 3 +- arch/arm/mach-exynos/hotplug.c | 45 ++++++++++++++++++++++++++++-- arch/arm/mach-exynos/pm.c | 7 +++++ arch/arm/plat-samsung/include/plat/pm.h | 2 + 5 files changed, 55 insertions(+), 4 deletions(-)
PATCH 1/5 ARM: EXYNOS: fix the hotplug for Cortex-A15
The sequence of cpu_enter_lowpower() for Cortex-A15 is different from the sequence for Cortex-A9. This patch implements cpu_enter_lowpower() for EXYNOS5 SoC which has Cortex-A15 cores.
--- arch/arm/mach-exynos/hotplug.c | 45 +++++++++++++++++++++++++++++++++++++-- 1 files changed, 42 insertions(+), 3 deletions(-)
arch/arm/mach-exynos/hotplug.c +42 -3
@@ -20,10 +20,11 @@#include <asm/smp_plat.h> #include <mach/regs-pmu.h> +#include <plat/cpu.h> #include "common.h" -static inline void cpu_enter_lowpower (void ) +static inline void cpu_enter_lowpower_a9 (void ) {unsigned int v;
@@ -45,6 +46,35 @@ static inline void cpu_enter_lowpower(void) : "cc"); } +static inline void cpu_enter_lowpower_a15 (void ) +{ +unsigned int v; + + asmvolatile ( +" 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_all (); + + asmvolatile ( +/* +* 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 inline void cpu_leave_lowpower (void ) {unsigned int v;
@@ -103,11 +133,20 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)void __ref exynos_cpu_die (unsigned int cpu) {int spurious =0 ; +int primary_part =0 ;/* -* we're ready for shutdown now, so do it +* we're ready for shutdown now, so do it. +* Exynos4 is A9 based while Exynos5 is A15; check the CPU part +* number by reading the Main ID register and then perform the +* appropriate sequence for entering low power. */ -cpu_enter_lowpower (); + asm("mrc p15, 0, %0, c0, c0, 0" :"=r" (primary_part) : :"cc" ); +if ((primary_part &0xfff0 ) ==0xc0f0 ) +cpu_enter_lowpower_a15 (); +else +cpu_enter_lowpower_a9 (); +platform_do_lowpower (cpu, &spurious);/*
Signature · 1 line
1.6.6.1
PATCH 1/5 ARM: EXYNOS: fix the hotplug for Cortex-A15
Hi,
Quoted 75 lines · Abhilash Kesavan
The sequence of
cpu_enter_lowpower()for Cortex-A15 is different from the sequence for Cortex-A9. This patch implementscpu_enter_lowpower()for EXYNOS5 SoC which has Cortex-A15 cores.Signed-off-by Changhwan Youn <[email protected]>Cc Russell King <[email protected]>Signed-off-by Kukjin Kim <[email protected]>Tested-by Abhilash Kesavan <[email protected]>--- arch/arm/mach-exynos/hotplug.c | 45 +++++++++++++++++++++++++++++++++++++-- 1 files changed, 42 insertions(+), 3 deletions(-)arch/arm/mach-exynos/hotplug.c +32
-1@@ -20,10 +20,11 @@#include <asm/smp_plat.h> #include <mach/regs-pmu.h> +#include <plat/cpu.h> #include "common.h" -static inline void cpu_enter_lowpower (void ) +static inline void cpu_enter_lowpower_a9 (void ) {unsigned int v;@@ -45,6 +46,35 @@ static inline void cpu_enter_lowpower(void) : "cc"); } +static inline void cpu_enter_lowpower_a15 (void ) +{ +unsigned int v; + + asmvolatile ( +" 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_all (); + + asmvolatile ( +/* +* 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 inline void cpu_leave_lowpower (void ) {unsigned int v;@@ -103,11 +133,20 @@ static inline void platform_do_lowpower(unsigned int cpu, int *spurious)void __ref exynos_cpu_die (unsigned int cpu) {int spurious =0 ; +int primary_part =0 ;
arch/arm/mach-exynos/hotplug.c static inline void platform_do_lowpower(unsigned int · line 146
Quoted 10 lines
arch/arm/mach-exynos/hotplug.c +6
-2/* -* we're ready for shutdown now, so do it +* we're ready for shutdown now, so do it. +* Exynos4 is A9 based while Exynos5 is A15; check the CPU part +* number by reading the Main ID register and then perform the +* appropriate sequence for entering low power. */ -cpu_enter_lowpower (); + asm("mrc p15, 0, %0, c0, c0, 0" :"=r" (primary_part) : :"cc" ); +if ((primary_part &0xfff0 ) ==0xc0f0 )
Doesn't better to use soc_is_exynos5250? Actullay, it's better to use soc_is_exynos5 for all exynos5 series. but not it doesn't have these macro.
Thank you,
Kyungmin Park
Quoted 16 lines
arch/arm/mach-exynos/hotplug.c +4
-0+cpu_enter_lowpower_a15 (); + else +cpu_enter_lowpower_a9 (); +platform_do_lowpower (cpu, &spurious);/*
--
1.6.6.1_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH 1/5 ARM: EXYNOS: fix the hotplug for Cortex-A15
In reply to Abhilash KesavanQuoted 2 lines · Abhilash Kesavan
The sequence of
cpu_enter_lowpower()for Cortex-A15 is different from the sequence for Cortex-A9.
Are you sure ? Apart from integrated cache vs external, there should be no change. And L2 doesn't need to come into picture while powering down just a CPU.
Quoted 36 lines
This patch implements
cpu_enter_lowpower()for EXYNOS5 SoC which has Cortex-A15 cores.Signed-off-by Changhwan Youn <[email protected]>Cc Russell King <[email protected]>Signed-off-by Kukjin Kim <[email protected]>Tested-by Abhilash Kesavan <[email protected]>--- arch/arm/mach-exynos/hotplug.c | 45 +++++++++++++++++++++++++++++++++++++-- 1 files changed, 42 insertions(+), 3 deletions(-)arch/arm/mach-exynos/hotplug.c +6
-1@@ -20,10 +20,11 @@#include <asm/smp_plat.h> #include <mach/regs-pmu.h> +#include <plat/cpu.h> #include "common.h" -static inline void cpu_enter_lowpower (void ) +static inline void cpu_enter_lowpower_a9 (void ) {unsigned int v;@@ -45,6 +46,35 @@ static inline void cpu_enter_lowpower(void) : "cc"); } +static inline void cpu_enter_lowpower_a15 (void ) +{ +unsigned int v; +
arch/arm/mach-exynos/hotplug.c static inline void cpu_enter_lowpower(void) · line 62
Quoted 10 lines
arch/arm/mach-exynos/hotplug.c +10
-0+ asmvolatile ( +" 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_all (); +
Why are flushing all the cache levels ?flush_kern_louis() should be enough for CPU power
down.
Quoted 5 lines
arch/arm/mach-exynos/hotplug.c +5
-0+ asmvolatile ( +/* +* Turn off coherency +*/ + " mrc p15, 0, %0, c1, c0, 1\n"
arch/arm/mach-exynos/hotplug.c static inline void cpu_enter_lowpower(void) · line 77
Quoted 10 lines
arch/arm/mach-exynos/hotplug.c +10
-0+" bic %0, %0, %1\n" +" mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (0x40) + : "cc"); + + isb(); +dsb (); +} +
The above sequence should work on A9 as well. In general you should have CPU power down code under one code block and avoid making use of stack in between. Otherwise you will end up with stack corruption because of the memory view change after C bit is disabled.
Regards
Santosh
PATCH 1/5 ARM: EXYNOS: fix the hotplug for Cortex-A15
Quoted 6 lines · Santosh Shilimkar
Quoted 2 lines · Abhilash Kesavan
The sequence of
cpu_enter_lowpower()for Cortex-A15 is different from the sequence for Cortex-A9.Are you sure ? Apart from integrated cache vs external, there should be no change. And L2 doesn't need to come into picture while powering down just a CPU.
Reiterating Santosh point in here. v7 shutdown procedure is and has to be identical across all v7 cores. There is not such a thing as "A15 specific" shutdown procedure.
Embedded L2 will come into the picture on multi-cluster systems, for the time being L2 must not be flushed when hotplugging a CPU in a single cluster so the LoUIS API is to be used here.
Quoted 41 lines
Quoted 41 lines
This patch implements
cpu_enter_lowpower()for EXYNOS5 SoC which has Cortex-A15 cores.Signed-off-by Changhwan Youn <[email protected]>Cc Russell King <[email protected]>Signed-off-by Kukjin Kim <[email protected]>Tested-by Abhilash Kesavan <[email protected]>--- arch/arm/mach-exynos/hotplug.c | 45 +++++++++++++++++++++++++++++++++++++-- 1 files changed, 42 insertions(+), 3 deletions(-)arch/arm/mach-exynos/hotplug.c +11
-1@@ -20,10 +20,11 @@#include <asm/smp_plat.h> #include <mach/regs-pmu.h> +#include <plat/cpu.h> #include "common.h" -static inline void cpu_enter_lowpower (void ) +static inline void cpu_enter_lowpower_a9 (void ) {unsigned int v;@@ -45,6 +46,35 @@ static inline void cpu_enter_lowpower(void) : "cc"); } +static inline void cpu_enter_lowpower_a15 (void ) +{ +unsigned int v; + + asmvolatile ( +" mrc p15, 0, %0, c1, c0, 0\n" +" bic %0, %0, %1\n" +" mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v)
Quoted 8 lines
arch/arm/mach-exynos/hotplug.c static inline void cpu_enter_lowpower(void) · line 62
Quoted 5 lines
arch/arm/mach-exynos/hotplug.c +5
-0+ : "Ir" (CR_C) + : "cc"); + +flush_cache_all (); +Why are flushing all the cache levels ?
flush_kern_louis()should be enough for CPU power
down.
Agree with Santosh again.
Quoted 21 lines
Quoted 6 lines
arch/arm/mach-exynos/hotplug.c +5
-0+ asmvolatile ( +/* +* Turn off coherency +*/ + " mrc p15, 0, %0, c1, c0, 1\n"arch/arm/mach-exynos/hotplug.c static inline void cpu_enter_lowpower(void) · line 77
Quoted 10 lines
arch/arm/mach-exynos/hotplug.c +10
-0+" bic %0, %0, %1\n" +" mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (0x40) + : "cc"); + + isb(); +dsb (); +} +The above sequence should work on A9 as well. In general you should have CPU power down code under one code block and avoid making use of stack in between. Otherwise you will end up with stack corruption because of the memory view change after C bit is disabled.
Quoted 2 lines
Regards
Santosh
The above sequence does not work on A9 since A9 does not look-up the caches when the C bit is cleared. It is an accident waiting to happen, as Santosh explained.
The sequence:
- clear C bit
- clean L1
- exit SMP
must be written in assembly with no access to any data whatsoever, no stack, _nothing_.
There is some code in the works to consolidate this procedure once for all but all bits and pieces are already in the kernel.
Lorenzo
Kukjin Kim
maintainerPATCH 1/5 ARM: EXYNOS: fix the hotplug for Cortex-A15
Quoted 5 lines · Lorenzo Pieralisi
Quoted 3 lines · Santosh Shilimkar
Quoted 2 lines · Abhilash Kesavan
The sequence of
cpu_enter_lowpower()for Cortex-A15 is different from the sequence for Cortex-A9.
Quoted 8 lines
Quoted 3 lines
Are you sure ? Apart from integrated cache vs external, there should be no change. And L2 doesn't need to come into picture while powering down just a CPU.
Reiterating Santosh point in here. v7 shutdown procedure is and has to be identical across all v7 cores. There is not such a thing as "A15 specific" shutdown procedure.
BTW, it's true that current codes cannot support A15. So we need a separate A15 func. And a A9 func. Now, cpu_enter_lowpower_a9() on A15 does NOT work...also cpu_enter_lowpower_a15() on A9 does NOT work as well...
Quoted 5 lines
Embedded L2 will come into the picture on multi-cluster systems, for the time being L2 must not be flushed when hotplugging a CPU in a single cluster
so the LoUIS API is to be used here.
OK.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
This patch implements
cpu_enter_lowpower()for EXYNOS5 SoC which has Cortex-A15 cores.
[...]
Quoted 19 lines
Quoted 10 lines
Quoted 10 lines
arch/arm/mach-exynos/hotplug.c +9
-0+static inline void cpu_enter_lowpower_a15 (void ) +{ +unsigned int v; + + asmvolatile ( +" mrc p15, 0, %0, c1, c0, 0\n" +" bic %0, %0, %1\n" +" mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v)Quoted 8 lines
arch/arm/mach-exynos/hotplug.c static inline void cpu_enter_lowpower(void) · line 62
Quoted 5 lines
arch/arm/mach-exynos/hotplug.c +5
-0+ : "Ir" (CR_C) + : "cc"); + +flush_cache_all (); +Why are flushing all the cache levels ?
flush_kern_louis()should be enough for CPU power
down.
Quoted 2 lines
Agree with Santosh again.
Yes, agree. I will replace as per your suggestion when I apply this. And as I know, Abhilash already tested it on the boards and it works fine.
Quoted 34 lines
Quoted 21 lines
Quoted 6 lines
arch/arm/mach-exynos/hotplug.c +5
-0+ asmvolatile ( +/* +* Turn off coherency +*/ + " mrc p15, 0, %0, c1, c0, 1\n"arch/arm/mach-exynos/hotplug.c static inline void cpu_enter_lowpower(void) · line 77
Quoted 10 lines
arch/arm/mach-exynos/hotplug.c +10
-0+" bic %0, %0, %1\n" +" mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (0x40) + : "cc"); + + isb(); +dsb (); +} +The above sequence should work on A9 as well. In general you should have CPU power down code under one code block and avoid making use of stack in between. Otherwise you will end up with stack corruption because of the memory view change after C bit is disabled.
Quoted 2 lines
Regards
SantoshThe above sequence does not work on A9 since A9 does not look-up the caches when the C bit is cleared. It is an accident waiting to happen, as Santosh explained.
The sequence:
- clear C bit
- clean L1
- exit SMP
Quoted 8 lines
must be written in assembly with no access to any data whatsoever, no stack,
_nothing_.There is some code in the works to consolidate this procedure once for all but
all bits and pieces are already in the kernel.
I see, so it means, at this moment, exynos stuff needs this patch until finishing common implementation you said. Then, I think, if any common codes are available, we can use new codes instead.
K-Gene <[email protected]>
PATCH 2/5 ARM: EXYNOS5: Add support for rtc wakeup
In reply to Abhilash KesavanFrom: Inderpal Singh <[email protected]>
Set the gic arch extension callback to support rtc wakeup.
--- arch/arm/mach-exynos/common.c | 2 ++ arch/arm/plat-samsung/include/plat/pm.h | 2 ++ 2 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/mach-exynos/common.c +2 -0
@@ -631,6 +631,8 @@ void __init exynos5_init_irq(void)* uses GIC instead of VIC. */ s5p_init_irq (NULL ,0 ); + + gic_arch_extn.irq_set_wake = s3c_irq_wake; }struct bus_type exynos_subsys = {
arch/arm/plat-samsung/include/plat/pm.h +2 -0
@@ -107,10 +107,12 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);extern void s3c_pm_do_restore_core (struct sleep_save *ptr,int count);#ifdef CONFIG_PM +extern int s3c_irq_wake (struct irq_data *data,unsigned int state);extern int s3c_irqext_wake (struct irq_data *data,unsigned int state);extern int s3c24xx_irq_suspend (void );extern void s3c24xx_irq_resume (void );#else +#define s3c_irq_wake NULL#define s3c_irqext_wake NULL#define s3c24xx_irq_suspend NULL#define s3c24xx_irq_resume NULL
Signature · 1 line
1.6.6.1
PATCH 3/5 ARM: EXYNOS: Fix soft reboot hang after suspend/resume
In reply to Abhilash KesavanFrom: Inderpal Singh <[email protected]>
Upon wake-up, clear the sleep mode set in INFORM1 register.
--- arch/arm/mach-exynos/pm.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/mach-exynos/pm.c +4 -0
@@ -312,6 +312,10 @@ static void exynos_pm_resume(void) } early_wakeup: + +/* Clear SLEEP mode set in INFORM1 */ +__raw_writel (0x0 ,S5P_INFORM1 ); +return ; }
Signature · 1 line
1.6.6.1
PATCH 4/5 ARM: EXYNOS5: Remove scu_enable from cpuidle
In reply to Abhilash KesavanCortex A9 based exynos4 has a memory mapped SCU while the Cortex A15 based exynos5 does not. Hence, remove the call to scu_enable for exynos5.
--- arch/arm/mach-exynos/cpuidle.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
arch/arm/mach-exynos/cpuidle.c +2 -1
@@ -116,7 +116,8 @@ static int exynos4_enter_core0_aftr(struct cpuidle_device *dev,cpu_suspend (0 , idle_finisher);#ifdef CONFIG_SMP -scu_enable (S5P_VA_SCU ); +if (!soc_is_exynos5250 ()) +scu_enable (S5P_VA_SCU );#endif cpu_pm_exit ();
Signature · 1 line
1.6.6.1
PATCH 5/5 ARM: EXYNOS5: Add flush_cache_all in suspend finisher
In reply to Abhilash KesavanThe core cpu_suspend code no longer calls flush_cache_all to optimize the cpu idle flow. Add a call for the same in the exynos specific suspend code.
--- arch/arm/mach-exynos/pm.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
arch/arm/mach-exynos/pm.c +3 -0
@@ -81,6 +81,9 @@ static int exynos_cpu_suspend(unsigned long arg)outer_flush_all ();#endif +if (soc_is_exynos5250 ()) +flush_cache_all (); +/* issue the standby signal into the pm unit. */ cpu_do_idle ();
Signature · 1 line
1.6.6.1