OMAP4: PM: suspend, CPU-hotplug and CPUilde support
v3 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support
V3 updates:
It's same as V2 with couple of minor updates and its rebased on Kevin's latest pm-core branch.
- Dropped 'enable_off_mode' flag altogether for OMAP4 as discussed on the list.
- Removed non-supported pm debug entries
The following changes since commit 61cbb3172176b84c106bf0f4c32317c472932ab5:
Kevin Hilman (1):
Merge branch 'for_2.6.40/pm-misc' into pm-reset
are available in the git repository at:
git://dev.omapzoom.org/pub/scm/santosh/kernel-omap4-base.git omap4_pm_pmcore_v3
Dependent patches and integrated barnch against pm-core branch
are also available at below.
git://dev.omapzoom.org/pub/scm/santosh/kernel-omap4-base.git omap4_pm_pmcore_dep
git://dev.omapzoom.org/pub/scm/santosh/kernel-omap4-base.git omap4_pm_pmcore_int
V2 updates:
Rebased on Kevin's latest pm-core branch and fixes below comments from Kevin Hilman <[email protected]>.
- All acronym fixes
- Use WARN_ON() instead of BUG_ON() with graceful exit.
- Export omap4_get_base*() rather than global address pointers
- CPUidle prepare() hook + hotplug notifier to manage C-state dynamically.
- Dropped debugfs way of changing C-state valid flags in favor of above.
This series adds OMAP4 suspend and cpuidle support till MPU subsystem (MPUSS) off-mode. The suspend on SMP machines uses cpu-hotplug infrastructure to take down the non-boot CPUs. We put secondary CPU(CPU1 in OMAP4) to OFF state via cpu-hotplug.
In cpuidle too, low power states are attempted only when the CPU1 is put to OFF state via cpu-hotplug because of hardware constraints.
Timer wakeup from suspend, debug pm counters and enable_off_mode provisions are supported as well.
Special thanks to Kevin Hilman <[email protected]> for doing detail off-the list reviews.
The patches are generated against mainline 2.6.38-rc5 and tested with OMAP4430 SDP and OMAP4 PANDA board. Any OMAP4 board with ES2.X silicon, below features should work with this series. On ES1.0, these PM features are not supported.
1. CPU hotplug (CPU is put into off-mode)
2. Suspend (Both CPUs put to off-mode and MPUSS to OFF/RET)
3. CPUILDE with below C-states.
C1 - CPU0 ON + CPU1 ON/OFF + MPU ON + CORE ON C2 - CPU0 ON + CPU1 OFF + MPU ON + CORE ON C3 - CPU0 OFF + CPU1 OFF + MPU CSWR + CORE ON C4 - CPU0 OFF + CPU1 OFF + MPU OFF + CORE ON
In OMAP4 mpuss consist of dual Cortex-A9 with per-cpu local timers GIC(Generic Interrupt Controller), SCU(Snoop Control Unit) and PL310 L2 cache controller and CPU0/CPU1 LPRM modules.
CPU0, CPU1 and MPUSS have there own power domain and hence multiple low power state combinations are possible. The CPU10 and CPU1 Close switch Retention(CSWR) isn't supported by hardware. Based on various studies, measurements, hardware constraints and recommendations from hardware team, only below low power modes are supported on OMAP4.
----------------------------------------
CPU0 CPU1 MPUSS
----------------------------------------
ON ON ON
OFF OFF CSWR
OFF OFF OSWR
OFF OFF OFF
-----------------------------------------
Note: CPU0 is the master core and it is the last CPU to go down and first to wake-up when MPUSS low power states are attempted
OSWR(Open Switch Retention) is not added as part of this series because it needs some power domain level support which isn't ready yet.
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg38667.html
Powerdomain INACTIVE support is also dropped because of its inconsistency between OMAP4 and OMAP3.
More information on this thread -
http://www.spinics.net/lists/linux-omap/msg45370.html
The cpu-hotplug and suspend works with omap2plus_defconfig. Not to damage your file system with current omap2plus_defconfig, disable ARCH_OMAP2 so that V6 and V7 support is not built together with SMP.
To tryout cpuidle, CONFIG_CPU_IDLE needs to be enabled in the build.
CPU-HOTPLUG commands :
offline : $echo 0 > /sys/devices/system/cpu/cpu1/online online : $echo 1 > /sys/devices/system/cpu/cpu1/online
Suspend :$echo mem > /sys/power/state
cpuilde : To trigger cpuidle deeper C-states on OMAP4, CPU1 needs
to be offlied
$echo 0 > /sys/devices/system/cpu/cpu1/online
To see PM debug counters,
$mount -t debugfs debugfs /proc/sys/debug/ $cat /proc/sys/debug/pm_debug/count
The following changes since commit 61cbb3172176b84c106bf0f4c32317c472932ab5:
Kevin Hilman (1):
Merge branch 'for_2.6.40/pm-misc' into pm-reset
are available in the git repository at:
git://dev.omapzoom.org/pub/scm/santosh/kernel-omap4-base.git omap4_pm_pmcore_v3
Rajendra Nayak (1):
OMAP4: cpuidle: Basic CPUidle support
Santosh Shilimkar (20):
OMAP4: PM: Add omap WakeupGen module support
OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit
OMAP4: PM: Export omap4_get_base*() rather than global address pointers
OMAP4: PM: Add SAR RAM support
OMAP4: PM: Add CPUX OFF mode support
OMAP4: PM: Initialise all the clockdomains to supported states
OMAP4: PM: Program CPU1 to hit OFF when off-lined
OMAP4: PM: CPU1 wakeup workaround from Low power modes
OMAP4: PM: Add GIC distributor and interface enable/disable accessory API
OMAP4: PM: Add GIC save/restore support
OMAP4: PM: Add WakeupGen save/restore support
OMAP4: PM: Add L2 cache lowpower support
OMAP4: suspend: Add MPUSS RET and OFF support
OMAP4: pm-debug: Add wakeup timer and debug counters
OMAP4: cpuidle: Add MPUSS RET OFF states
OMAP4: cpuidle: Switch to gptimer from twd in deeper C-states.
OMAP4: cpuidle: Add CPU hotplug notifier and prepare() hook.
OMAP4: Remove un-used do_wfi() macro.
OMAP4: PM: Set static dependency between MPUSS-EMIF and MPUSS-L3_1
OMAP4: PM: Avoid omap4_pm_init() on OMAP4430 ES1.0
arch/arm/mach-omap2/Makefile | 8 +- arch/arm/mach-omap2/cpuidle44xx.c | 352 ++++++++++++++++ arch/arm/mach-omap2/include/mach/omap-wakeupgen.h | 41 ++ arch/arm/mach-omap2/include/mach/omap4-common.h | 73 +++- arch/arm/mach-omap2/omap-hotplug.c | 30 ++- arch/arm/mach-omap2/omap-smp.c | 32 ++- arch/arm/mach-omap2/omap-wakeupgen.c | 319 +++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 86 ++++- arch/arm/mach-omap2/omap4-mpuss-lowpower.c | 451 +++++++++++++++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 66 +++ arch/arm/mach-omap2/pm-debug.c | 11 +- arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm44xx.c | 138 ++++++- arch/arm/mach-omap2/sleep44xx.S | 404 ++++++++++++++++++ arch/arm/plat-omap/include/plat/omap44xx.h | 1 + 15 files changed, 1980 insertions(+), 33 deletions(-) create mode 100644 arch/arm/mach-omap2/cpuidle44xx.c create mode 100644 arch/arm/mach-omap2/include/mach/omap-wakeupgen.h create mode 100644 arch/arm/mach-omap2/omap-wakeupgen.c create mode 100644 arch/arm/mach-omap2/omap4-mpuss-lowpower.c create mode 100644 arch/arm/mach-omap2/omap4-sar-layout.h create mode 100644 arch/arm/mach-omap2/sleep44xx.S
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
This patch adds OMAP WakeupGen support. The WakeupGen unit is responsible for generating wakeup event from the incoming interrupts and enable bits. The WakeupGen is implemented in MPU Always-On power domain. During normal operation, WakeupGen delivers external interrupts directly to the GIC. When the CPUx asserts StandbyWFI, indicating it wants to enter lowpower state, the Standby Controller checks with the WakeupGen unit using the idlereq/idleack handshake to make sure there is no incoming interrupts. The GIC and WakeupGen needs to be kept in synchronisation for proper interrupt functioning.
Hence this patch hooks up the omap WakeupGen mask/unmask along with GIC using architecture specific hooks.
--- arch/arm/mach-omap2/Makefile | 3 +- arch/arm/mach-omap2/include/mach/omap-wakeupgen.h | 40 ++++ arch/arm/mach-omap2/omap-wakeupgen.c | 238 +++++++++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 3 + 4 files changed, 283 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/include/mach/omap-wakeupgen.h create mode 100644 arch/arm/mach-omap2/omap-wakeupgen.c
arch/arm/mach-omap2/Makefile +2 -1
@@ -24,7 +24,8 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o -obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o +obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o \ + omap-wakeupgen.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
arch/arm/mach-omap2/include/mach/omap-wakeupgen.h new file +40 -0
@@ -0,0 +1,40 @@ +/* +* OMAP WakeupGen header file +* +* Copyright (C) 2011 Texas Instruments, Inc. +* Written by Santosh Shilimkar <[email protected]> +* +* 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. +*/ +#ifndef OMAP_ARCH_WAKEUPGEN_H +#define OMAP_ARCH_WAKEUPGEN_H + +#define OMAP_WKG_CONTROL_0 0x00 +#define OMAP_WKG_ENB_A_0 0x10 +#define OMAP_WKG_ENB_B_0 0x14 +#define OMAP_WKG_ENB_C_0 0x18 +#define OMAP_WKG_ENB_D_0 0x1c +#define OMAP_WKG_ENB_SECURE_A_0 0x20 +#define OMAP_WKG_ENB_SECURE_B_0 0x24 +#define OMAP_WKG_ENB_SECURE_C_0 0x28 +#define OMAP_WKG_ENB_SECURE_D_0 0x2c +#define OMAP_WKG_ENB_A_1 0x410 +#define OMAP_WKG_ENB_B_1 0x414 +#define OMAP_WKG_ENB_C_1 0x418 +#define OMAP_WKG_ENB_D_1 0x41c +#define OMAP_WKG_ENB_SECURE_A_1 0x420 +#define OMAP_WKG_ENB_SECURE_B_1 0x424 +#define OMAP_WKG_ENB_SECURE_C_1 0x428 +#define OMAP_WKG_ENB_SECURE_D_1 0x42c +#define OMAP_AUX_CORE_BOOT_0 0x800 +#define OMAP_AUX_CORE_BOOT_1 0x804 +#define OMAP_PTMSYNCREQ_MASK 0xc00 +#define OMAP_PTMSYNCREQ_EN 0xc04 +#define OMAP_TIMESTAMPCYCLELO 0xc08 +#define OMAP_TIMESTAMPCYCLEHI 0xc0c + +extern int __init omap_wakeupgen_init (void ); +extern void omap_wakeupgen_irqmask_all (unsigned int cpu,unsigned int set); +#endif
arch/arm/mach-omap2/omap-wakeupgen.c new file +238 -0
238 lines not on this page · raw message
arch/arm/mach-omap2/omap4-common.c +3 -0
@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;
@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base); +omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }
Signature · 1 line
1.6.0.4
Tony Lindgren
maintainerPATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 11 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c +2
-0@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base); +omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }
Do you really need to initialize all of this that early?
Tony
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
Tony Lindgren
maintainerPATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 6 lines · Santosh Shilimkar
Quoted 4 lines
From: Tony Lindgren [mailto:tony at atomide.com]
Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
Hmm to me it seems that the gic_arch_extn functions should be all NULL during runtime operation, and the wake-up generator should be programmed only before entering an idle state.
Then the wake-up generator can be cleared after delivering the wake-up event(s).
Or am I missing something on why this should be enabled all the time?
BTW, looks like you got few typos in the comments in this patch, noticed these while reading:
Hardware requirements is
GIC rgeisters
gic architecture specific fucntioms
I know I'm making tons of typos too ;)
Tony
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 12 lines · Tony Lindgren
Quoted 6 lines · Santosh Shilimkar
Quoted 4 lines
From: Tony Lindgren [mailto:tony at atomide.com]
Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
Hmm to me it seems that the
gic_arch_extnfunctions should be all NULL during runtime operation, and the wake-up generator should be programmed only before entering an idle state.
Quoted 6 lines
Then the wake-up generator can be cleared after delivering the wake-up event(s).
Or am I missing something on why this should be enabled all the time?
Yep. The WakeupGen sits between GIC and CPU and can gate the interrupts in normal operation too. It's mandatory that the interrupt mask at GIC and WakeupGen matches to deliver the interrupt to CPU.
This is the reason why all the necessary GIC hooks are populated with it so that they work together.
So far without this patch all interrupts at WakeupGen level were always enabled and hence there was no issue.
Quoted 7 lines
BTW, looks like you got few typos in the comments in this patch, noticed these while reading:
Hardware requirements is
GIC rgeisters
gic architecture specific fucntioms
I do lot of them :(
Will fix these typos.
Regards
Santosh
Tony Lindgren
maintainerPATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 16 lines · Santosh
Quoted 15 lines · Tony Lindgren
Quoted 6 lines · Santosh Shilimkar
Quoted 4 lines
From: Tony Lindgren [mailto:tony at atomide.com]
Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
Hmm to me it seems that the
gic_arch_extnfunctions should be all NULL during runtime operation, and the wake-up generator should be programmed only before entering an idle state.Then the wake-up generator can be cleared after delivering the wake-up event(s).
Quoted 7 lines
Quoted 3 lines
Or am I missing something on why this should be enabled all the time?
Yep. The WakeupGen sits between GIC and CPU and can gate the interrupts in normal operation too. It's mandatory that the interrupt mask at GIC and WakeupGen matches to deliver the interrupt to CPU.
But it seems that the states of GIC and WakeupGen can be synced up just before hitting an idle mode.
And then the wake-ups only need to be acked after waking from idle and delivering the interrupts.
Quoted 2 lines
This is the reason why all the necessary GIC hooks are populated with it so that they work together.
Hmm I still see no reason to call these functions for every interrupt during runtime.
AFAIK, these functions only need to be called only once right after waking from idle.
Quoted 2 lines
So far without this patch all interrupts at WakeupGen level were always enabled and hence there was no issue.
OK so things work during runtime without calling these functions for every interrupt. Why then would we want to call them for each interrupt?
Regards,
Tony
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 20 lines · Tony Lindgren
Quoted 19 lines · Santosh
Quoted 18 lines · Tony Lindgren
Quoted 6 lines · Santosh Shilimkar
Quoted 4 lines
From: Tony Lindgren [mailto:tony at atomide.com]
Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
Hmm to me it seems that the
gic_arch_extnfunctions should be all NULL during runtime operation, and the wake-up generator should be programmed only before entering an idle state.Then the wake-up generator can be cleared after delivering the wake-up event(s).
Or am I missing something on why this should be enabled all the time?
Quoted 8 lines
Quoted 4 lines
Yep. The WakeupGen sits between GIC and CPU and can gate the interrupts in normal operation too. It's mandatory that the interrupt mask at GIC and WakeupGen matches to deliver the interrupt to CPU.
But it seems that the states of GIC and WakeupGen can be synced up just before hitting an idle mode.
Even during normal operation, WakeUpGen delivers external interrupts directly to the Interrupt Controller (GIC) in the CortexA9 MP Core.
Quoted 12 lines
And then the wake-ups only need to be acked after waking from idle and delivering the interrupts.
Quoted 2 lines
This is the reason why all the necessary GIC hooks are populated with it so that they work together.
Hmm I still see no reason to call these functions for every interrupt during runtime.
AFAIK, these functions only need to be called only once right after waking from idle.
No. That's pure hack. I think the name of the module "WakeupGen" seems to be the confusing point.
Quoted 7 lines
Quoted 2 lines
So far without this patch all interrupts at WakeupGen level were always enabled and hence there was no issue.
OK so things work during runtime without calling these functions for every interrupt. Why then would we want to call them for each interrupt?
Because that's the best way to ensure the synchronization between the GIC and Wakeupgen interrupts mask. The IRQ framework does this job and we don't have to hack low level idle code to make special arrangement.
FYI, this is not OMAP4 only problem but even other architectures based on Cortex-A9 needs an additional interrupt controller. And they are managed through the Linux IRQ framework.
As I said earlier it's another interrupt controller works along with GIC and it's control needs to be in kernel IRQ framework.
Regards
Santosh
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Tony LindgrenQuoted 24 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:20 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 01/21] OMAP4: PM: Add omap WakeupGen module supportQuoted 14 lines · Santosh Shilimkar
arch/arm/mach-omap2/omap4-common.c +1
-0@@ -21,6 +21,7 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 void __iomem *l2cache_base;@@ -41,6 +42,8 @@ void __init gic_init_irq(void) gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 );BUG_ON (!gic_cpu_base);
Quoted 7 lines
arch/arm/mach-omap2/omap4-common.c void __init gic_init_irq(void) · line 48
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+omap_wakeupgen_init (); +gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); }Do you really need to initialize all of this that early?
Yes. It's a interrupt controller extension and needs to work together with GIC.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
In reply to Santosh ShilimkarQuoted 15 lines · Santosh Shilimkar
This patch adds OMAP WakeupGen support. The WakeupGen unit is responsible for generating wakeup event from the incoming interrupts and enable bits. The WakeupGen is implemented in MPU Always-On power domain. During normal operation, WakeupGen delivers external interrupts directly to the GIC. When the CPUx asserts StandbyWFI, indicating it wants to enter lowpower state, the Standby Controller checks with the WakeupGen unit using the idlereq/idleack handshake to make sure there is no incoming interrupts. The GIC and WakeupGen needs to be kept in synchronisation for proper interrupt functioning.
Hence this patch hooks up the omap WakeupGen mask/unmask along with GIC using architecture specific hooks.
Signed-off-by Santosh Shilimkar <[email protected]>Cc Kevin Hilman <[email protected]>
<snip >
Quoted 17 lines
(quoted diff) +17
-0+static void _wakeupgen_clear(unsigned int irq) +{ + ? ? ? unsigned int cpu = smp_processor_id(); + ? ? ? u32 val, bit_number; + ? ? ? u8 i; + + ? ? ? if (_wakeupgen_get_irq_info(irq, &bit_number, &i)) + ? ? ? ? ? ? ? return; + + ? ? ? val = wakeupgen_readl(i, cpu); + ? ? ? val &= ~BIT(bit_number); + ? ? ? wakeupgen_writel(val, i, cpu); +} + +static void _wakeupgen_set(unsigned int irq) +{ + ? ? ? unsigned int cpu = smp_processor_id();
Review
Quoted 10 lines
(quoted diff) +10
-0+ ? ? ? u32 val, bit_number; + ? ? ? u8 i; + + ? ? ? if (_wakeupgen_get_irq_info(irq, &bit_number, &i)) + ? ? ? ? ? ? ? return; + + ? ? ? val = wakeupgen_readl(i, cpu); + ? ? ? val |= BIT(bit_number); + ? ? ? wakeupgen_writel(val, i, cpu); +}
Since you already call these from a function that takes a bool as an argument, using a bool argument here instead of duplicating everything for set and clear would be simpler.
<snip>
Quoted 30 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +30
-0+/* +* Architecture specific Mask extensiom +*/ +static void wakeupgen_mask (struct irq_data *d) +{ + ? ? ? spin_lock(&wakeupgen_lock); + ? ? ? _wakeupgen_clear(d->irq); + ? ? ? spin_unlock(&wakeupgen_lock); +} + +/* +* Architecture specific Unmask extensiom +*/ +static void wakeupgen_unmask (struct irq_data *d) +{ + + ? ? ? spin_lock(&wakeupgen_lock); + ? ? ? _wakeupgen_set(d->irq); + ? ? ? spin_unlock(&wakeupgen_lock); +} + +#ifdef CONFIG_PM +/* +* Architecture specific set_wake extension +*/ +static int wakeupgen_set_wake (struct irq_data *d,unsigned int on) +{ + ? ? ? spin_lock(&wakeupgen_lock); + ? ? ? if (on) + ? ? ? ? ? ? ? _wakeupgen_set(d->irq);
arch/arm/mach-omap2/omap-wakeupgen.c line 177
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +10
-0+ ? ? ? else + ? ? ? ? ? ? ? _wakeupgen_clear(d->irq); + ? ? ? spin_unlock(&wakeupgen_lock); + + ? ? ? return 0; +} + +#else +#define wakeupgen_set_wake ? ? NULL +#endif
I don't think these are correct, and it probably only works at all due to lazy disabling of interrupts during suspend.
First, unless I'm missing some code somewhere, all interrupts are still enabled during suspend. Any interrupt that has had enable_irq on it resulted in a call to wakeupgen_unmask, but when disable_irq is called on all the interrupts during suspend, masking is delayed until an interrupt is delivered. If no interrupt is delivered, all enabled irqs will still be enabled in the wakeupgen module in suspend, and they will all wake the device out of suspend.
Second, it is possible for a wake interrupt that should be enabled to end up disabled in suspend. Consider the following calls that occur in a driver during its suspend handler:
enable_irq_wake
...
wakeupgen_unmask (irq is now unmasked)disable_irq (lazy disable, wakeupgen_mask is not called, irq is still unmasked) <irq occurs>handle_level_irq
...
wakeupgen_mask (irq is now masked)
The irq will never get unmasked because it is marked disabled, and the irq will not wake the device from suspend.
wakeupgen_set_wake needs to set or clear bits in memory, and then those suspend masks need to be copied into the wakeupgen registers very late in suspend, after interrupts have been disabled at the cpu. I think syscore_ops is the right place.
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 42 lines · Colin Cross
Quoted 15 lines · Santosh Shilimkar
This patch adds OMAP WakeupGen support. The WakeupGen unit is responsible for generating wakeup event from the incoming interrupts and enable bits. The WakeupGen is implemented in MPU Always-On power domain. During normal operation, WakeupGen delivers external interrupts directly to the GIC. When the CPUx asserts StandbyWFI, indicating it wants to enter lowpower state, the Standby Controller checks with the WakeupGen unit using the idlereq/idleack handshake to make sure there is no incoming interrupts. The GIC and WakeupGen needs to be kept in synchronisation for proper interrupt functioning.
Hence this patch hooks up the omap WakeupGen mask/unmask along with GIC using architecture specific hooks.
Signed-off-by Santosh Shilimkar<[email protected]>Cc Kevin Hilman<[email protected]><snip>
Quoted 22 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +22
-0+static void _wakeupgen_clear (unsigned int irq) +{ +unsigned int cpu =smp_processor_id (); +u32 val, bit_number; +u8 i; + +if (_wakeupgen_get_irq_info (irq,&bit_number,&i)) +return ; + + val =wakeupgen_readl (i, cpu); + val&= ~BIT (bit_number); +wakeupgen_writel (val, i, cpu); +} + +static void _wakeupgen_set (unsigned int irq) +{ +unsigned int cpu =smp_processor_id (); +u32 val, bit_number; +u8 i; + +if (_wakeupgen_get_irq_info (irq,&bit_number,&i)) +return ;
Quoted 9 lines
arch/arm/mach-omap2/omap-wakeupgen.c line 120
Quoted 5 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +5
-0+ + val =wakeupgen_readl (i, cpu); + val |=BIT (bit_number); +wakeupgen_writel (val, i, cpu); +}Since you already call these from a function that takes a bool as an argument, using a bool argument here instead of duplicating everything for set and clear would be simpler.
First version of this patch has this done under single function as you said. Kevin suggested to have separate functions for better readability.
Quoted 46 lines
<snip>
Quoted 30 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +30
-0+/* +* Architecture specific Mask extensiom +*/ +static void wakeupgen_mask (struct irq_data *d) +{ +spin_lock (&wakeupgen_lock); +_wakeupgen_clear (d->irq); +spin_unlock (&wakeupgen_lock); +} + +/* +* Architecture specific Unmask extensiom +*/ +static void wakeupgen_unmask (struct irq_data *d) +{ + +spin_lock (&wakeupgen_lock); +_wakeupgen_set (d->irq); +spin_unlock (&wakeupgen_lock); +} + +#ifdef CONFIG_PM +/* +* Architecture specific set_wake extension +*/ +static int wakeupgen_set_wake (struct irq_data *d,unsigned int on) +{ +spin_lock (&wakeupgen_lock); +if (on) +_wakeupgen_set (d->irq);arch/arm/mach-omap2/omap-wakeupgen.c line 177
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +10
-0+ else + _wakeupgen_clear(d->irq); +spin_unlock (&wakeupgen_lock); + + return 0; +} + +#else +#define wakeupgen_set_wake NULL +#endif I don't think these are correct, and it probably only works at all due to lazy disabling of interrupts during suspend.
Quoted 8 lines
First, unless I'm missing some code somewhere, all interrupts are still enabled during suspend. Any interrupt that has had
enable_irqon it resulted in a call towakeupgen_unmask, but whendisable_irqis called on all the interrupts during suspend, masking is delayed until an interrupt is delivered. If no interrupt is delivered, all enabled irqs will still be enabled in the wakeupgen module in suspend, and they will all wake the device out of suspend.
During suspend it's expected that the drivers disables there interrupts as part of suspend hooks. One can used "set_wake" API's to enable/disable wakeups from suspend.
Quoted 13 lines
Second, it is possible for a wake interrupt that should be enabled to end up disabled in suspend. Consider the following calls that occur in a driver during its suspend handler:
enable_irq_wake
...
wakeupgen_unmask(irq is now unmasked)disable_irq(lazy disable,wakeupgen_maskis not called, irq is still unmasked) <irq occurs>handle_level_irq
...
wakeupgen_mask(irq is now masked)
Quoted 8 lines
The irq will never get unmasked because it is marked disabled, and the irq will not wake the device from suspend.
wakeupgen_set_wakeneeds to set or clear bits in memory, and then those suspend masks need to be copied into the wakeupgen registers very late in suspend, after interrupts have been disabled at the cpu. I thinksyscore_opsis the right place.
This is a good point about lazy disabling. Copy to memory happens already as part of save in SAR layout.
Will think over this one. Thanks for bringing this point here.
Regards
Santosh
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 113 lines · Santosh Shilimkar
Quoted 46 lines · Colin Cross
Quoted 17 lines · On Mon, Mar 28, 2011 at 2:22 AM, Santosh Shilimkar <[email protected]>…
This patch adds OMAP WakeupGen support. The WakeupGen unit is responsible for generating wakeup event from the incoming interrupts and enable bits. The WakeupGen is implemented in MPU Always-On power domain. During normal operation, WakeupGen delivers external interrupts directly to the GIC. When the CPUx asserts StandbyWFI, indicating it wants to enter lowpower state, the Standby Controller checks with the WakeupGen unit using the idlereq/idleack handshake to make sure there is no incoming interrupts. The GIC and WakeupGen needs to be kept in synchronisation for proper interrupt functioning.
Hence this patch hooks up the omap WakeupGen mask/unmask along with GIC using
architecture specific hooks.Signed-off-by Santosh Shilimkar<[email protected]>Cc Kevin Hilman<[email protected]><snip>
Quoted 23 lines
(quoted diff) +23
-0+static void _wakeupgen_clear(unsigned int irq) +{ + ? ? ? unsigned int cpu = smp_processor_id(); + ? ? ? u32 val, bit_number; + ? ? ? u8 i; + + ? ? ? if (_wakeupgen_get_irq_info(irq,&bit_number,&i)) + ? ? ? ? ? ? ? return; + + ? ? ? val = wakeupgen_readl(i, cpu); + ? ? ? val&= ~BIT(bit_number); + ? ? ? wakeupgen_writel(val, i, cpu); +} + +static void _wakeupgen_set(unsigned int irq) +{ + ? ? ? unsigned int cpu = smp_processor_id(); + ? ? ? u32 val, bit_number; + ? ? ? u8 i; + + ? ? ? if (_wakeupgen_get_irq_info(irq,&bit_number,&i)) + ? ? ? ? ? ? ? return; +Quoted 9 lines
Quoted 4 lines
+ ? ? ? val =
wakeupgen_readl(i, cpu);
+ ? ? ? val |=BIT(bit_number);
+ ? ? ?wakeupgen_writel(val, i, cpu);
+}Since you already call these from a function that takes a bool as an argument, using a bool argument here instead of duplicating everything for set and clear would be simpler.
First version of this patch has this done under single function as you said. Kevin suggested to have separate functions for better readability.
Quoted 46 lines
<snip>
Quoted 30 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +30
-0+/* +* Architecture specific Mask extensiom +*/ +static void wakeupgen_mask (struct irq_data *d) +{ + ? ? ? spin_lock(&wakeupgen_lock); + ? ? ? _wakeupgen_clear(d->irq); + ? ? ? spin_unlock(&wakeupgen_lock); +} + +/* +* Architecture specific Unmask extensiom +*/ +static void wakeupgen_unmask (struct irq_data *d) +{ + + ? ? ? spin_lock(&wakeupgen_lock); + ? ? ? _wakeupgen_set(d->irq); + ? ? ? spin_unlock(&wakeupgen_lock); +} + +#ifdef CONFIG_PM +/* +* Architecture specific set_wake extension +*/ +static int wakeupgen_set_wake (struct irq_data *d,unsigned int on) +{ + ? ? ? spin_lock(&wakeupgen_lock); + ? ? ? if (on) + ? ? ? ? ? ? ? _wakeupgen_set(d->irq);arch/arm/mach-omap2/omap-wakeupgen.c line 177
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +10
-0+ ? ? ? else + ? ? ? ? ? ? ? _wakeupgen_clear(d->irq); + ? ? ? spin_unlock(&wakeupgen_lock); + + ? ? ? return 0; +} + +#else +#define wakeupgen_set_wake ? ? NULL +#endif I don't think these are correct, and it probably only works at all due to lazy disabling of interrupts during suspend.
Quoted 8 lines
First, unless I'm missing some code somewhere, all interrupts are still enabled during suspend. ?Any interrupt that has had
enable_irqon it resulted in a call towakeupgen_unmask, but whendisable_irqis called on all the interrupts during suspend, masking is delayed until an interrupt is delivered. ?If no interrupt is delivered, all enabled irqs will still be enabled in the wakeupgen module in suspend, and they will all wake the device out of suspend.
Quoted 3 lines
During suspend it's expected that the drivers disables there interrupts as part of suspend hooks. One can used "
set_wake" API's to enable/disable wakeups from suspend.
But because of lazy masking, disabling an interrupt is not the same as masking. None of the interrupts will get masked, and they will all act as wakeup interrupts, even if enable_irq_wake was never called on it.
Quoted 18 lines
Quoted 18 lines
Second, it is possible for a wake interrupt that should be enabled to end up disabled in suspend. ?Consider the following calls that occur in a driver during its suspend handler:
enable_irq_wake
? ...
?wakeupgen_unmask(irq is now unmasked)disable_irq(lazy disable,wakeupgen_maskis not called, irq is still unmasked)
<irq occurs>handle_level_irq
? ...
?wakeupgen_mask(irq is now masked)The irq will never get unmasked because it is marked disabled, and the irq will not wake the device from suspend.
Quoted 8 lines
Quoted 5 lines
wakeupgen_set_wakeneeds to set or clear bits in memory, and then those suspend masks need to be copied into the wakeupgen registers very late in suspend, after interrupts have been disabled at the cpu. I thinksyscore_opsis the right place.This is a good point about lazy disabling. Copy to memory happens already as part of save in SAR layout.
Will think over this one. Thanks for bringing this point here.
The key is that mask/unmask and set_wake must act on different mask data - mask/unmask must take effect immediately, so they must write to the mask registers, but set_wake takes effect only during suspend, so it must write to a copy of the mask registers that gets switched in during suspend.
Quoted 3 lines
Regards
Santosh
PATCH v3 1/21 OMAP4: PM: Add omap WakeupGen module support
Quoted 3 lines · Colin Cross
Quoted 1 line · Santosh Shilimkar
On 4/2/2011 11:40 AM, Colin Cross wrote:
[....]
Quoted 67 lines
Quoted 31 lines
Quoted 23 lines
Quoted 9 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +9
-0+#ifdef CONFIG_PM +/* +* Architecture specific set_wake extension +*/ +static int wakeupgen_set_wake (struct irq_data *d,unsigned int on) +{ +spin_lock (&wakeupgen_lock); +if (on) +_wakeupgen_set (d->irq);arch/arm/mach-omap2/omap-wakeupgen.c line 177
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c new file +10
-0+ else + _wakeupgen_clear(d->irq); +spin_unlock (&wakeupgen_lock); + + return 0; +} + +#else +#define wakeupgen_set_wake NULL +#endif I don't think these are correct, and it probably only works at all due to lazy disabling of interrupts during suspend.
Quoted 8 lines
First, unless I'm missing some code somewhere, all interrupts are still enabled during suspend. Any interrupt that has had
enable_irqon it resulted in a call towakeupgen_unmask, but whendisable_irqis called on all the interrupts during suspend, masking is delayed until an interrupt is delivered. If no interrupt is delivered, all enabled irqs will still be enabled in the wakeupgen module in suspend, and they will all wake the device out of suspend.Quoted 3 lines
During suspend it's expected that the drivers disables there interrupts as part of suspend hooks. One can used "
set_wake" API's to enable/disable wakeups from suspend.But because of lazy masking, disabling an interrupt is not the same as masking. None of the interrupts will get masked, and they will all act as wakeup interrupts, even if
enable_irq_wakewas never called on it.Quoted 18 lines
Quoted 18 lines
Second, it is possible for a wake interrupt that should be enabled to end up disabled in suspend. Consider the following calls that occur in a driver during its suspend handler:
enable_irq_wake
...
wakeupgen_unmask(irq is now unmasked)disable_irq(lazy disable,wakeupgen_maskis not called, irq is still unmasked)
<irq occurs>handle_level_irq
...
wakeupgen_mask(irq is now masked)The irq will never get unmasked because it is marked disabled, and the irq will not wake the device from suspend.
Quoted 8 lines
Quoted 5 lines
wakeupgen_set_wakeneeds to set or clear bits in memory, and then those suspend masks need to be copied into the wakeupgen registers very late in suspend, after interrupts have been disabled at the cpu. I thinksyscore_opsis the right place.This is a good point about lazy disabling. Copy to memory happens already as part of save in SAR layout.
Will think over this one. Thanks for bringing this point here.
Quoted 6 lines
The key is that mask/unmask and
set_wakemust act on different mask data - mask/unmask must take effect immediately, so they must write to the mask registers, butset_waketakes effect only during suspend, so it must write to a copy of the mask registers that gets switched in during suspend.
Right. I shall fix the set_wake() API to take care of lazy disabling of IRQs.
Regards
Santosh
PATCH v3 2/21 OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit
In reply to Santosh ShilimkarOMAP L2X0 and GIC initialisation code uses BUG_ON() for the ioremap() failure scenarios.
Use WARN_ON() instead and allow graceful function exits.
This was suggsted by Kevin Hilman <[email protected]> during OMAP4 PM code review.
--- arch/arm/mach-omap2/omap4-common.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
arch/arm/mach-omap2/omap4-common.c +6 -3
@@ -36,11 +36,13 @@ void __init gic_init_irq(void)/* Static mapping, never released */ gic_dist_base_addr =ioremap (OMAP44XX_GIC_DIST_BASE ,SZ_4K ); -BUG_ON (!gic_dist_base_addr); +if (WARN_ON (!gic_dist_base_addr)) +return ;/* Static mapping, never released */ gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 ); -BUG_ON (!gic_cpu_base); +if (WARN_ON (!gic_cpu_base)) +return ;omap_wakeupgen_init ();
@@ -68,7 +70,8 @@ static int __init omap_l2_cache_init(void)/* Static mapping, never released */ l2cache_base =ioremap (OMAP44XX_L2CACHE_BASE ,SZ_4K ); -BUG_ON (!l2cache_base); +if (WARN_ON (!l2cache_base)) +return -ENODEV ;/* * 16-way associativity, parity disabled
Signature · 1 line
1.6.0.4
Tony Lindgren
maintainerPATCH v3 2/21 OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit
Quoted 35 lines · Santosh Shilimkar
OMAP L2X0 and GIC initialisation code uses
BUG_ON()for theioremap()failure scenarios.Use
WARN_ON()instead and allow graceful function exits.This was suggsted by Kevin Hilman <[email protected]> during OMAP4 PM code review.
Signed-off-by Santosh Shilimkar <[email protected]>Cc Kevin Hilman <[email protected]>--- arch/arm/mach-omap2/omap4-common.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)arch/arm/mach-omap2/omap4-common.c +4
-2@@ -36,11 +36,13 @@ void __init gic_init_irq(void)/* Static mapping, never released */ gic_dist_base_addr =ioremap (OMAP44XX_GIC_DIST_BASE ,SZ_4K ); -BUG_ON (!gic_dist_base_addr); +if (WARN_ON (!gic_dist_base_addr)) +return ;/* Static mapping, never released */ gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 ); -BUG_ON (!gic_cpu_base); +if (WARN_ON (!gic_cpu_base)) +return ;omap_wakeupgen_init ();
arch/arm/mach-omap2/omap4-common.c static int __init omap_l2_cache_init(void) · line 77
Quoted 9 lines
arch/arm/mach-omap2/omap4-common.c +2
-1@@ -68,7 +70,8 @@ static int __init omap_l2_cache_init(void)/* Static mapping, never released */ l2cache_base =ioremap (OMAP44XX_L2CACHE_BASE ,SZ_4K ); -BUG_ON (!l2cache_base); +if (WARN_ON (!l2cache_base)) +return -ENODEV ;/* * 16-way associativity, parity disabled
Hmm to me it seems that if any of these we don't want to continue.
Tony
PATCH v3 2/21 OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit
Quoted 43 lines · Tony Lindgren
Quoted 42 lines · Santosh Shilimkar
OMAP L2X0 and GIC initialisation code uses
BUG_ON()for theioremap()failure scenarios.Use
WARN_ON()instead and allow graceful function exits.This was suggsted by Kevin Hilman<[email protected]> during OMAP4 PM code review.
Signed-off-by Santosh Shilimkar<[email protected]>Cc Kevin Hilman<[email protected]>--- arch/arm/mach-omap2/omap4-common.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)arch/arm/mach-omap2/omap4-common.c +6
-3@@ -36,11 +36,13 @@ void __init gic_init_irq(void)/* Static mapping, never released */ gic_dist_base_addr =ioremap (OMAP44XX_GIC_DIST_BASE ,SZ_4K ); -BUG_ON (!gic_dist_base_addr); +if (WARN_ON (!gic_dist_base_addr)) +return ;/* Static mapping, never released */ gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 ); -BUG_ON (!gic_cpu_base); +if (WARN_ON (!gic_cpu_base)) +return ;omap_wakeupgen_init ();@@ -68,7 +70,8 @@ static int __init omap_l2_cache_init(void)/* Static mapping, never released */ l2cache_base =ioremap (OMAP44XX_L2CACHE_BASE ,SZ_4K ); -BUG_ON (!l2cache_base); +if (WARN_ON (!l2cache_base)) +return -ENODEV ;
Quoted 6 lines
arch/arm/mach-omap2/omap4-common.c static int __init omap_l2_cache_init(void) · line 77
Quoted 2 lines
arch/arm/mach-omap2/omap4-common.c +0
-0/* * 16-way associativity, parity disabled Hmm to me it seems that if any of these we don't want to continue.
L2 cache is no problem and kernel can boot without L2 cache support. I agree with you on interrupt controller init though.
Will drop the interrupt related checks from this patch.
Kevin, Are you ok with it ?
Regards
Santosh
PATCH v3 2/21 OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit
Quoted 50 lines · Santosh Shilimkar
Quoted 43 lines · Tony Lindgren
Quoted 42 lines · Santosh Shilimkar
OMAP L2X0 and GIC initialisation code uses
BUG_ON()for theioremap()failure scenarios.Use
WARN_ON()instead and allow graceful function exits.This was suggsted by Kevin Hilman<[email protected]> during OMAP4 PM code review.
Signed-off-by Santosh Shilimkar<[email protected]>Cc Kevin Hilman<[email protected]>--- arch/arm/mach-omap2/omap4-common.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)arch/arm/mach-omap2/omap4-common.c +6
-3@@ -36,11 +36,13 @@ void __init gic_init_irq(void)/* Static mapping, never released */ gic_dist_base_addr =ioremap (OMAP44XX_GIC_DIST_BASE ,SZ_4K ); -BUG_ON (!gic_dist_base_addr); +if (WARN_ON (!gic_dist_base_addr)) +return ;/* Static mapping, never released */ gic_cpu_base =ioremap (OMAP44XX_GIC_CPU_BASE ,SZ_512 ); -BUG_ON (!gic_cpu_base); +if (WARN_ON (!gic_cpu_base)) +return ;omap_wakeupgen_init ();@@ -68,7 +70,8 @@ static int __init omap_l2_cache_init(void)/* Static mapping, never released */ l2cache_base =ioremap (OMAP44XX_L2CACHE_BASE ,SZ_4K ); -BUG_ON (!l2cache_base); +if (WARN_ON (!l2cache_base)) +return -ENODEV ;Quoted 6 lines
arch/arm/mach-omap2/omap4-common.c static int __init omap_l2_cache_init(void) · line 77
Quoted 2 lines
arch/arm/mach-omap2/omap4-common.c +0
-0/* * 16-way associativity, parity disabled Hmm to me it seems that if any of these we don't want to continue.
Quoted 6 lines
L2 cache is no problem and kernel can boot without L2 cache support. I agree with you on interrupt controller init though.
Will drop the interrupt related checks from this patch.
Kevin, Are you ok with it ?
In general, BUG should only be used when the kernel really can not possibly continue[1]. I suppose inability to map the GIC falls into that category.
Kevin
[1] from asm-generic/bug.h:
/*
* Don't use BUG() or BUG_ON() unless there's really no way out; one
* example might be detecting data structure corruption in the middle
* of an operation that can't be backed out of. If the (sub)system
* can somehow continue operating, perhaps with reduced functionality,
* it's probably not BUG-worthy.
*
* If you're tempted to BUG(), think again: is completely giving up
* really the *only* solution? There are usually better options, where
* users don't need to reboot ASAP and can mostly shut down cleanly. */
PATCH v3 2/21 OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit
Quoted 5 lines · Kevin Hilman
Quoted 2 lines · Santosh Shilimkar
Quoted 1 line · Tony Lindgren
* Santosh Shilimkar<[email protected]> [110328 02:20]:
[...]
Quoted 11 lines
Quoted 6 lines
L2 cache is no problem and kernel can boot without L2 cache support. I agree with you on interrupt controller init though.
Will drop the interrupt related checks from this patch.
Kevin, Are you ok with it ?
In general, BUG should only be used when the kernel really can not possibly continue[1]. I suppose inability to map the GIC falls into that category.
Thanks. Will drop GIC ones.
Regards
Santosh
PATCH v3 3/21 OMAP4: PM: Export omap4_get_base*() rather than global address pointers
In reply to Santosh ShilimkarThis patch exports APIs to get base address for GIC distributor, CPU interface, SCU and PL310 L2 Cache which are used in OMAP4 PM code.
This was suggested by Kevin Hilman <[email protected]> during OMAP4 PM code review.
--- arch/arm/mach-omap2/include/mach/omap4-common.h | 13 +++++++++++-- arch/arm/mach-omap2/omap-smp.c | 6 ++++++ arch/arm/mach-omap2/omap4-common.c | 21 ++++++++++++++++++--- 3 files changed, 35 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/include/mach/omap4-common.h +11 -2
@@ -25,11 +25,20 @@#endif #ifdef CONFIG_CACHE_L2X0 -extern void __iomem *l2cache_base; +extern void __iomem *omap4_get_l2cache_base (void );#endif -extern void __iomem *gic_dist_base_addr; +#ifdef CONFIG_SMP +extern void __iomem *omap4_get_scu_base (void ); +#else +static inline void __iomem *omap4_get_scu_base (void ) +{ +return NULL ; +} +#endif +extern void __iomem *omap4_get_gic_dist_base (void ); +extern void __iomem *omap4_get_gic_cpu_base (void );extern void __init gic_init_irq (void );extern void omap_smc1 (u32 fn,u32 arg);
arch/arm/mach-omap2/omap-smp.c +6 -0
@@ -30,6 +30,12 @@ static void __iomem *scu_base;static DEFINE_SPINLOCK (boot_lock); + +void __iomem *omap4_get_scu_base (void ) +{ +return scu_base; +} +void __cpuinit platform_secondary_init (unsigned int cpu) {/*
arch/arm/mach-omap2/omap4-common.c +18 -3
@@ -24,15 +24,25 @@#include <mach/omap-wakeupgen.h> #ifdef CONFIG_CACHE_L2X0 -void __iomem *l2cache_base; +static void __iomem *l2cache_base;#endif -void __iomem *gic_dist_base_addr; +static void __iomem *gic_dist_base_addr; +static void __iomem *gic_cpu_base; +void __iomem *omap4_get_gic_dist_base (void ) +{ +return gic_dist_base_addr; +} + +void __iomem *omap4_get_gic_cpu_base (void ) +{ +return gic_cpu_base; +} +void __init gic_init_irq (void ) { -void __iomem *gic_cpu_base;/* Static mapping, never released */ gic_dist_base_addr =ioremap (OMAP44XX_GIC_DIST_BASE ,SZ_4K );
@@ -51,6 +61,11 @@ void __init gic_init_irq(void)#ifdef CONFIG_CACHE_L2X0 +void __iomem *omap4_get_l2cache_base (void ) +{ +return l2cache_base; +} +static void omap4_l2x0_disable (void ) {/* Disable PL310 L2 Cache controller */
Signature · 1 line
1.6.0.4
PATCH v3 4/21 OMAP4: PM: Add SAR RAM support
In reply to Santosh ShilimkarThis patch adds SAR RAM support on OMAP4430. SAR RAM used to save and restore the HW context in low power modes.
--- arch/arm/mach-omap2/include/mach/omap4-common.h | 1 + arch/arm/mach-omap2/omap4-common.c | 31 ++++++++++++++++++++++- arch/arm/mach-omap2/omap4-sar-layout.h | 22 ++++++++++++++++ arch/arm/plat-omap/include/plat/omap44xx.h | 1 + 4 files changed, 54 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/omap4-sar-layout.h
arch/arm/mach-omap2/include/mach/omap4-common.h +1 -0
@@ -39,6 +39,7 @@ static inline void __iomem *omap4_get_scu_base(void)extern void __iomem *omap4_get_gic_dist_base (void );extern void __iomem *omap4_get_gic_cpu_base (void ); +extern void __iomem *omap4_get_sar_ram_base (void );extern void __init gic_init_irq (void );extern void omap_smc1 (u32 fn,u32 arg);
arch/arm/mach-omap2/omap4-common.c +30 -1
@@ -23,13 +23,15 @@#include <mach/omap4-common.h> #include <mach/omap-wakeupgen.h> +#include "omap4-sar-layout.h" +#ifdef CONFIG_CACHE_L2X0 static void __iomem *l2cache_base;#endif static void __iomem *gic_dist_base_addr;static void __iomem *gic_cpu_base; - +static void __iomem *sar_ram_base;void __iomem *omap4_get_gic_dist_base (void ) {
@@ -125,3 +127,30 @@ static int __init omap_l2_cache_init(void) }early_initcall (omap_l2_cache_init);#endif + +void __iomem *omap4_get_sar_ram_base (void ) +{ +return sar_ram_base; +} + +/* +* SAR RAM used to save and restore the HW +* context in low power modes +*/ +static int __init omap4_sar_ram_init (void ) +{ +/* +* To avoid code running on other OMAPs in +* multi-omap builds +*/ +if (!cpu_is_omap44xx ()) +return -ENODEV ; + +/* Static mapping, never released */ + sar_ram_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_8K ); +if (WARN_ON (!sar_ram_base)) +return -ENODEV ; + +return 0 ; +} +early_initcall (omap4_sar_ram_init);
arch/arm/mach-omap2/omap4-sar-layout.h new file +22 -0
@@ -0,0 +1,22 @@ +/* +* omap4-sar-layout.h: OMAP4 SAR RAM layout header file +* +* Copyright (C) 2011 Texas Instruments, Inc. +* Santosh Shilimkar <[email protected]> +* +* 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. +*/ +#ifndef OMAP_ARCH_OMAP4_SAR_LAYOUT_H +#define OMAP_ARCH_OMAP4_SAR_LAYOUT_H + +/* +* SAR BANK offsets from base address OMAP44XX_SAR_RAM_BASE +*/ +#define SAR_BANK1_OFFSET 0x0000 +#define SAR_BANK2_OFFSET 0x1000 +#define SAR_BANK3_OFFSET 0x2000 +#define SAR_BANK4_OFFSET 0x3000 + +#endif
arch/arm/plat-omap/include/plat/omap44xx.h +1 -0
@@ -45,6 +45,7 @@#define OMAP44XX_WKUPGEN_BASE 0x48281000#define OMAP44XX_MCPDM_BASE 0x40132000#define OMAP44XX_MCPDM_L3_BASE 0x49032000 +#define OMAP44XX_SAR_RAM_BASE 0x4a326000#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
Signature · 1 line
1.6.0.4
PATCH v3 5/21 OMAP4: PM: Add CPUX OFF mode support
In reply to Santosh ShilimkarThis patch adds the CPU0 and CPU1 off mode support. CPUX close switch retention (CSWR) is not supported by hardware design.
The CPUx OFF mode isn't supported on OMAP4430 ES1.0
CPUx sleep code is common for hotplug, suspend and CPUilde.
--- arch/arm/mach-omap2/Makefile | 4 +- arch/arm/mach-omap2/include/mach/omap4-common.h | 46 +++ arch/arm/mach-omap2/omap4-mpuss-lowpower.c | 240 ++++++++++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 11 + arch/arm/mach-omap2/pm44xx.c | 6 + arch/arm/mach-omap2/sleep44xx.S | 339 +++++++++++++++++++++++ 6 files changed, 645 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/omap4-mpuss-lowpower.c create mode 100644 arch/arm/mach-omap2/sleep44xx.S
arch/arm/mach-omap2/Makefile +3 -1
@@ -63,13 +63,15 @@ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ cpuidle34xx.o pm_bus.o -obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o +obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o \ + omap4-mpuss-lowpower.o sleep44xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a +AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a ifeq ($(CONFIG_PM_VERBOSE),y) CFLAGS_pm_bus.o += -DDEBUG
arch/arm/mach-omap2/include/mach/omap4-common.h +46 -0
56 lines not on this page · raw message
arch/arm/mach-omap2/omap4-mpuss-lowpower.c new file +240 -0
240 lines not on this page · raw message
arch/arm/mach-omap2/omap4-sar-layout.h +11 -0
@@ -19,4 +19,15 @@#define SAR_BANK3_OFFSET 0x2000#define SAR_BANK4_OFFSET 0x3000 +/* Scratch pad memory offsets from SAR_BANK1 */ +#define CPU0_SAVE_OFFSET 0xb00 +#define CPU1_SAVE_OFFSET 0xc00 +#define MMU_OFFSET 0xd00 +#define SCU_OFFSET0 0xd20 +#define SCU_OFFSET1 0xd24 + +/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */ +#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04 +#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08 +#endif
arch/arm/mach-omap2/pm44xx.c +6 -0
@@ -111,6 +111,12 @@ static int __init omap4_pm_init(void) goto err2; } + ret =omap4_mpuss_init (); +if (ret) { +pr_err ("Failed to initialise OMAP4 MPUSS\n" ); + goto err2; + } +#ifdef CONFIG_SUSPEND suspend_set_ops (&omap_pm_ops);#endif /* CONFIG_SUSPEND */
arch/arm/mach-omap2/sleep44xx.S new file +339 -0
339 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH v3 6/21 OMAP4: PM: Initialise all the clockdomains to supported states
In reply to Santosh ShilimkarInitialise hardware supervised mode for all clockdomains if it's supported. Initiate sleep transition for other clockdomains, if they are not being used.
--- arch/arm/mach-omap2/pm44xx.c | 22 +++++++++++++++++++++- 1 files changed, 21 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/pm44xx.c +21 -1
@@ -16,9 +16,11 @@#include <linux/err.h> #include <linux/slab.h> -#include "powerdomain.h" #include <mach/omap4-common.h> +#include "powerdomain.h" +#include "clockdomain.h" +struct power_state {struct powerdomain *pwrdm;u32 next_state;
@@ -73,6 +75,22 @@ static const struct platform_suspend_ops omap_pm_ops = { };#endif /* CONFIG_SUSPEND */ +/* +* Enable hardware supervised mode for all clockdomains if it's +* supported. Initiate sleep transition for other clockdomains, if +* they are not used +*/ +static int __init clkdms_setup (struct clockdomain *clkdm,void *unused) +{ +if (clkdm->flags &CLKDM_CAN_ENABLE_AUTO ) +clkdm_allow_idle (clkdm); +else if (clkdm->flags &CLKDM_CAN_FORCE_SLEEP && +atomic_read (&clkdm->usecount) ==0 ) +clkdm_sleep (clkdm); +return 0 ; +} + +static int __init pwrdms_setup (struct powerdomain *pwrdm,void *unused) {struct power_state *pwrst;
@@ -111,6 +129,8 @@ static int __init omap4_pm_init(void) goto err2; } + (void )clkdm_for_each (clkdms_setup,NULL ); + ret =omap4_mpuss_init ();if (ret) {pr_err ("Failed to initialise OMAP4 MPUSS\n" );
Signature · 1 line
1.6.0.4
PATCH v3 7/21 OMAP4: PM: Program CPU1 to hit OFF when off-lined
In reply to Santosh ShilimkarProgram non-boot CPUs to hit lowest supported power state when it is off-lined using cpu hotplug framework.
--- arch/arm/mach-omap2/omap-hotplug.c | 18 +++++++++++++----- 1 files changed, 13 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/omap-hotplug.c +13 -5
@@ -20,6 +20,9 @@#include <asm/cacheflush.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> + +#include "powerdomain.h" int platform_cpu_kill (unsigned int cpu) {
@@ -32,6 +35,8 @@ int platform_cpu_kill(unsigned int cpu)*/ void platform_cpu_die (unsigned int cpu) { +unsigned int this_cpu; +flush_cache_all ();dsb ();
@@ -39,18 +44,21 @@ void platform_cpu_die(unsigned int cpu)* we're ready for shutdown now, so do it */ if (omap_modify_auxcoreboot0 (0x0 ,0x200 ) !=0x0 ) -printk (KERN_CRIT "Secure clear status failed\n" ); +pr_err ("Secure clear status failed\n" );for (;;) {/* -* Execute WFI +* Enter into low power state +* clear all interrupt wakeup sources */ -do_wfi (); - -if (omap_read_auxcoreboot0 () == cpu) { +omap_wakeupgen_irqmask_all (cpu,1 ); +omap4_enter_lowpower (cpu,PWRDM_POWER_OFF ); + this_cpu =hard_smp_processor_id (); +if (omap_read_auxcoreboot0 () == this_cpu) {/* * OK, proper wakeup, we're done */ +omap_wakeupgen_irqmask_all (this_cpu,0 );break ; }pr_debug ("CPU%u: spurious wakeup call\n" , cpu);
Signature · 1 line
1.6.0.4
PATCH v3 8/21 OMAP4: PM: CPU1 wakeup workaround from Low power modes
In reply to Santosh ShilimkarThe SGI(Software Generated Interrupts) are not wakeup capable from low power states. This is known limitation on OMAP4 and needs to be worked around by using software forced clockdomain wake-up. CPU0 forces the CPU1 clockdomain to software force wakeup. After the wakeup, CPU1 restores its clockdomain hardware supervised mode.
More details can be found in OMAP4430 TRM - Version J Section :
4.3.4.2 Power States of CPU0 and CPU1
--- arch/arm/mach-omap2/omap-hotplug.c | 8 ++++++++ arch/arm/mach-omap2/omap-smp.c | 26 +++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap-hotplug.c +8 -0
@@ -23,6 +23,7 @@#include <mach/omap-wakeupgen.h> #include "powerdomain.h" +#include "clockdomain.h" int platform_cpu_kill (unsigned int cpu) {
@@ -36,6 +37,10 @@ int platform_cpu_kill(unsigned int cpu)void platform_cpu_die (unsigned int cpu) {unsigned int this_cpu; +static struct clockdomain *cpu1_clkdm; + +if (!cpu1_clkdm) + cpu1_clkdm =clkdm_lookup ("mpu1_clkdm" );flush_cache_all ();dsb ();
@@ -59,6 +64,9 @@ void platform_cpu_die(unsigned int cpu)* OK, proper wakeup, we're done */ omap_wakeupgen_irqmask_all (this_cpu,0 ); + +/* Restore clockdomain to hardware supervised */ +clkdm_allow_idle (cpu1_clkdm);break ; }pr_debug ("CPU%u: spurious wakeup call\n" , cpu);
arch/arm/mach-omap2/omap-smp.c +25 -1
@@ -25,6 +25,8 @@#include <mach/hardware.h> #include <mach/omap4-common.h> +#include "clockdomain.h" +/* SCU base address */ static void __iomem *scu_base;
@@ -54,6 +56,8 @@ void __cpuinit platform_secondary_init(unsigned int cpu)int __cpuinit boot_secondary (unsigned int cpu,struct task_struct *idle) { +static struct clockdomain *cpu1_clkdm; +static bool booted;/* * Set synchronisation state between this boot processor * and the secondary one
@@ -69,7 +73,27 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)omap_modify_auxcoreboot0 (0x200 ,0xfffffdff );flush_cache_all ();smp_wmb (); -smp_cross_call (cpumask_of (cpu),1 ); + +if (!cpu1_clkdm) + cpu1_clkdm =clkdm_lookup ("mpu1_clkdm" ); + +/* +* The SGI(Software Generated Interrupts) are not wakeup capable +* from low power states. This is known limitation on OMAP4 and +* needs to be worked around by using software forced clockdomain +* wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to +* software force wakeup. After the wakeup, CPU1 restores its +* clockdomain hardware supervised mode. +* More details can be found in OMAP4430 TRM - Version J +* Section : +* 4.3.4.2 Power States of CPU0 and CPU1 +*/ +if (booted) { +clkdm_wakeup (cpu1_clkdm); + }else { +dsb_sev (); + booted = true; + }/* * Now the secondary core is starting up let it run its
Signature · 1 line
1.6.0.4
PATCH v3 9/21 OMAP4: PM: Add GIC distributor and interface enable/disable accessory API
In reply to Santosh ShilimkarThe power management code needs to have access to enable/disable the gic cpu interface and distributor based on targetted low power states.
These APIs are suppose to me moved to common ARM GIC library and patch for the same was posted earlier. The GIC code refactoring is ongoing and hence for time being this is kept under OMAP code so that OMAP4 PM can continue to work.
Discussion thread:
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg42940.html
--- arch/arm/mach-omap2/include/mach/omap4-common.h | 5 +++- arch/arm/mach-omap2/omap4-common.c | 24 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/include/mach/omap4-common.h +4 -1
@@ -44,6 +44,10 @@ extern void __iomem *omap4_get_gic_dist_base(void);extern void __iomem *omap4_get_gic_cpu_base (void );extern void __iomem *omap4_get_sar_ram_base (void );extern void __init gic_init_irq (void ); +extern void gic_cpu_enable (void ); +extern void gic_cpu_disable (void ); +extern void gic_dist_enable (void ); +extern void gic_dist_disable (void );extern void omap_smc1 (u32 fn,u32 arg);/*
@@ -64,7 +68,6 @@ extern int omap4_mpuss_init(void);extern int omap4_enter_lowpower (unsigned int cpu,unsigned int power_state);extern void omap4_cpu_suspend (unsigned int cpu,unsigned int save_state);extern void omap4_cpu_resume (void ); -#else static inline int omap4_enter_lowpower(unsigned int cpu,
arch/arm/mach-omap2/omap4-common.c +24 -0
@@ -61,6 +61,30 @@ void __init gic_init_irq(void)gic_init (0 ,29 , gic_dist_base_addr, gic_cpu_base); } +/* +* FIXME: Remove this GIC APIs once common GIG library starts +* supporting it. +*/ +void gic_cpu_enable (void ) +{ +__raw_writel (0xf0 , gic_cpu_base +GIC_CPU_PRIMASK ); +__raw_writel (1 , gic_cpu_base +GIC_CPU_CTRL ); +} + +void gic_cpu_disable (void ) +{ +__raw_writel (0 , gic_cpu_base +GIC_CPU_CTRL ); +} + +void gic_dist_enable (void ) +{ +__raw_writel (0x1 , gic_dist_base_addr +GIC_DIST_CTRL ); +} +void gic_dist_disable (void ) +{ +__raw_writel (0 , gic_dist_base_addr +GIC_CPU_CTRL ); +} +#ifdef CONFIG_CACHE_L2X0 void __iomem *omap4_get_l2cache_base (void )
Signature · 1 line
1.6.0.4
PATCH v3 10/21 OMAP4: PM: Add GIC save/restore support
In reply to Santosh ShilimkarOn OMAP4 when attempting MPU off-mode or OSWR, the GIC context is lost. This patch adds GIC context save and restore support.
The context save is done by software and restore is done by ROM code from predefined SAR locations where the context supposed to be saved. Refer to OMAP4430 TRM for the SAR RAM layout.
--- arch/arm/mach-omap2/omap-hotplug.c | 4 + arch/arm/mach-omap2/omap4-mpuss-lowpower.c | 195 +++++++++++++++++++++++++++- arch/arm/mach-omap2/omap4-sar-layout.h | 20 +++ 3 files changed, 213 insertions(+), 6 deletions(-)
arch/arm/mach-omap2/omap-hotplug.c +4 -0
@@ -19,6 +19,8 @@#include <linux/smp.h> #include <asm/cacheflush.h> +#include <asm/hardware/gic.h> +#include <mach/omap4-common.h> #include <mach/omap-wakeupgen.h>
@@ -57,6 +59,7 @@ void platform_cpu_die(unsigned int cpu)* clear all interrupt wakeup sources */ omap_wakeupgen_irqmask_all (cpu,1 ); +gic_cpu_disable ();omap4_enter_lowpower (cpu,PWRDM_POWER_OFF ); this_cpu =hard_smp_processor_id ();if (omap_read_auxcoreboot0 () == this_cpu) {
@@ -64,6 +67,7 @@ void platform_cpu_die(unsigned int cpu)* OK, proper wakeup, we're done */ omap_wakeupgen_irqmask_all (this_cpu,0 ); +gic_cpu_enable ();/* Restore clockdomain to hardware supervised */ clkdm_allow_idle (cpu1_clkdm);
arch/arm/mach-omap2/omap4-mpuss-lowpower.c +189 -6
267 lines not on this page · raw message
arch/arm/mach-omap2/omap4-sar-layout.h +20 -0
@@ -30,4 +30,24 @@#define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04#define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08 +/* GIC save restore offset from SAR_BANK3 */ +#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500) +#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504) +#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508) +#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c) +#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510) +#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514) +#define ICDISER_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x524) +#define ICDISER_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x528) +#define ICDISER_SPI_OFFSET (SAR_BANK3_OFFSET + 0x52c) +#define ICDIPR_SFI_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x53c) +#define ICDIPR_PPI_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x54c) +#define ICDIPR_SFI_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x550) +#define ICDIPR_PPI_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x560) +#define ICDIPR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x564) +#define ICDIPTR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x5e4) +#define ICDICFR_OFFSET (SAR_BANK3_OFFSET + 0x664) +#define SAR_BACKUP_STATUS_GIC_CPU0 0x1 +#define SAR_BACKUP_STATUS_GIC_CPU1 0x2 +#endif
Signature · 1 line
1.6.0.4
PATCH v3 11/21 OMAP4: PM: Add WakeupGen save/restore support
In reply to Santosh ShilimkarWakeupGen IP is integrated along with GIC to manage the interrupt wakeups from CPU low power states. It's located in always ON power domain. It manages masking/unmasking of Shared peripheral interrupts(SPI).So the interrupt enable/disable control should be in sync and consistent at WakeupGen and GIC so that interrupts are not lost.
Considering this GIC and WakeupGen save and restore is done together.
--- arch/arm/mach-omap2/include/mach/omap-wakeupgen.h | 1 + arch/arm/mach-omap2/omap-wakeupgen.c | 81 +++++++++++++++++++++ arch/arm/mach-omap2/omap4-mpuss-lowpower.c | 2 + arch/arm/mach-omap2/omap4-sar-layout.h | 11 +++ 4 files changed, 95 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/include/mach/omap-wakeupgen.h +1 -0
@@ -37,4 +37,5 @@extern int __init omap_wakeupgen_init (void );extern void omap_wakeupgen_irqmask_all (unsigned int cpu,unsigned int set); +extern void omap_wakeupgen_save (void );#endif
arch/arm/mach-omap2/omap-wakeupgen.c +81 -0
102 lines not on this page · raw message
arch/arm/mach-omap2/omap4-mpuss-lowpower.c +2 -0
@@ -52,6 +52,7 @@#include <plat/omap44xx.h> #include <mach/omap4-common.h> +#include <mach/omap-wakeupgen.h> #include "omap4-sar-layout.h" #include "pm.h"
@@ -292,6 +293,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* GIC lost during MPU OFF and OSWR */ if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) { +omap_wakeupgen_save ();gic_save_context (); save_state =3 ; }
arch/arm/mach-omap2/omap4-sar-layout.h +11 -0
@@ -50,4 +50,15 @@#define SAR_BACKUP_STATUS_GIC_CPU0 0x1#define SAR_BACKUP_STATUS_GIC_CPU1 0x2 +/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ +#define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684) +#define WAKEUPGENENB_SECURE_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x694) +#define WAKEUPGENENB_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6a4) +#define WAKEUPGENENB_SECURE_OFFSET_CPU1 (SAR_BANK3_OFFSET + 0x6b4) +#define AUXCOREBOOT0_OFFSET (SAR_BANK3_OFFSET + 0x6c4) +#define AUXCOREBOOT1_OFFSET (SAR_BANK3_OFFSET + 0x6c8) +#define PTMSYNCREQ_MASK_OFFSET (SAR_BANK3_OFFSET + 0x6cc) +#define PTMSYNCREQ_EN_OFFSET (SAR_BANK3_OFFSET + 0x6d0) +#define SAR_BACKUP_STATUS_WAKEUPGEN 0x10 +#endif
Signature · 1 line
1.6.0.4
PATCH v3 12/21 OMAP4: PM: Add L2 cache lowpower support
In reply to Santosh ShilimkarWhen MPUSS hits off-mode e, L2 cache is lost. This patch adds L2X0 necessary maintenance operations and context restoration in the low power code.
--- arch/arm/mach-omap2/omap4-mpuss-lowpower.c | 18 ++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 2 + arch/arm/mach-omap2/sleep44xx.S | 65 ++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap4-mpuss-lowpower.c +18 -0
@@ -49,6 +49,7 @@#include <asm/system.h> #include <asm/irq.h> #include <asm/hardware/gic.h> +#include <asm/hardware/cache-l2x0.h> #include <plat/omap44xx.h> #include <mach/omap4-common.h>
@@ -336,6 +337,21 @@ ret:return 0 ; } +static void save_l2x0_auxctrl (void ) +{ +#ifdef CONFIG_CACHE_L2X0 +/* +* Save the L2X0 AUXCTRL value to SAR memory. Its used to +* in every restore patch MPUSS OFF path. +*/ +void __iomem *l2x0_base =omap4_get_l2cache_base (); +u32 val; + + val =__raw_readl (l2x0_base +L2X0_AUX_CTRL ); +__raw_writel (val, sar_base +L2X0_AUXCTRL_OFFSET ); +#endif +} +/* * Initialise OMAP4 MPUSS */
@@ -418,6 +434,8 @@ int __init omap4_mpuss_init(void)for (i =0 ; i < max_spi_reg; i++)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i); +save_l2x0_auxctrl (); +return 0 ; }
arch/arm/mach-omap2/omap4-sar-layout.h +2 -0
@@ -25,6 +25,8 @@#define MMU_OFFSET 0xd00#define SCU_OFFSET0 0xd20#define SCU_OFFSET1 0xd24 +#define L2X0_OFFSET 0xd28 +#define L2X0_AUXCTRL_OFFSET 0xd2c/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */ #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04
arch/arm/mach-omap2/sleep44xx.S +65 -0
91 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH v3 13/21 OMAP4: suspend: Add MPUSS RET and OFF support
In reply to Santosh ShilimkarThis patch adds MPUSS(MPU Sub System) RET and OFF mode support to suspend path. For both MPUSS RET and OFF support, CPUs are programmed to OFF state.
Only MPUSS RET and OFF supported at this point of time. CORE RET will be added subsequently.
--- arch/arm/mach-omap2/omap4-mpuss-lowpower.c | 6 ++- arch/arm/mach-omap2/pm44xx.c | 67 ++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/omap4-mpuss-lowpower.c +5 -1
@@ -25,7 +25,7 @@* ON(Inactive) OFF ON(Inactive) * OFF OFF CSWR * OFF OFF OSWR (*TBD) -* OFF OFF OFF* (*TBD) +* OFF OFF OFF * ---------------------------------------------- * * Note: CPU0 is the master core and it is the last CPU to go down
@@ -293,6 +293,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* Check MPUSS next state and save GIC if needed * GIC lost during MPU OFF and OSWR */ +pwrdm_clear_all_prev_pwrst (mpuss_pd);if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) {omap_wakeupgen_save ();gic_save_context ();
@@ -414,6 +415,9 @@ int __init omap4_mpuss_init(void)return -ENODEV ; } +/* Clear CPU previous power domain state */ +pwrdm_clear_all_prev_pwrst (mpuss_pd); +/* * Find out how many interrupts are supported. * OMAP4 supports max of 128 SPIs where as GIC can support
arch/arm/mach-omap2/pm44xx.c +63 -4
92 lines not on this page · raw message
Signature · 1 line
1.6.0.4
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Santosh ShilimkarThis patch adds configurable wakeup timer support in suspend. Also for statistics pm counter support is added.
--- arch/arm/mach-omap2/omap4-mpuss-lowpower.c | 4 ++++ arch/arm/mach-omap2/pm-debug.c | 11 +++++++++-- arch/arm/mach-omap2/pm44xx.c | 6 ++++++ 3 files changed, 19 insertions(+), 2 deletions(-)
arch/arm/mach-omap2/omap4-mpuss-lowpower.c +4 -0
@@ -289,6 +289,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)if (cpu) goto cpu_prepare; +pwrdm_pre_transition (); +/* * Check MPUSS next state and save GIC if needed * GIC lost during MPU OFF and OSWR
@@ -334,6 +336,8 @@ cpu_prepare:gic_dist_enable (); } +pwrdm_post_transition (); + ret:return 0 ; }
arch/arm/mach-omap2/pm-debug.c +9 -2
@@ -604,9 +604,11 @@ static int __init pm_dbg_init(void)if (pm_dbg_init_done)return 0 ; -if (cpu_is_omap34xx ()) +if (cpu_is_omap34xx ()) { pm_dbg_reg_modules = omap3_pm_reg_modules; -else { + }else if (cpu_is_omap44xx ()) { +/* Allow pm_dbg_init on OMAP4. */ + }else {printk (KERN_ERR "%s: only OMAP3 supported\n" , __func__);return -ENODEV ; }
@@ -622,6 +624,9 @@ static int __init pm_dbg_init(void)pwrdm_for_each (pwrdms_setup, (void *)d); +if (cpu_is_omap44xx ()) + goto skip_reg_debufs; + pm_dbg_dir =debugfs_create_dir ("registers" , d);if (IS_ERR (pm_dbg_dir))return PTR_ERR (pm_dbg_dir);
@@ -641,6 +646,8 @@ static int __init pm_dbg_init(void) &enable_off_mode, &pm_dbg_option_fops); (void )debugfs_create_file ("sleep_while_idle" ,S_IRUGO |S_IWUSR , d, &sleep_while_idle, &pm_dbg_option_fops); + +skip_reg_debufs: (void )debugfs_create_file ("wakeup_timer_seconds" ,S_IRUGO |S_IWUSR , d, &wakeup_timer_seconds, &pm_dbg_option_fops); (void) debugfs_create_file("wakeup_timer_milliseconds",
arch/arm/mach-omap2/pm44xx.c +6 -0
@@ -21,6 +21,7 @@#include "powerdomain.h" #include "clockdomain.h" +#include "pm.h" struct power_state {struct powerdomain *pwrdm;
@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id (); +/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state =pwrdm_read_next_pwrst (pwrst->pwrdm);
Signature · 1 line
1.6.0.4
Tony Lindgren
maintainerPATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
Quoted 4 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;
arch/arm/mach-omap2/pm-debug.c static int omap4_pm_suspend(void) · line 51
Quoted 10 lines
arch/arm/mach-omap2/pm-debug.c +5
-0u32 cpu_id =smp_processor_id (); +/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state =pwrdm_read_next_pwrst (pwrst->pwrdm);
This hack to mess diretly with sys_timer will be ripped out, so please drop this patch.
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Tony
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
Quoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
Sorry for spamming your inbox with same email. :(
Looks like my mailer has srewed up. It send same messege almost 20 times and it shows me that it has
stuck in outbox
Regards
Santosh
Quoted 29 lines · Santosh Shilimkar
Quoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:[email protected]]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: [email protected]; [email protected]; [email protected]; [email protected]
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Quoted 9 lines
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 14/21 OMAP4: pm-debug: Add wakeup timer and debug counters
In reply to Tony LindgrenQuoted 16 lines
-----Original Message-----
From: Tony Lindgren [mailto:tony at atomide.com]
Sent: Tuesday, March 29, 2011 2:31 AM
To: Santosh Shilimkar
Cc: linux-omap at vger.kernel.org; khilman at ti.com; rnayak at ti.com; linux-arm-kernel at lists.infradead.org
Subject: Re: [pm-core][PATCH v3 14/21] OMAP4: pm-debug: Add wakeup timer and debug countersQuoted 6 lines · Santosh Shilimkar
arch/arm/mach-omap2/pm-debug.c +0
-0@@ -40,6 +41,11 @@ static int omap4_pm_suspend(void)int state, ret =0 ;u32 cpu_id =smp_processor_id ();
Quoted 13 lines
Quoted 9 lines
arch/arm/mach-omap2/pm-debug.c +5
-0+/* Wakeup timer from suspend */ +if (wakeup_timer_seconds || wakeup_timer_milliseconds) +omap2_pm_wakeup_on_timer (wakeup_timer_seconds, + wakeup_timer_milliseconds); +/* Save current powerdomain state */ list_for_each_entry (pwrst, &pwrst_list, node) { pwrst->saved_state = pwrdm_read_next_pwrst(pwrst-pwrdm);
This hack to mess diretly with
sys_timerwill be ripped out, so please drop this patch.
Ok.
Quoted 3 lines
In the long run we'll have dmtimer1 dedicated to the PM code, so then it's possible to do similar things.
Regards,
Santosh
PATCH v3 15/21 OMAP4: cpuidle: Basic CPUidle support
In reply to Santosh ShilimkarFrom: Rajendra Nayak <[email protected]>
The patch adds a basic CPUidle driver for OMAP4. Just one C state is registered for CPU0 which does a WFI. CPU1 is left with defualt idle and the low power state for it is managed via cpu-hotplug.
--- arch/arm/mach-omap2/Makefile | 3 +- arch/arm/mach-omap2/cpuidle44xx.c | 161 +++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm44xx.c | 2 + 4 files changed, 166 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/cpuidle44xx.c
arch/arm/mach-omap2/Makefile +2 -1
@@ -64,7 +64,8 @@ obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o \ cpuidle34xx.o pm_bus.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o \ - omap4-mpuss-lowpower.o sleep44xx.o + omap4-mpuss-lowpower.o sleep44xx.o \ + cpuidle44xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
arch/arm/mach-omap2/cpuidle44xx.c new file +161 -0
161 lines not on this page · raw message
arch/arm/mach-omap2/pm.h +1 -0
@@ -21,6 +21,7 @@ extern void omap_sram_idle(void);extern int omap3_can_sleep (void );extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap3_idle_init (void ); +extern int omap4_idle_init (void );#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );
arch/arm/mach-omap2/pm44xx.c +2 -0
@@ -206,6 +206,8 @@ static int __init omap4_pm_init(void)suspend_set_ops (&omap_pm_ops);#endif /* CONFIG_SUSPEND */ +omap4_idle_init (); + err2:return ret; }
Signature · 1 line
1.6.0.4
PATCH v3 16/21 OMAP4: cpuidle: Add MPUSS RET OFF states
In reply to Santosh ShilimkarThis patch adds MPUSS low power states in cpuidle.
C1 - CPU0 ON + CPU1 ON + MPU ON
C2 - CPU0 ON + CPU1 OFF + MPU ON
C3 - CPU0 OFF + CPU1 OFF + MPU CSWR
C4 - CPU0 OFF + CPU1 OFF + MPU OFF
MPU OSWR isn't supported yet. To support OSWR, power domain context registers needs to be managed which are not supported yet. A patch to address this was submitted but it's not ready for merge yet because it was not addressing all OMAP4 power domain context registers. More info on this issue:
http://www.mail-archive.com/linux-omap at vger.kernel.org/msg38667.html
OMAP4 powerdomain INACTIVE support is also dropped because of inconsistency of it with OMAP3. More information on this thread.
http://www.spinics.net/lists/linux-omap/msg45370.html
CORE low power states and associated latencies will be updated as part along with chip retention support.
On OMAP4 because of hardware constraints, no low power states are targeted when both CPUs are online and in SMP mode. The low power states are attempted only when secondary CPU gets offline to OFF through hotplug infrastructure.
Thanks to Nicole Chalhoub <[email protected]> for doing exhaustive C-state latency profiling.
--- arch/arm/mach-omap2/cpuidle44xx.c | 129 +++++++++++++++++++++++++++++++++++-- 1 files changed, 124 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/cpuidle44xx.c +124 -5
@@ -3,6 +3,7 @@* * Copyright (C) 2011 Texas Instruments, Inc. * Rajendra Nayak <[email protected]> +* Santosh Shilimkar <[email protected]> * * 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
@@ -17,12 +18,20 @@#include <mach/omap4-common.h> #include "pm.h" +#include "prm.h" #ifdef CONFIG_CPU_IDLE -#define OMAP4_MAX_STATES 1 +#define OMAP4_MAX_STATES 4 + /* C1 - CPU0 ON + + CPU1 ON + MPU ON + CORE ON */ #define OMAP4_STATE_C1 0 +/* C2 - CPU0 ON + CPU1 OFF + MPU ON + CORE ON */ +#define OMAP4_STATE_C2 1 +/* C3 - CPU0 OFF + CPU1 OFF + MPU CSWR + CORE ON */ +#define OMAP4_STATE_C3 2 +/* C4 - CPU0 OFF + CPU1 OFF + MPU OFF + CORE ON */ +#define OMAP4_STATE_C4 3 struct omap4_processor_cx { u8 valid;
@@ -31,16 +40,34 @@ struct omap4_processor_cx {u32 wakeup_latency;u32 cpu0_state;u32 mpu_state; +u32 mpu_logic_state;u32 core_state; +u32 core_logic_state;u32 threshold;u32 flags; +const char *desc; };struct omap4_processor_cx omap4_power_states[OMAP4_MAX_STATES ]; +static struct powerdomain *mpu_pd, *cpu1_pd, *core_pd; +/* +* FIXME: Full latency numbers needs to be updated as part of +* cpuidle CORE retention support. +* Currently only MPUSS latency numbers are added based on +* measurements done internally. The numbers for MPUSS are +* not board dependent and hence set directly here instead of +* passing it from board files. +*/ static struct cpuidle_params cpuidle_params_table[] = { -/* C1 */ - {1 ,2 ,2 ,5 }, +/* C1 - CPU0 ON + CPU1 ON + MPU ON + CORE ON */ + {1 ,2 ,2 ,5 }, +/* C2 - CPU0 ON + CPU1 OFF + MPU ON + CORE ON */ + {1 ,140 ,160 ,300 }, +/* C3 - CPU0 OFF + CPU1 OFF + MPU CSWR + CORE ON */ + {1 ,200 ,300 ,700 }, +/* C4 - CPU0 OFF + CPU1 OFF + MPU OFF + CORE ON */ + {1 ,1400 ,600 ,5000 }, };/**
@@ -55,7 +82,9 @@ static struct cpuidle_params cpuidle_params_table[] = {static int omap4_enter_idle (struct cpuidle_device *dev,struct cpuidle_state *state) { +struct omap4_processor_cx *cx =cpuidle_get_statedata (state);struct timespec ts_preidle, ts_postidle, ts_idle; +u32 cpu1_state;/* Used to keep track of the total time in idle */ getnstimeofday (&ts_preidle);
@@ -63,7 +92,26 @@ static int omap4_enter_idle(struct cpuidle_device *dev,local_irq_disable ();local_fiq_disable (); -cpu_do_idle (); +/* +* Continue to do only WFI on CPU0 till CPU1 hits OFF state. +* This is necessary to honour hardware recommondation +* of triggeing all the possible low power modes once CPU1 is +* out of coherency and in OFF mode. +* Update dev->last_state so that governor stats reflects right +* data. +*/ + cpu1_state =pwrdm_read_pwrst (cpu1_pd); +if ((cpu1_state !=PWRDM_POWER_OFF ) || (!cx->valid)) { + dev->last_state = dev->safe_state; + cx =cpuidle_get_statedata (dev->safe_state); + } + +pwrdm_set_logic_retst (mpu_pd, cx->mpu_logic_state); +omap_set_pwrdm_state (mpu_pd, cx->mpu_state); +pwrdm_set_logic_retst (core_pd, cx->core_logic_state); +omap_set_pwrdm_state (core_pd, cx->core_state); + +omap4_enter_lowpower (dev->cpu, cx->cpu0_state);getnstimeofday (&ts_postidle); ts_idle =timespec_sub (ts_postidle, ts_preidle);
@@ -96,9 +144,73 @@ void omap4_init_power_states(void) cpuidle_params_table[OMAP4_STATE_C1 ].wake_latency; omap4_power_states[OMAP4_STATE_C1 ].threshold = cpuidle_params_table[OMAP4_STATE_C1 ].threshold; + omap4_power_states[OMAP4_STATE_C1 ].cpu0_state =PWRDM_POWER_ON ; omap4_power_states[OMAP4_STATE_C1 ].mpu_state =PWRDM_POWER_ON ; + omap4_power_states[OMAP4_STATE_C1 ].mpu_logic_state =PWRDM_POWER_RET ; omap4_power_states[OMAP4_STATE_C1 ].core_state =PWRDM_POWER_ON ; + omap4_power_states[OMAP4_STATE_C1 ].core_logic_state =PWRDM_POWER_RET ; omap4_power_states[OMAP4_STATE_C1 ].flags =CPUIDLE_FLAG_TIME_VALID ; + omap4_power_states[OMAP4_STATE_C1 ].desc ="MPU ON + CORE ON" ; + +/* +* C2 - CPU0 ON + CPU1 OFF + MPU ON + CORE ON +*/ + omap4_power_states[OMAP4_STATE_C2 ].valid = + cpuidle_params_table[OMAP4_STATE_C2 ].valid; + omap4_power_states[OMAP4_STATE_C2 ].type =OMAP4_STATE_C2 ; + omap4_power_states[OMAP4_STATE_C2 ].sleep_latency = + cpuidle_params_table[OMAP4_STATE_C2 ].sleep_latency; + omap4_power_states[OMAP4_STATE_C2 ].wakeup_latency = + cpuidle_params_table[OMAP4_STATE_C2 ].wake_latency; + omap4_power_states[OMAP4_STATE_C2 ].threshold = + cpuidle_params_table[OMAP4_STATE_C2 ].threshold; + omap4_power_states[OMAP4_STATE_C2 ].cpu0_state =PWRDM_POWER_ON ; + omap4_power_states[OMAP4_STATE_C2 ].mpu_state =PWRDM_POWER_ON ; + omap4_power_states[OMAP4_STATE_C2 ].mpu_logic_state =PWRDM_POWER_RET ; + omap4_power_states[OMAP4_STATE_C2 ].core_state =PWRDM_POWER_ON ; + omap4_power_states[OMAP4_STATE_C2 ].core_logic_state =PWRDM_POWER_RET ; + omap4_power_states[OMAP4_STATE_C2 ].flags =CPUIDLE_FLAG_IGNORE ; + omap4_power_states[OMAP4_STATE_C2 ].desc ="MPU ON + CORE ON" ; + +/* +* C3 - CPU0 OFF + CPU1 OFF + MPU CSWR + CORE ON +*/ + omap4_power_states[OMAP4_STATE_C3 ].valid = + cpuidle_params_table[OMAP4_STATE_C3 ].valid; + omap4_power_states[OMAP4_STATE_C3 ].type =OMAP4_STATE_C3 ; + omap4_power_states[OMAP4_STATE_C3 ].sleep_latency = + cpuidle_params_table[OMAP4_STATE_C3 ].sleep_latency; + omap4_power_states[OMAP4_STATE_C3 ].wakeup_latency = + cpuidle_params_table[OMAP4_STATE_C3 ].wake_latency; + omap4_power_states[OMAP4_STATE_C3 ].threshold = + cpuidle_params_table[OMAP4_STATE_C3 ].threshold; + omap4_power_states[OMAP4_STATE_C3 ].cpu0_state =PWRDM_POWER_OFF ; + omap4_power_states[OMAP4_STATE_C3 ].mpu_state =PWRDM_POWER_RET ; + omap4_power_states[OMAP4_STATE_C3 ].mpu_logic_state =PWRDM_POWER_RET ; + omap4_power_states[OMAP4_STATE_C3 ].core_state =PWRDM_POWER_ON ; + omap4_power_states[OMAP4_STATE_C3 ].core_logic_state =PWRDM_POWER_RET ; + omap4_power_states[OMAP4_STATE_C3 ].flags =CPUIDLE_FLAG_IGNORE ; + omap4_power_states[OMAP4_STATE_C3 ].desc ="MPU CSWR + CORE ON" ; + +/* +* C4 - CPU0 OFF + CPU1 OFF + MPU OFF + CORE ON +*/ + omap4_power_states[OMAP4_STATE_C4 ].valid = + cpuidle_params_table[OMAP4_STATE_C4 ].valid; + omap4_power_states[OMAP4_STATE_C4 ].type =OMAP4_STATE_C4 ; + omap4_power_states[OMAP4_STATE_C4 ].sleep_latency = + cpuidle_params_table[OMAP4_STATE_C4 ].sleep_latency; + omap4_power_states[OMAP4_STATE_C4 ].wakeup_latency = + cpuidle_params_table[OMAP4_STATE_C4 ].wake_latency; + omap4_power_states[OMAP4_STATE_C4 ].threshold = + cpuidle_params_table[OMAP4_STATE_C4 ].threshold; + omap4_power_states[OMAP4_STATE_C4 ].cpu0_state =PWRDM_POWER_OFF ; + omap4_power_states[OMAP4_STATE_C4 ].mpu_state =PWRDM_POWER_OFF ; + omap4_power_states[OMAP4_STATE_C4 ].mpu_logic_state =PWRDM_POWER_OFF ; + omap4_power_states[OMAP4_STATE_C4 ].core_state =PWRDM_POWER_ON ; + omap4_power_states[OMAP4_STATE_C4 ].core_logic_state =PWRDM_POWER_RET ; + omap4_power_states[OMAP4_STATE_C4 ].flags =CPUIDLE_FLAG_IGNORE ; + omap4_power_states[OMAP4_STATE_C4 ].desc ="MPU OFF + CORE ON" ; }
@@ -115,11 +227,15 @@ struct cpuidle_driver omap4_idle_driver = {*/ int __init omap4_idle_init (void ) { -int cpu_id =0 , i, count =0 ; +int cpu_id =0 , i, count =0 , ret;struct omap4_processor_cx *cx;struct cpuidle_state *state;struct cpuidle_device *dev; + mpu_pd =pwrdm_lookup ("mpu_pwrdm" ); + cpu1_pd =pwrdm_lookup ("cpu1_pwrdm" ); + core_pd =pwrdm_lookup ("core_pwrdm" ); +omap4_init_power_states ();cpuidle_register_driver (&omap4_idle_driver);
@@ -137,8 +253,11 @@ int __init omap4_idle_init(void) cx->wakeup_latency; state->target_residency = cx->threshold; state->flags = cx->flags; +if (cx->type ==OMAP4_STATE_C1 ) + dev->safe_state = state; state->enter = omap4_enter_idle;sprintf (state->name,"C%d" , count+1 ); +strncpy (state->desc, cx->desc,CPUIDLE_DESC_LEN ); count++; }
Signature · 1 line
1.6.0.4
PATCH v3 17/21 OMAP4: cpuidle: Switch to gptimer from twd in deeper C-states.
In reply to Santosh ShilimkarCPU local timer(TWD) stops when the CPU is transitioning into deeper C-States. Since these timers are not wakeup capable, we need the wakeup capable global timer to program the wakeup time depending on the next timer expiry.
It can be handled by registering a global wakeup capable timer along with local timers marked with (mis)feature flag CLOCK_EVT_FEAT_C3STOP. Then notify the clock events layer from idle code using CLOCK_EVT_NOTIFY_BROADCAST_ENTER/EXIT).
--- arch/arm/mach-omap2/cpuidle44xx.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/cpuidle44xx.c +8 -0
@@ -12,6 +12,7 @@#include <linux/sched.h> #include <linux/cpuidle.h> +#include <linux/clockchips.h> #include <asm/proc-fns.h>
@@ -85,6 +86,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev,struct omap4_processor_cx *cx =cpuidle_get_statedata (state);struct timespec ts_preidle, ts_postidle, ts_idle;u32 cpu1_state; +int cpu_id =smp_processor_id ();/* Used to keep track of the total time in idle */ getnstimeofday (&ts_preidle);
@@ -111,8 +113,14 @@ static int omap4_enter_idle(struct cpuidle_device *dev,pwrdm_set_logic_retst (core_pd, cx->core_logic_state);omap_set_pwrdm_state (core_pd, cx->core_state); +if (cx->type >OMAP4_STATE_C1 ) +clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &cpu_id); +omap4_enter_lowpower (dev->cpu, cx->cpu0_state); +if (cx->type >OMAP4_STATE_C1 ) +clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &cpu_id); +getnstimeofday (&ts_postidle); ts_idle =timespec_sub (ts_postidle, ts_preidle);
Signature · 1 line
1.6.0.4
PATCH v3 18/21 OMAP4: cpuidle: Add CPU hotplug notifier and prepare() hook.
In reply to Santosh ShilimkarOn OMAP4 CPUidle, the low power states are triggered when CPU1 is offlined to OFF power state. When the CPU1 is online, no low power states are supported.
The patch adds CPU hotplug notifier to manage the C-state states using CPUidle prepare() hook and CPUIDLE_FLAG_IGNORE c-state flag.
This was suggested by Kevin Hilman <[email protected]> during OMAP4 PM code review.
--- arch/arm/mach-omap2/cpuidle44xx.c | 64 +++++++++++++++++++++++++++++++++++++ 1 files changed, 64 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/cpuidle44xx.c +64 -0
@@ -13,6 +13,8 @@#include <linux/sched.h> #include <linux/cpuidle.h> #include <linux/clockchips.h> +#include <linux/notifier.h> +#include <linux/cpu.h> #include <asm/proc-fns.h>
@@ -51,6 +53,8 @@ struct omap4_processor_cx {struct omap4_processor_cx omap4_power_states[OMAP4_MAX_STATES ];static struct powerdomain *mpu_pd, *cpu1_pd, *core_pd; +static int needs_state_data_update; +static unsigned int state_flags =CPUIDLE_FLAG_IGNORE ;/* * FIXME: Full latency numbers needs to be updated as part of
@@ -72,6 +76,31 @@ static struct cpuidle_params cpuidle_params_table[] = { };/** +* omap4_prepare_idle - Update C-state parameters dynamically +* @dev: cpuidle device +* +* Called from the CPUidle framework to prepare the device +* for idle before before calling the governor's select function. +*/ +static int omap4_prepare_idle (struct cpuidle_device *dev) +{ +int i, ret =0 ; + +if (!needs_state_data_update) +return ret; + +/* +* Update the C-state flags based on CPU1 online +* or offline state. On OMAP4, the low power C-states +* are made available when only CPU1 is offline. +*/ +for (i =OMAP4_STATE_C2 ; i <OMAP4_MAX_STATES ; i++) + dev->states[i].flags = state_flags; + +return ret; +} + +/** * omap4_enter_idle - Programs OMAP4 to enter the specified state * @dev: cpuidle device * @state: The target state to be programmed
@@ -227,6 +256,36 @@ struct cpuidle_driver omap4_idle_driver = { .owner = THIS_MODULE, }; +/* +* CPU hotplug notifier to update the C-states when +* CPU1 is offline or onine. While updating C-state flag, +* keep the cpuidle disabled. +*/ +static int __cpuinit omap_cpu_hotplug_notify (struct notifier_block *self, +unsigned long action,void *unused) +{ +switch (action) { +case CPU_ONLINE : +disable_hlt (); + needs_state_data_update =1 ; + state_flags =CPUIDLE_FLAG_IGNORE ; +enable_hlt (); +break ; +case CPU_DEAD : +disable_hlt (); + needs_state_data_update =1 ; + state_flags =CPUIDLE_FLAG_TIME_VALID ; +enable_hlt (); +break ; + } + +return NOTIFY_OK ; +} + +static struct notifier_block __refdata omap_ilde_hotplug_notifier = { + .notifier_call = omap_cpu_hotplug_notify, +}; +/** * omap4_idle_init - Init routine for OMAP4 idle *
@@ -272,12 +331,17 @@ int __init omap4_idle_init(void)if (!count)return -EINVAL ; dev->state_count = count; + dev->prepare = omap4_prepare_idle;if (cpuidle_register_device (dev)) {pr_err ("%s: CPUidle register device failed\n" , __func__);return -EIO ; } + ret =register_hotcpu_notifier (&omap_ilde_hotplug_notifier); +if (ret) +return ret; + return 0; }#else
Signature · 1 line
1.6.0.4
PATCH v3 19/21 OMAP4: Remove un-used do_wfi() macro.
In reply to Santosh ShilimkarWith OMAP4 suspend, idle and hotplug series, we no longer need do_wfi() macro.
Remove the same.
--- arch/arm/mach-omap2/include/mach/omap4-common.h | 10 ---------- 1 files changed, 0 insertions(+), 10 deletions(-)
arch/arm/mach-omap2/include/mach/omap4-common.h +0 -10
@@ -16,16 +16,6 @@#include <asm/proc-fns.h> #ifndef __ASSEMBLER__ -/* -* wfi used in low power code. Directly opcode is used instead -* of instruction to avoid mulit-omap build break -*/ -#ifdef CONFIG_THUMB2_KERNEL -#define do_wfi () __asm__ __volatile__ ("wfi" : : : "memory") -#else -#define do_wfi () \ - __asm__ __volatile__ (".word 0xe320f003" : : : "memory") -#endif #ifdef CONFIG_CACHE_L2X0 extern void __iomem *omap4_get_l2cache_base (void );
Signature · 1 line
1.6.0.4
PATCH v3 20/21 OMAP4: PM: Set static dependency between MPUSS-EMIF and MPUSS-L3_1
In reply to Santosh ShilimkarAs per OMAP4430 TRM, the dynamic dependency between MPUSS<->MEMIF and MPUSS<->L3_MAIN_1 clockdomains is enable by default. Refer register CM_MPU_DYNAMICDEP description for details.
But it doesn't seems to work as expected and MPUSS doesn't wakeup from off-mode if the static dependency is not set between MPUSS<->EMIF and MPUSS<->L3_MAIN_1 clockdomains. At times, CPU dead-locks with above static dependencies cleared.
The issue is under investigation with hardware team.
--- arch/arm/mach-omap2/pm44xx.c | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm44xx.c +30 -0
@@ -182,6 +182,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)static int __init omap4_pm_init (void ) {int ret; +struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;if (!cpu_is_omap44xx ())return -ENODEV ;
@@ -196,6 +197,35 @@ static int __init omap4_pm_init(void) (void )clkdm_for_each (clkdms_setup,NULL ); +/* +* FIXME: Remove the MPUSS <-> EMIF static dependency once the +* dynamic dependency issue is root-caused. +* The dynamic dependency between MPUSS <-> MEMIF and MPUSS <-> L3_1 +* doesn't seems to work as expected and MPUSS does not wakeup +* from off-mode if the static dependency is not set between them. +* At times CPUs dead-locks with above static dependencies cleared. +*/ + mpuss_clkdm =clkdm_lookup ("mpuss_clkdm" ); + emif_clkdm =clkdm_lookup ("l3_emif_clkdm" ); + l3_1_clkdm =clkdm_lookup ("l3_1_clkdm" ); +if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm)) + goto err2; + + ret =clkdm_add_wkdep (mpuss_clkdm, emif_clkdm); +if (ret) { +pr_err ("Failed to add MPUSS <-> EMIF wakeup dependency\n" ); + goto err2; + } + + ret =clkdm_add_wkdep (mpuss_clkdm, l3_1_clkdm); +if (ret) { +pr_err ("Failed to add MPUSS <-> L3_MAIN_1 wakeup dependency\n" ); + goto err2; + } + +pr_info ("OMAP4 PM: Temporary static dependency added between" +"MPUSS <-> EMIF and MPUSS <-> L3_MAIN_1.\n" ); + ret =omap4_mpuss_init ();if (ret) {pr_err ("Failed to initialise OMAP4 MPUSS\n" );
Signature · 1 line
1.6.0.4
PATCH v3 21/21 OMAP4: PM: Avoid omap4_pm_init() on OMAP4430 ES1.0
In reply to Santosh ShilimkarOn OMAP4430 ES1.0, Power Management features are not supported. Avoid omap4_pm_init() on ES1.0 silicon so that we can continue to use same kernel binary to boot on all OMAP4 silicons.
The ES1.0 boot failure with OMAP4 PM series was because of the clockdomain initialisation code. Hardware supervised clockdomain mode isn't functional for all clockdomains on OMAP4430 ES1.0 silicon so avoid the same.
--- arch/arm/mach-omap2/pm44xx.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm44xx.c +5 -0
@@ -187,6 +187,11 @@ static int __init omap4_pm_init(void)if (!cpu_is_omap44xx ())return -ENODEV ; +if (omap_rev () ==OMAP4430_REV_ES1_0 ) { +WARN (1 ,"Power Management not supported on OMAP4430 ES1.0\n" ); +return -ENODEV ; + } +pr_err ("Power Management for TI OMAP4.\n" ); ret =pwrdm_for_each (pwrdms_setup,NULL );
Signature · 1 line
1.6.0.4