Skip to contentSkip to conversation

OMAP4: PM: suspend, CPU-hotplug and CPUilde support

PATCH Superseded Santosh Shilimkar 2 participants 33 messages Sep 24, 2011 – Oct 11, 2011

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

This is a repost with minor changelog updates, re-basing against 3.1-rc6, adding reiwed-by/tested-by etc and re-ordering of errata patch. The main change is the errata i688 is cleanly separated and kept as last patch in the series as per Tony's suggestion.

Now Russell's L2 suspend series is merged in his for-next branch and CPU PM notifiers series pull request is out, most of the dependencies are taken care. The irq/core patch is also in Thomas's 3.2 queue.

An integrated branch with these branches merged can be found here [1]. The series is tested on OMAP4430 SDP for suspend, hotplug and CPUidle with OMAP4 GP and HS (secure) devices.

The following changes since commit b6fd41e29dea9c6753b1843a77e50433e6123bcb:

Linux 3.1-rc6 (2011-09-12 14:02:02 -0700)

are available in the git repository at:
git://gitorious.org/omap-sw-develoment/linux-omap-dev.git for_3_2/omap4-mpuss-pm

Santosh Shilimkar (24):
OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit
OMAP4: Export omap4_get_base*() rather than global address pointers
OMAP4: PM: Add SAR RAM support
OMAP4: PM: Keep static dep between MPUSS-EMIF and MPUSS-L3/L4 and DUCATI-L3
OMAP4: PM: Avoid omap4_pm_init() on OMAP4430 ES1.0
OMAP4: PM: Initialise all the clockdomains to supported states
OMAP: Add Secure HAL and monitor mode API infrastructure.
OMAP: PM: Add support to allocate the memory for secure RAM
OMAP4: PM: Add WakeupGen module as OMAP gic_arch_extn
OMAP4: PM: Add CPUX OFF mode support
OMAP4: Remove __INIT from omap_secondary_startup() to re-use it for hotplug.
OMAP4: PM: Program CPU1 to hit OFF when off-lined
OMAP4: PM: CPU1 wakeup workaround from Low power modes
OMAP4: PM: Use custom omap_do_wfi() for default idle.
OMAP4: suspend: Add MPUSS power domain RETENTION support
OMAP4: Remove un-used do_wfi() macro.
OMAP4: PM: Add WakeupGen and secure GIC low power support
OMAP4: PM: Add L2X0 cache lowpower support
OMAP4: PM: Add MPUSS power domain OSWR support
OMAP4: PM: Add power domain statistics support
OMAP4: PM: Add CPUidle support
OMAP4: cpuidle: Switch to gptimer from twd in deeper C-states.
OMAP3: CPUidle: Make use of CPU PM notifiers
OMAP4: Fix errata i688 with MPU interconnect barriers.

 arch/arm/mach-omap2/Kconfig                        |   21 +
 arch/arm/mach-omap2/Makefile                       |   16 +-
 arch/arm/mach-omap2/cpuidle34xx.c                  |   15 +
 arch/arm/mach-omap2/cpuidle44xx.c                  |  218 +++++++++++
 arch/arm/mach-omap2/include/mach/barriers.h        |   31 ++
 arch/arm/mach-omap2/include/mach/omap-secure.h     |   57 +++
 arch/arm/mach-omap2/include/mach/omap-wakeupgen.h  |   39 ++
 arch/arm/mach-omap2/include/mach/omap4-common.h    |   71 +++-
 arch/arm/mach-omap2/omap-headsmp.S                 |    5 -
 arch/arm/mach-omap2/omap-hotplug.c                 |   14 +-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c          |  398 ++++++++++++++++++++
 arch/arm/mach-omap2/omap-secure.c                  |   81 ++++
 arch/arm/mach-omap2/{omap44xx-smc.S => omap-smc.S} |   23 ++
 arch/arm/mach-omap2/omap-smp.c                     |   45 +++
 arch/arm/mach-omap2/omap-wakeupgen.c               |  387 +++++++++++++++++++
 arch/arm/mach-omap2/omap4-common.c                 |   88 +++++-
 arch/arm/mach-omap2/omap4-sar-layout.h             |   50 +++
 arch/arm/mach-omap2/pm.h                           |    1 +
 arch/arm/mach-omap2/pm44xx.c                       |  156 ++++++++-
 arch/arm/mach-omap2/sleep44xx.S                    |  378 +++++++++++++++++++
 arch/arm/plat-omap/common.c                        |    3 +
 arch/arm/plat-omap/include/plat/omap44xx.h         |    1 +
 arch/arm/plat-omap/sram.c                          |   43 ++-
 23 files changed, 2091 insertions(+), 50 deletions(-)
 create mode 100644 arch/arm/mach-omap2/cpuidle44xx.c
 create mode 100644 arch/arm/mach-omap2/include/mach/barriers.h
 create mode 100644 arch/arm/mach-omap2/include/mach/omap-secure.h
 create mode 100644 arch/arm/mach-omap2/include/mach/omap-wakeupgen.h
 create mode 100644 arch/arm/mach-omap2/omap-mpuss-lowpower.c
 create mode 100644 arch/arm/mach-omap2/omap-secure.c
 rename arch/arm/mach-omap2/{omap44xx-smc.S => omap-smc.S} (70%)
 create mode 100644 arch/arm/mach-omap2/omap-wakeupgen.c
 create mode 100644 arch/arm/mach-omap2/omap4-sar-layout.h
 create mode 100644 arch/arm/mach-omap2/sleep44xx.S

Regards,
Santosh

[1] git://gitorious.org/omap-sw-develoment/linux-omap-dev.git for_3_2/omap4_mpuss_pm-integrated

#1 lore raw

PATCH v2 1/24 OMAP4: Use WARN_ON() instead of BUG_ON() with graceful exit

OMAP4 L2X0 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 |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap4-common.c +2 -1
index 35ac3e5..a6c33e4 100644
@@ -71,7 +71,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 -ENOMEM;
 
 	/*
 	 * 16-way associativity, parity disabled
Signature · 1 line
1.7.4.1
#2 lore raw

PATCH v2 2/24 OMAP4: Export omap4_get_base*() rather than global address pointers

In reply to Santosh Shilimkar

This 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 |   11 +++++++++--
 arch/arm/mach-omap2/omap-smp.c                  |    5 +++++
 arch/arm/mach-omap2/omap4-common.c              |    7 ++++++-
 3 files changed, 20 insertions(+), 3 deletions(-)
arch/arm/mach-omap2/include/mach/omap4-common.h +9 -2
index e4bd87619..b28ad10 100644
@@ -25,10 +25,17 @@
 #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 __init gic_init_irq(void);
 extern void omap_smc1(u32 fn, u32 arg);
arch/arm/mach-omap2/omap-smp.c +5 -0
index ce65e93..8e9b491 100644
@@ -31,6 +31,11 @@ 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 +6 -1
index a6c33e4..a12896a 100644
@@ -25,7 +25,7 @@
 #include <mach/omap4-common.h>
 
 #ifdef CONFIG_CACHE_L2X0
-void __iomem *l2cache_base;
+static void __iomem *l2cache_base;
 #endif
 
 void __iomem *gic_dist_base_addr;
@@ -46,6 +46,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.7.4.1
#3 lore raw

PATCH v2 3/24 OMAP4: PM: Add SAR RAM support

In reply to Santosh Shilimkar

This 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, 55 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap2/omap4-sar-layout.h
arch/arm/mach-omap2/include/mach/omap4-common.h +1 -0
index b28ad10..947d0c8 100644
@@ -39,6 +39,7 @@ static inline void __iomem *omap4_get_scu_base(void)
 
 extern void __init gic_init_irq(void);
 extern void omap_smc1(u32 fn, u32 arg);
+extern void __iomem *omap4_get_sar_ram_base(void);
 
 #ifdef CONFIG_SMP
 /* Needed for secondary core boot */
arch/arm/mach-omap2/omap4-common.c +31 -0
index a12896a..652e319 100644
@@ -24,12 +24,16 @@
 #include <mach/hardware.h>
 #include <mach/omap4-common.h>
 
+#include "omap4-sar-layout.h"
+
 #ifdef CONFIG_CACHE_L2X0
 static void __iomem *l2cache_base;
 #endif
 
 void __iomem *gic_dist_base_addr;
 
+static void __iomem *sar_ram_base;
+
 
 void __init gic_init_irq(void)
 {
@@ -117,3 +121,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 -ENOMEM;
+
+	/* Static mapping, never released */
+	sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_8K);
+	if (WARN_ON(!sar_ram_base))
+		return -ENOMEM;
+
+	return 0;
+}
+early_initcall(omap4_sar_ram_init);
arch/arm/mach-omap2/omap4-sar-layout.h new file +22 -0
new file mode 100644
index 0000000..7781ea4
@@ -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
index ea2b8a6..c0d478e 100644
@@ -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.7.4.1
#4 lore raw

PATCH v2 4/24 OMAP4: PM: Keep static dep between MPUSS-EMIF and MPUSS-L3/L4 and DUCATI-L3

In reply to Santosh Shilimkar

As per OMAP4430 TRM, the dynamic dependency between MPUSS -> EMIF and MPUSS -> L4PER/L3_* and DUCATI -> L3_* clockdomains is enable by default. Refer register CM_MPU_DYNAMICDEP description for details.

But these dynamic dependencies doesn't work as expected. The hardware recommendation is to enable static dependencies for above clockdomains. Without this, system locks up or randomly crashes.

---
 arch/arm/mach-omap2/pm44xx.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm44xx.c +30 -0
index 59a870b..348ebf1 100644
@@ -99,6 +99,8 @@ 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;
+	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
 
 	if (!cpu_is_omap44xx())
 		return -ENODEV;
@@ -111,6 +113,34 @@ static int __init omap4_pm_init(void)
 		goto err2;
 	}
 
+	/*
+	 * The dynamic dependency between MPUSS -> MEMIF and
+	 * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as
+	 * expected. The hardware recommendation is to enable static
+	 * dependencies for these to avoid system lock ups or random crashes.
+	 */
+	mpuss_clkdm = clkdm_lookup("mpuss_clkdm");
+	emif_clkdm = clkdm_lookup("l3_emif_clkdm");
+	l3_1_clkdm = clkdm_lookup("l3_1_clkdm");
+	l3_2_clkdm = clkdm_lookup("l3_2_clkdm");
+	l4_per_clkdm = clkdm_lookup("l4_per_clkdm");
+	ducati_clkdm = clkdm_lookup("ducati_clkdm");
+	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
+		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
+		goto err2;
+
+	ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
+	ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm);
+	ret |= clkdm_add_wkdep(mpuss_clkdm, l3_2_clkdm);
+	ret |= clkdm_add_wkdep(mpuss_clkdm, l4_per_clkdm);
+	ret |= clkdm_add_wkdep(ducati_clkdm, l3_1_clkdm);
+	ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm);
+	if (ret) {
+		pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 "
+				"wakeup dependency\n");
+		goto err2;
+	}
+
 #ifdef CONFIG_SUSPEND
 	suspend_set_ops(&omap_pm_ops);
 #endif /* CONFIG_SUSPEND */
Signature · 1 line
1.7.4.1
#5 lore raw

PATCH v2 5/24 OMAP4: PM: Avoid omap4_pm_init() on OMAP4430 ES1.0

In reply to Santosh Shilimkar

On 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
index 348ebf1..44761bb 100644
@@ -105,6 +105,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.7.4.1
#6 lore raw

PATCH v2 6/24 OMAP4: PM: Initialise all the clockdomains to supported states

In reply to Santosh Shilimkar

Initialise 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 |   19 +++++++++++++++++++
 1 files changed, 19 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm44xx.c +19 -0
index 44761bb..5ec4bc6 100644
@@ -17,6 +17,7 @@
 #include <linux/slab.h>
 
 #include "powerdomain.h"
+#include "clockdomain.h"
 #include <mach/omap4-common.h>
 
 struct power_state {
@@ -73,6 +74,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;
@@ -146,6 +163,8 @@ static int __init omap4_pm_init(void)
 		goto err2;
 	}
 
+	(void) clkdm_for_each(clkdms_setup, NULL);
+
 #ifdef CONFIG_SUSPEND
 	suspend_set_ops(&omap_pm_ops);
 #endif /* CONFIG_SUSPEND */
Signature · 1 line
1.7.4.1
#7 lore raw

PATCH v2 7/24 OMAP: Add Secure HAL and monitor mode API infrastructure.

In reply to Santosh Shilimkar

On OMAP secure/emulation devices, certain APIs are exported by secure code. Add an infrastructure so that relevant operations on secure devices can be implemented using it.

While at this, rename omap44xx-smc.S to omap-smc.S since the common APIs can be used on other OMAP's too.

---
 arch/arm/mach-omap2/Makefile                       |   11 ++--
 arch/arm/mach-omap2/include/mach/omap-secure.h     |   40 +++++++++++++++
 arch/arm/mach-omap2/omap-secure.c                  |   52 ++++++++++++++++++++
 arch/arm/mach-omap2/{omap44xx-smc.S => omap-smc.S} |   23 +++++++++
 4 files changed, 121 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/mach-omap2/include/mach/omap-secure.h
 create mode 100644 arch/arm/mach-omap2/omap-secure.c
 rename arch/arm/mach-omap2/{omap44xx-smc.S => omap-smc.S} (70%)
arch/arm/mach-omap2/Makefile +6 -5
index f343365..663f28a 100644
@@ -11,10 +11,11 @@ hwmod-common				= omap_hwmod.o \
 					  omap_hwmod_common_data.o
 clock-common				= clock.o clock_common_data.o \
 					  clkt_dpll.o clkt_clksel.o
+secure-common                          = omap-smc.o omap-secure.o
 
-obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
-obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common)
-obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
+obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
+obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) $(secure-common)
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
@@ -24,11 +25,11 @@ 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)		+= omap4-common.o
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_omap-headsmp.o			:=-Wa,-march=armv7-a$(plus_sec)
-AFLAGS_omap44xx-smc.o			:=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_omap-smc.o			:=-Wa,-march=armv7-a$(plus_sec)
 
 # Functions loaded to SRAM
 obj-$(CONFIG_SOC_OMAP2420)		+= sram242x.o
arch/arm/mach-omap2/include/mach/omap-secure.h new file +40 -0
new file mode 100644
index 0000000..26e7bcc
@@ -0,0 +1,40 @@
+/*
+ * omap-secure.h: OMAP Secure infrastructure header.
+ *
+ * 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_OMAP_SECURE_H
+#define OMAP_ARCH_OMAP_SECURE_H
+
+/* Monitor error code */
+#define  API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR	0xFFFFFFFE
+#define  API_HAL_RET_VALUE_SERVICE_UNKNWON		0xFFFFFFFF
+
+/* HAL API error codes */
+#define  API_HAL_RET_VALUE_OK		0x00
+#define  API_HAL_RET_VALUE_FAIL		0x01
+
+/* Secure HAL API flags */
+#define FLAG_START_CRITICAL		0x4
+#define FLAG_IRQFIQ_MASK		0x3
+#define FLAG_IRQ_ENABLE			0x2
+#define FLAG_FIQ_ENABLE			0x1
+#define NO_FLAG				0x0
+
+
+/* Secure low power HAL API index */
+#define OMAP4_HAL_SAVESECURERAM_INDEX	0x1a
+#define OMAP4_HAL_SAVEHW_INDEX		0x1b
+#define OMAP4_HAL_SAVEALL_INDEX		0x1c
+#define OMAP4_HAL_SAVEGIC_INDEX		0x1d
+
+extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
+				u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
+
+#endif /* OMAP_ARCH_OMAP_SECURE_H */
arch/arm/mach-omap2/omap-secure.c new file +52 -0

52 lines not on this page · raw message

arch/arm/mach-omap2/omap-smc.S renamed from arch/arm/mach-omap2/omap44xx-smc.S +23 -0
similarity index 70%
rename from arch/arm/mach-omap2/omap44xx-smc.S
rename to arch/arm/mach-omap2/omap-smc.S
index e69d37d..f6441c1 100644
@@ -31,6 +31,29 @@ ENTRY(omap_smc1)
 	ldmfd   sp!, {r2-r12, pc}
 ENDPROC(omap_smc1)
 
+/**
+ * u32 omap_smc2(u32 id, u32 falg, u32 pargs)
+ * Low level common routine for secure HAL and PPA APIs.
+ * @id: Application ID of HAL APIs
+ * @flag: Flag to indicate the criticality of operation
+ * @pargs: Physical address of parameter list starting
+ *	    with number of parametrs
+ */
+ENTRY(omap_smc2)
+	stmfd   sp!, {r4-r12, lr}
+	mov	r3, r2
+	mov	r2, r1
+	mov	r1, #0x0	@ Process ID
+	mov	r6, #0xff
+	mov	r12, #0x00	@ Secure Service ID
+	mov	r7, #0
+	mcr	p15, 0, r7, c7, c5, 6
+	dsb
+	dmb
+	smc	#0
+	ldmfd   sp!, {r4-r12, pc}
+ENDPROC(omap_smc2)
+
 ENTRY(omap_modify_auxcoreboot0)
 	stmfd   sp!, {r1-r12, lr}
 	ldr	r12, =0x104
Signature · 1 line
1.7.4.1
#8 lore raw

PATCH v2 8/24 OMAP: PM: Add support to allocate the memory for secure RAM

In reply to Santosh Shilimkar

Allocate the memory to save secure ram context which needs to be done when MPU is hitting OFF mode.

The ROM code expects a physical address to this memory and hence use memblock APIs to reserve this memory as part of .reserve() callback. Maximum size as per secure RAM requirements is allocated.

---
 arch/arm/mach-omap2/include/mach/omap-secure.h |    4 +++
 arch/arm/mach-omap2/omap-secure.c              |   29 ++++++++++++++++++++++++
 arch/arm/plat-omap/common.c                    |    3 ++
 3 files changed, 36 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/include/mach/omap-secure.h +4 -0
index 26e7bcc..e2f95a0 100644
@@ -26,6 +26,8 @@
 #define FLAG_FIQ_ENABLE			0x1
 #define NO_FLAG				0x0
 
+/* Maximum Secure memory storage size */
+#define OMAP_SECURE_RAM_STORAGE	(88 * SZ_1K)
 
 /* Secure low power HAL API index */
 #define OMAP4_HAL_SAVESECURERAM_INDEX	0x1a
@@ -36,5 +38,7 @@
 extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
 				u32 arg1, u32 arg2, u32 arg3, u32 arg4);
 extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
+extern phys_addr_t omap_secure_ram_mempool_base(void);
+extern int omap_secure_ram_reserve_memblock(void);
 
 #endif /* OMAP_ARCH_OMAP_SECURE_H */
arch/arm/mach-omap2/omap-secure.c +29 -0
index e5a606e..69f3c72 100644
@@ -13,11 +13,14 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/memblock.h>
 
 #include <asm/cacheflush.h>
 
 #include <mach/omap-secure.h>
 
+static phys_addr_t omap_secure_memblock_base;
+
 /**
  * omap_sec_dispatcher: Routine to dispatch low power secure
  * service routines
@@ -50,3 +53,29 @@ u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
 
 	return ret;
 }
+
+/* Allocate the memory to save secure ram */
+int __init omap_secure_ram_reserve_memblock(void)
+{
+	phys_addr_t paddr;
+	u32 size = OMAP_SECURE_RAM_STORAGE;
+
+	size = ALIGN(size, SZ_1M);
+	paddr = memblock_alloc(size, SZ_1M);
+	if (!paddr) {
+		pr_err("%s: failed to reserve %x bytes\n",
+				__func__, size);
+		return -ENOMEM;
+	}
+	memblock_free(paddr, size);
+	memblock_remove(paddr, size);
+
+	omap_secure_memblock_base = paddr;
+
+	return 0;
+}
+
+phys_addr_t omap_secure_ram_mempool_base(void)
+{
+	return omap_secure_memblock_base;
+}
arch/arm/plat-omap/common.c +3 -0
index d9f10a3..827f896 100644
@@ -21,6 +21,8 @@
 #include <plat/vram.h>
 #include <plat/dsp.h>
 
+#include <mach/omap-secure.h>
+
 
 #define NO_LENGTH_CHECK 0xffffffff
 
@@ -65,4 +67,5 @@ void __init omap_reserve(void)
 	omapfb_reserve_sdram_memblock();
 	omap_vram_reserve_sdram_memblock();
 	omap_dsp_reserve_sdram_memblock();
+	omap_secure_ram_reserve_memblock();
 }
Signature · 1 line
1.7.4.1
#9 lore raw

PATCH v2 9/24 OMAP4: PM: Add WakeupGen module as OMAP gic_arch_extn

In reply to Santosh Shilimkar

OMAP WakeupGen is the interrupt controller extension used along with ARM GIC to wake the CPU out from low power states on external interrupts.

The WakeupGen unit is responsible for generating the wakeup event from the incoming interrupts and enable bits. It is implemented in the MPU always ON power domain. During normal operation, WakeupGen delivers the external interrupts directly to the GIC.

WakeupGen specification has one restriction as per Veyron version 1.6. It is SW responsibility to program interrupt enabling/disabling coherently in the GIC and in the WakeupGen enable registers. That is, a given interrupt for a given CPU is either enable at both GIC and WakeupGen, or disable at both, but no mix. That's the reason the WakeupGen is implemented as an extension of GIC.

---
 arch/arm/mach-omap2/Makefile                      |    2 +-
 arch/arm/mach-omap2/include/mach/omap-wakeupgen.h |   39 ++++
 arch/arm/mach-omap2/omap-wakeupgen.c              |  226 +++++++++++++++++++++
 arch/arm/mach-omap2/omap4-common.c                |    3 +
 4 files changed, 269 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 +1 -1
index 663f28a..ba8249b 100644
@@ -25,7 +25,7 @@ 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)		+= omap4-common.o
+obj-$(CONFIG_ARCH_OMAP4)		+= 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 +39 -0
new file mode 100644
index 0000000..d79321b
@@ -0,0 +1,39 @@
+/*
+ * OMAP WakeupGen 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_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);
+#endif
arch/arm/mach-omap2/omap-wakeupgen.c new file +226 -0

226 lines not on this page · raw message

arch/arm/mach-omap2/omap4-common.c +3 -0
index 652e319..17274c0 100644
@@ -23,6 +23,7 @@
 
 #include <mach/hardware.h>
 #include <mach/omap4-common.h>
+#include <mach/omap-wakeupgen.h>
 
 #include "omap4-sar-layout.h"
 
@@ -45,6 +46,8 @@ void __init gic_init_irq(void)
 	omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
 	BUG_ON(!omap_irq_base);
 
+	omap_wakeupgen_init();
+
 	gic_init(0, 29, gic_dist_base_addr, omap_irq_base);
 }
 
Signature · 1 line
1.7.4.1
#10 lore raw

PATCH v2 10/24 OMAP4: PM: Add CPUX OFF mode support

In reply to Santosh Shilimkar

This 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                    |    6 +-
 arch/arm/mach-omap2/include/mach/omap-secure.h  |    8 +
 arch/arm/mach-omap2/include/mach/omap4-common.h |   32 +++
 arch/arm/mach-omap2/omap-mpuss-lowpower.c       |  248 ++++++++++++++++++++
 arch/arm/mach-omap2/omap-smp.c                  |   13 +
 arch/arm/mach-omap2/omap4-sar-layout.h          |    9 +
 arch/arm/mach-omap2/pm44xx.c                    |    6 +
 arch/arm/mach-omap2/sleep44xx.S                 |  275 +++++++++++++++++++++++
 8 files changed, 595 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-omap2/omap-mpuss-lowpower.c
 create mode 100644 arch/arm/mach-omap2/sleep44xx.S
arch/arm/mach-omap2/Makefile +4 -2
index ba8249b..974c9d1 100644
@@ -25,11 +25,13 @@ 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)		+= omap4-common.o omap-wakeupgen.o
+obj-$(CONFIG_ARCH_OMAP4)		+= omap4-common.o omap-wakeupgen.o \
+					   sleep44xx.o
 
 plus_sec := $(call as-instr,.arch_extension sec,+sec)
 AFLAGS_omap-headsmp.o			:=-Wa,-march=armv7-a$(plus_sec)
 AFLAGS_omap-smc.o			:=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep44xx.o			:=-Wa,-march=armv7-a$(plus_sec)
 
 # Functions loaded to SRAM
 obj-$(CONFIG_SOC_OMAP2420)		+= sram242x.o
@@ -63,7 +65,7 @@ obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o \
 					   cpuidle34xx.o
-obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o
+obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o omap-mpuss-lowpower.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/include/mach/omap-secure.h +8 -0
index e2f95a0..0062d49 100644
@@ -35,10 +35,18 @@
 #define OMAP4_HAL_SAVEALL_INDEX		0x1c
 #define OMAP4_HAL_SAVEGIC_INDEX		0x1d
 
+/* Secure Monitor mode APIs */
+#define OMAP4_MON_SCU_PWR_INDEX		0x108
+
+/* Secure PPA(Primary Protected Application) APIs */
+#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
+
+#ifndef __ASSEMBLER__
 extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
 				u32 arg1, u32 arg2, u32 arg3, u32 arg4);
 extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
 extern phys_addr_t omap_secure_ram_mempool_base(void);
 extern int omap_secure_ram_reserve_memblock(void);
 
+#endif /* __ASSEMBLER__ */
 #endif /* OMAP_ARCH_OMAP_SECURE_H */
arch/arm/mach-omap2/include/mach/omap4-common.h +32 -0
index 947d0c8..1f6c9ac 100644
@@ -13,6 +13,9 @@
 #ifndef OMAP_ARCH_OMAP4_COMMON_H
 #define OMAP_ARCH_OMAP4_COMMON_H
 
+#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
@@ -40,6 +43,7 @@ static inline void __iomem *omap4_get_scu_base(void)
 extern void __init gic_init_irq(void);
 extern void omap_smc1(u32 fn, u32 arg);
 extern void __iomem *omap4_get_sar_ram_base(void);
+extern void omap_do_wfi(void);
 
 #ifdef CONFIG_SMP
 /* Needed for secondary core boot */
@@ -48,4 +52,32 @@ extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
 extern void omap_auxcoreboot_addr(u32 cpu_addr);
 extern u32 omap_read_auxcoreboot0(void);
 #endif
+
+#if defined(CONFIG_SMP) && defined(CONFIG_PM)
+extern int omap4_mpuss_init(void);
+extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
+extern int omap4_finish_suspend(unsigned long cpu_state);
+extern void omap4_cpu_resume(void);
+#else
+static inline int omap4_enter_lowpower(unsigned int cpu,
+					unsigned int power_state)
+{
+	cpu_do_idle();
+	return 0;
+}
+
+static inline int omap4_mpuss_init(void)
+{
+	return 0;
+}
+
+static inline int omap4_finish_suspend(unsigned long cpu_state)
+{
+	return 0;
+}
+
+static inline void omap4_cpu_resume(void)
+{}
 #endif
+#endif /* __ASSEMBLER__ */
+#endif /* OMAP_ARCH_OMAP4_COMMON_H */
arch/arm/mach-omap2/omap-mpuss-lowpower.c new file +248 -0

248 lines not on this page · raw message

arch/arm/mach-omap2/omap-smp.c +13 -0
index 8e9b491..844ca5d 100644
@@ -25,6 +25,7 @@
 #include <asm/smp_scu.h>
 #include <mach/hardware.h>
 #include <mach/omap4-common.h>
+#include <mach/omap-secure.h>
 
 /* SCU base address */
 static void __iomem *scu_base;
@@ -39,6 +40,18 @@ void __iomem *omap4_get_scu_base(void)
 void __cpuinit platform_secondary_init(unsigned int cpu)
 {
 	/*
+	 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device.
+	 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA
+	 * init and for CPU1, a secure PPA API provided. CPU0 must be ON
+	 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+.
+	 * OMAP443X GP devices- SMP bit isn't accessible.
+	 * OMAP446X GP devices - SMP bit access is enabled on both CPUs.
+	 */
+	if (cpu_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+		omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
+							4, 0, 0, 0, 0, 0);
+
+	/*
 	 * If any interrupts are already enabled for the primary
 	 * core (e.g. timer irq), then they will not have been enabled
 	 * for us: do so
arch/arm/mach-omap2/omap4-sar-layout.h +9 -0
index 7781ea4..970a2ee 100644
@@ -19,4 +19,13 @@
 #define SAR_BANK3_OFFSET		0x2000
 #define SAR_BANK4_OFFSET		0x3000
 
+/* Scratch pad memory offsets from SAR_BANK1 */
+#define SCU_OFFSET0				0xd00
+#define SCU_OFFSET1				0xd04
+#define OMAP_TYPE_OFFSET			0xd10
+
+/* 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
index 5ec4bc6..3805c0c 100644
@@ -163,6 +163,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;
+	}
+
 	(void) clkdm_for_each(clkdms_setup, NULL);
 
 #ifdef CONFIG_SUSPEND
arch/arm/mach-omap2/sleep44xx.S new file +275 -0

275 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#11 lore raw

PATCH v2 11/24 OMAP4: Remove __INIT from omap_secondary_startup() to re-use it for hotplug.

In reply to Santosh Shilimkar

Remove the __INIT from omap_secondary_startup() so that it can be re-used for CPU hotplug.

While at this, remove the un-used AUXBOOT register reference.

---
 arch/arm/mach-omap2/omap-headsmp.S |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/omap-headsmp.S +0 -5
index 4ee6aec..b13ef7e 100644
@@ -18,11 +18,6 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-/* Physical address needed since MMU not enabled yet on secondary core */
-#define OMAP4_AUX_CORE_BOOT1_PA			0x48281804
-
-	__INIT
-
 /*
  * OMAP4 specific entry point for secondary CPU to jump from ROM
  * code.  This routine also provides a holding flag into which
Signature · 1 line
1.7.4.1
#12 lore raw

PATCH v2 12/24 OMAP4: PM: Program CPU1 to hit OFF when off-lined

In reply to Santosh Shilimkar

Program non-boot CPUs to hit lowest supported power state when it is off-lined using cpu hotplug framework.

---
 arch/arm/mach-omap2/include/mach/omap4-common.h |    7 +++++
 arch/arm/mach-omap2/omap-hotplug.c              |   14 ++++++---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c       |   32 +++++++++++++++++++++++
 arch/arm/mach-omap2/omap-wakeupgen.c            |   32 +++++++++++++++++++++++
 4 files changed, 80 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/include/mach/omap4-common.h +7 -0
index 1f6c9ac..ed3797c 100644
@@ -58,6 +58,7 @@ extern int omap4_mpuss_init(void);
 extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
 extern int omap4_finish_suspend(unsigned long cpu_state);
 extern void omap4_cpu_resume(void);
+extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
 #else
 static inline int omap4_enter_lowpower(unsigned int cpu,
 					unsigned int power_state)
@@ -66,6 +67,12 @@ static inline int omap4_enter_lowpower(unsigned int cpu,
 	return 0;
 }
 
+static inline int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
+{
+	cpu_do_idle();
+	return 0;
+}
+
 static inline int omap4_mpuss_init(void)
 {
 	return 0;
arch/arm/mach-omap2/omap-hotplug.c +9 -5
index 4976b93..51ade8d 100644
@@ -21,6 +21,8 @@
 #include <asm/cacheflush.h>
 #include <mach/omap4-common.h>
 
+#include "powerdomain.h"
+
 int platform_cpu_kill(unsigned int cpu)
 {
 	return 1;
@@ -32,6 +34,8 @@ int platform_cpu_kill(unsigned int cpu)
  */
 void platform_cpu_die(unsigned int cpu)
 {
+	unsigned int this_cpu;
+
 	flush_cache_all();
 	dsb();
 
@@ -39,15 +43,15 @@ 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
 		 */
-		do_wfi();
-
-		if (omap_read_auxcoreboot0() == cpu) {
+		omap4_hotplug_cpu(cpu, PWRDM_POWER_OFF);
+		this_cpu = smp_processor_id();
+		if (omap_read_auxcoreboot0() == this_cpu) {
 			/*
 			 * OK, proper wakeup, we're done
 			 */
arch/arm/mach-omap2/omap-mpuss-lowpower.c +32 -0
index e4f11be..c0b6472 100644
@@ -192,6 +192,38 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	return 0;
 }
 
+/**
+ * omap4_hotplug_cpu: OMAP4 CPU hotplug entry
+ * @cpu : CPU ID
+ * @power_state: CPU low power state.
+ */
+int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
+{
+	unsigned int cpu_state = 0;
+
+	if (omap_rev() == OMAP4430_REV_ES1_0)
+		return -ENXIO;
+
+	if (power_state == PWRDM_POWER_OFF)
+		cpu_state = 1;
+
+	clear_cpu_prev_pwrst(cpu);
+	set_cpu_next_pwrst(cpu, power_state);
+	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_secondary_startup));
+	scu_pwrst_prepare(cpu, power_state);
+
+	/*
+	 * CPU never retuns back if targetted power state is OFF mode.
+	 * CPU ONLINE follows normal CPU ONLINE ptah via
+	 * omap_secondary_startup().
+	 */
+	omap4_finish_suspend(cpu_state);
+
+	set_cpu_next_pwrst(cpu, PWRDM_POWER_ON);
+	return 0;
+}
+
+
 /*
  * Initialise OMAP4 MPUSS
  */
arch/arm/mach-omap2/omap-wakeupgen.c +32 -0
index 22b0269..12b00e0 100644
@@ -180,6 +180,36 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)
 	spin_unlock_irqrestore(&wakeupgen_lock, flags);
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self,
+					 unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned int)hcpu;
+
+	switch (action) {
+	case CPU_ONLINE:
+		wakeupgen_irqmask_all(cpu, 0);
+		break;
+	case CPU_DEAD:
+		wakeupgen_irqmask_all(cpu, 1);
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block __refdata irq_hotplug_notifier = {
+	.notifier_call = irq_cpu_hotplug_notify,
+};
+
+static void __init irq_hotplug_init(void)
+{
+	register_hotcpu_notifier(&irq_hotplug_notifier);
+}
+#else
+static void __init irq_hotplug_init(void)
+{}
+#endif
+
 /*
  * Initialise the wakeupgen module.
  */
@@ -222,5 +252,7 @@ int __init omap_wakeupgen_init(void)
 	for (i = 0; i < NR_IRQS; i++)
 		irq_target_cpu[i] = boot_cpu;
 
+	irq_hotplug_init();
+
 	return 0;
 }
Signature · 1 line
1.7.4.1
#13 lore raw

PATCH v2 13/24 OMAP4: PM: CPU1 wakeup workaround from Low power modes

In reply to Santosh Shilimkar

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. CPU0 forces the CPU1 clockdomain to software force wakeup.

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-smp.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-smp.c +27 -0
index 844ca5d..d550a44 100644
@@ -27,6 +27,8 @@
 #include <mach/omap4-common.h>
 #include <mach/omap-secure.h>
 
+#include "clockdomain.h"
+
 /* SCU base address */
 static void __iomem *scu_base;
 
@@ -67,6 +69,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
@@ -82,6 +86,29 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
 	omap_modify_auxcoreboot0(0x200, 0xfffffdff);
 	flush_cache_all();
 	smp_wmb();
+
+	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. The clockdomain is then put back to
+	 * 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);
+		clkdm_allow_idle(cpu1_clkdm);
+	} else {
+		dsb_sev();
+		booted = true;
+	}
+
 	gic_raise_softirq(cpumask_of(cpu), 1);
 
 	/*
Signature · 1 line
1.7.4.1
#14 lore raw

PATCH v2 14/24 OMAP4: PM: Use custom omap_do_wfi() for default idle.

In reply to Santosh Shilimkar

Default arch_idle() isn't good enough for OMAP4 because of aync bridge errata and necessity of NOPs post WFI to avoid speculative prefetch aborts. Hence Use OMAP4 custom omap_do_wfi() hook for default idle.

Later in the series, async bridge errata work-around patch updates the omap_do_wfi() with necessary interconnects barriers.

---
 arch/arm/mach-omap2/pm44xx.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm44xx.c +21 -0
index 3805c0c..fdba72a 100644
@@ -108,6 +108,24 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
 }
 
 /**
+ * omap_default_idle - OMAP4 default ilde routine.'
+ *
+ * Implements OMAP4 memory, IO ordering requirements which can't be addressed
+ * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and
+ * by secondary CPU with CONFIG_CPUIDLE.
+ */
+static void omap_default_idle(void)
+{
+	local_irq_disable();
+	local_fiq_disable();
+
+	omap_do_wfi();
+
+	local_fiq_enable();
+	local_irq_enable();
+}
+
+/**
  * omap4_pm_init - Init routine for OMAP4 PM
  *
  * Initializes all powerdomain and clockdomain target states
@@ -175,6 +193,9 @@ static int __init omap4_pm_init(void)
 	suspend_set_ops(&omap_pm_ops);
 #endif /* CONFIG_SUSPEND */
 
+	/* Overwrite the default arch_idle() */
+	pm_idle = omap_default_idle;
+
 err2:
 	return ret;
 }
Signature · 1 line
1.7.4.1
#15 lore raw

PATCH v2 15/24 OMAP4: suspend: Add MPUSS power domain RETENTION support

In reply to Santosh Shilimkar

This patch adds MPUSS(MPU Sub System) power domain CSWR(Close Switch Retention) support to system wide suspend. For MPUSS power domain to hit retention(CSWR or OSWR), both CPU0 and CPU1 power domains need to be in OFF or DORMANT state, since CPU power domain CSWR is not supported by hardware

---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   16 +++++++
 arch/arm/mach-omap2/pm44xx.c              |   69 ++++++++++++++++++++++++++--
 2 files changed, 80 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +16 -0
index c0b6472..d8becec 100644
@@ -66,6 +66,7 @@ struct omap4_cpu_pm_info {
 };
 
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
+static struct powerdomain *mpuss_pd;
 
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
@@ -140,6 +141,13 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
  * of OMAP4 MPUSS subsystem
  * @cpu : CPU ID
  * @power_state: Low power state.
+ *
+ * MPUSS states for the context save:
+ * save_state =
+ *	0 - Nothing lost and no need to save: MPUSS INACTIVE
+ *	1 - CPUx L1 and logic lost: MPUSS CSWR
+ *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
+ *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
  */
 int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 {
@@ -169,6 +177,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		return -ENXIO;
 	}
 
+	pwrdm_clear_all_prev_pwrst(mpuss_pd);
 	clear_cpu_prev_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
 	set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
@@ -268,6 +277,13 @@ int __init omap4_mpuss_init(void)
 	/* Initialise CPU1 power domain state to ON */
 	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
 
+	mpuss_pd = pwrdm_lookup("mpu_pwrdm");
+	if (!mpuss_pd) {
+		pr_err("Failed to lookup MPUSS power domain\n");
+		return -ENODEV;
+	}
+	pwrdm_clear_all_prev_pwrst(mpuss_pd);
+
 	/* Save device type on scratchpad for low level code to use */
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
 		__raw_writel(1, sar_base + OMAP_TYPE_OFFSET);
arch/arm/mach-omap2/pm44xx.c +64 -5

102 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#16 lore raw

PATCH v2 16/24 OMAP4: Remove un-used do_wfi() macro.

In reply to Santosh Shilimkar

With 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
index ed3797c..e5db389 100644
@@ -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.7.4.1
#17 lore raw

PATCH v2 17/24 OMAP4: PM: Add WakeupGen and secure GIC low power support

In reply to Santosh Shilimkar

Add WakeupGen and secure GIC low power support to save and restore it's registers. WakeupGen Registers are saved to pre-defined SAR RAM layout and the restore is automatically done by hardware(ROM code) while coming out of MPUSS OSWR or Device off state. Secure GIC is saved using secure API and restored by hardware like WakeupGen.

---
 arch/arm/mach-omap2/omap-wakeupgen.c   |  129 ++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/omap4-sar-layout.h |   15 ++++
 2 files changed, 144 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-wakeupgen.c +129 -0
index 12b00e0..bdd7210 100644
@@ -22,10 +22,16 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/cpu.h>
+#include <linux/notifier.h>
+#include <linux/cpu_pm.h>
 
 #include <asm/hardware/gic.h>
 
 #include <mach/omap-wakeupgen.h>
+#include <mach/omap4-common.h>
+#include <mach/omap-secure.h>
+
+#include "omap4-sar-layout.h"
 
 #define NR_BANKS		4
 #define MAX_IRQS		128
@@ -36,6 +42,7 @@
 #define CPU1_ID			0x1
 
 static void __iomem *wakeupgen_base;
+static void __iomem *sar_base;
 static DEFINE_PER_CPU(u32 [NR_BANKS], irqmasks);
 static DEFINE_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[NR_IRQS];
@@ -55,6 +62,11 @@ static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu)
 				(cpu * CPU_ENA_OFFSET) + (idx * 4));
 }
 
+static inline void sar_writel(u32 val, u32 offset, u8 idx)
+{
+	__raw_writel(val, sar_base + offset + (idx * 4));
+}
+
 static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg)
 {
 	u8 i;
@@ -180,6 +192,91 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set)
 	spin_unlock_irqrestore(&wakeupgen_lock, flags);
 }
 
+/*
+ * Save WakeupGen interrupt context in SAR BANK3. Restore is done by
+ * ROM code. WakeupGen IP is integrated along with GIC to manage the
+ * interrupt wakeups from CPU low power states. 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.
+ */
+static void irq_save_context(void)
+{
+	u32 i, val;
+
+	if (omap_rev() == OMAP4430_REV_ES1_0)
+		return;
+
+	if (!sar_base)
+		sar_base = omap4_get_sar_ram_base();
+
+	for (i = 0; i < NR_BANKS; i++) {
+		/* Save the CPUx interrupt mask for IRQ 0 to 127 */
+		val = wakeupgen_readl(i, 0);
+		sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i);
+		val = wakeupgen_readl(i, 1);
+		sar_writel(val, WAKEUPGENENB_OFFSET_CPU1, i);
+
+		/*
+		 * Disable the secure interrupts for CPUx. The restore
+		 * code blindly restores secure and non-secure interrupt
+		 * masks from SAR RAM. Secure interrupts are not suppose
+		 * to be enabled from HLOS. So overwrite the SAR location
+		 * so that the secure interrupt remains disabled.
+		 */
+		sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU0, i);
+		sar_writel(0x0, WAKEUPGENENB_SECURE_OFFSET_CPU1, i);
+	}
+
+	/* Save AuxBoot* registers */
+	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+	__raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET);
+	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+	__raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET);
+
+	/* Save SyncReq generation logic */
+	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+	__raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET);
+	val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
+	__raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET);
+
+	/* Save SyncReq generation logic */
+	val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_MASK);
+	__raw_writel(val, sar_base + PTMSYNCREQ_MASK_OFFSET);
+	val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_EN);
+	__raw_writel(val, sar_base + PTMSYNCREQ_EN_OFFSET);
+
+	/* Set the Backup Bit Mask status */
+	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
+	val |= SAR_BACKUP_STATUS_WAKEUPGEN;
+	__raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
+}
+
+/*
+ * Clear WakeupGen SAR backup status.
+ */
+void irq_sar_clear(void)
+{
+	u32 val;
+	val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);
+	val &= ~SAR_BACKUP_STATUS_WAKEUPGEN;
+	__raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET);
+}
+
+/*
+ * Save GIC and Wakeupgen interrupt context using secure API
+ * for HS/EMU devices.
+ */
+static void irq_save_secure_context(void)
+{
+	u32 ret;
+	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
+				FLAG_START_CRITICAL,
+				0, 0, 0, 0, 0);
+	if (ret != API_HAL_RET_VALUE_OK)
+		pr_err("GIC and Wakeupgen context save failed\n");
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static int __cpuinit irq_cpu_hotplug_notify(struct notifier_block *self,
 					 unsigned long action, void *hcpu)
@@ -210,6 +307,37 @@ static void __init irq_hotplug_init(void)
 {}
 #endif
 
+#ifdef CONFIG_CPU_PM
+static int irq_notifier(struct notifier_block *self, unsigned long cmd,	void *v)
+{
+	switch (cmd) {
+	case CPU_CLUSTER_PM_ENTER:
+		if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+			irq_save_context();
+		else
+			irq_save_secure_context();
+		break;
+	case CPU_CLUSTER_PM_EXIT:
+		if (omap_type() == OMAP2_DEVICE_TYPE_GP)
+			irq_sar_clear();
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block irq_notifier_block = {
+	.notifier_call = irq_notifier,
+};
+
+static void __init irq_pm_init(void)
+{
+	cpu_pm_register_notifier(&irq_notifier_block);
+}
+#else
+static void __init irq_pm_init(void)
+{}
+#endif
+
 /*
  * Initialise the wakeupgen module.
  */
@@ -253,6 +381,7 @@ int __init omap_wakeupgen_init(void)
 		irq_target_cpu[i] = boot_cpu;
 
 	irq_hotplug_init();
+	irq_pm_init();
 
 	return 0;
 }
arch/arm/mach-omap2/omap4-sar-layout.h +15 -0
index 970a2ee..aa14a8d 100644
@@ -28,4 +28,19 @@
 #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET		0xa04
 #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET		0xa08
 
+#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)
+
+/* 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.7.4.1
#18 lore raw

PATCH v2 18/24 OMAP4: PM: Add L2X0 cache lowpower support

In reply to Santosh Shilimkar

When MPUSS hits off-mode, L2 cache is lost. This patch adds L2X0 necessary maintenance operations and context restoration in the low power code.

---
 arch/arm/mach-omap2/include/mach/omap-secure.h |    5 +
 arch/arm/mach-omap2/omap-mpuss-lowpower.c      |   41 ++++++++++-
 arch/arm/mach-omap2/omap4-sar-layout.h         |    4 +
 arch/arm/mach-omap2/sleep44xx.S                |   95 ++++++++++++++++++++++++
 4 files changed, 144 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/include/mach/omap-secure.h +5 -0
index 0062d49..6e929c5 100644
@@ -37,8 +37,13 @@
 
 /* Secure Monitor mode APIs */
 #define OMAP4_MON_SCU_PWR_INDEX		0x108
+#define OMAP4_MON_L2X0_DBG_CTRL_INDEX	0x100
+#define OMAP4_MON_L2X0_CTRL_INDEX	0x102
+#define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
+#define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 
 /* Secure PPA(Primary Protected Application) APIs */
+#define OMAP4_PPA_L2_POR_INDEX		0x23
 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
 
 #ifndef __ASSEMBLER__
arch/arm/mach-omap2/omap-mpuss-lowpower.c +40 -1

97 lines not on this page · raw message

arch/arm/mach-omap2/omap4-sar-layout.h +4 -0
index aa14a8d..fe5b545 100644
@@ -23,6 +23,10 @@
 #define SCU_OFFSET0				0xd00
 #define SCU_OFFSET1				0xd04
 #define OMAP_TYPE_OFFSET			0xd10
+#define L2X0_SAVE_OFFSET0			0xd14
+#define L2X0_SAVE_OFFSET1			0xd18
+#define L2X0_AUXCTRL_OFFSET			0xd1c
+#define L2X0_PREFETCH_CTRL_OFFSET		0xd20
 
 /* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */
 #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET		0xa04
arch/arm/mach-omap2/sleep44xx.S +95 -0

113 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#19 lore raw

PATCH v2 19/24 OMAP4: PM: Add MPUSS power domain OSWR support

In reply to Santosh Shilimkar

This patch adds the MPUSS OSWR (Open Switch Retention) support. The MPUSS OSWR configuration is as below.
- CPUx L1 and logic lost, MPUSS logic lost, L2 memory is retained

OMAP4460 onwards, MPUSS power domain doesn't support OFF state any more anymore just like CORE power domain. The deepest state supported is OSWR. On OMAP4430 secure devices too, MPUSS off mode can't be used because of a bug which alters Ducati and Tesla states. Hence MPUSS off mode as an independent state isn't supported on OMAP44XX devices.

Ofcourse when MPUSS power domain transitions to OSWR along with device off mode, it eventually hits off state since memory contents are lost.

Hence the MPUSS off mode independent state is not attempted without device off mode. All the necessary infrastructure code for MPUSS off mode is in place as part of this series.

---
 arch/arm/mach-omap2/include/mach/omap4-common.h |    6 ++
 arch/arm/mach-omap2/omap-mpuss-lowpower.c       |   65 +++++++++++++++++++++-
 arch/arm/mach-omap2/pm44xx.c                    |    4 ++
 3 files changed, 72 insertions(+), 3 deletions(-)
arch/arm/mach-omap2/include/mach/omap4-common.h +6 -0
index e5db389..1f6ae1d 100644
@@ -49,6 +49,7 @@ extern int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state);
 extern int omap4_finish_suspend(unsigned long cpu_state);
 extern void omap4_cpu_resume(void);
 extern int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state);
+extern u32 omap4_mpuss_read_prev_context_state(void);
 #else
 static inline int omap4_enter_lowpower(unsigned int cpu,
 					unsigned int power_state)
@@ -75,6 +76,11 @@ static inline int omap4_finish_suspend(unsigned long cpu_state)
 
 static inline void omap4_cpu_resume(void)
 {}
+
+static inline u32 omap4_mpuss_read_prev_context_state(void)
+{
+	return 0;
+}
 #endif
 #endif /* __ASSEMBLER__ */
 #endif /* OMAP_ARCH_OMAP4_COMMON_H */
arch/arm/mach-omap2/omap-mpuss-lowpower.c +62 -3

109 lines not on this page · raw message

arch/arm/mach-omap2/pm44xx.c +4 -0
index e64e275..fda656d 100644
@@ -28,6 +28,7 @@ struct power_state {
 	u32 next_state;
 #ifdef CONFIG_SUSPEND
 	u32 saved_state;
+	u32 saved_logic_state;
 #endif
 	struct list_head node;
 };
@@ -44,11 +45,13 @@ static int omap4_pm_suspend(void)
 	/* Save current powerdomain state */
 	list_for_each_entry(pwrst, &pwrst_list, node) {
 		pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
+		pwrst->saved_logic_state = pwrdm_read_logic_retst(pwrst->pwrdm);
 	}
 
 	/* Set targeted power domain states by suspend */
 	list_for_each_entry(pwrst, &pwrst_list, node) {
 		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
+		pwrdm_set_logic_retst(pwrst->pwrdm, PWRDM_POWER_OFF);
 	}
 
 	/*
@@ -72,6 +75,7 @@ static int omap4_pm_suspend(void)
 			ret = -1;
 		}
 		omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
+		pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
 	}
 	if (ret)
 		pr_crit("Could not enter target state in pm_suspend\n");
Signature · 1 line
1.7.4.1
#20 lore raw

PATCH v2 20/24 OMAP4: PM: Add power domain statistics support

In reply to Santosh Shilimkar
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +4 -0
index 505844f..b146854 100644
@@ -256,6 +256,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		return -ENXIO;
 	}
 
+	pwrdm_pre_transition();
+
 	/*
 	 * Check MPUSS next state and save interrupt controller if needed.
 	 * In MPUSS OSWR or device OFF, interrupt controller  contest is lost.
@@ -288,6 +290,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 	wakeup_cpu = smp_processor_id();
 	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);
 
+	pwrdm_post_transition();
+
 	return 0;
 }
 
Signature · 1 line
1.7.4.1
#21 lore raw

PATCH v2 21/24 OMAP4: PM: Add CPUidle support

In reply to Santosh Shilimkar

Add OMAP4 CPUIDLE support. CPU1 is left with defualt idle and the low power state for it is managed via cpu-hotplug.

This patch adds MPUSS low power states in cpuidle.

C1 - CPU0 ON + CPU1 ON + MPU ON
C2 - CPU0 OFF + CPU1 OFF + MPU CSWR
C3 - CPU0 OFF + CPU1 OFF + MPU OSWR

OMAP4460 onwards, MPUSS power domain doesn't support OFF state any more anymore just like CORE power domain. The deepest state supported is OSWr. Ofcourse when MPUSS and CORE PD transitions to OSWR along with device off mode, even the memory contemts are lost which is as good as the PD off state.

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/Makefile      |    3 +-
 arch/arm/mach-omap2/cpuidle44xx.c |  210 +++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm.h          |    1 +
 arch/arm/mach-omap2/pm44xx.c      |    2 +
 4 files changed, 215 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/cpuidle44xx.c
arch/arm/mach-omap2/Makefile +2 -1
index 974c9d1..a9f8d48 100644
@@ -65,7 +65,8 @@ obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o \
 					   cpuidle34xx.o
-obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o omap-mpuss-lowpower.o
+obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o omap-mpuss-lowpower.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 +210 -0

210 lines not on this page · raw message

arch/arm/mach-omap2/pm.h +1 -0
index 4e166ad..b737b11 100644
@@ -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
index fda656d..0e4c39c 100644
@@ -259,6 +259,8 @@ static int __init omap4_pm_init(void)
 	/* Overwrite the default arch_idle() */
 	pm_idle = omap_default_idle;
 
+	omap4_idle_init();
+
 err2:
 	return ret;
 }
Signature · 1 line
1.7.4.1
#22 lore raw

PATCH v2 22/24 OMAP4: cpuidle: Switch to gptimer from twd in deeper C-states.

In reply to Santosh Shilimkar

CPU 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).

ARM local timers are already marked with C3STOP feature. Add the notifiers to OMAP4 CPU idle code for the broadcast entry and exit.

---
 arch/arm/mach-omap2/cpuidle44xx.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/cpuidle44xx.c +8 -0
index ac8f4c0..f0cd214 100644
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu_pm.h>
+#include <linux/clockchips.h>
 
 #include <asm/proc-fns.h>
 
@@ -60,6 +61,7 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
 	struct omap4_idle_statedata *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);
@@ -81,6 +83,9 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
 		cx = cpuidle_get_statedata(dev->safe_state);
 	}
 
+	if (state > &dev->states[0])
+		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
+
 	/*
 	 * Call idle CPU PM enter notifier chain so that
 	 * VFP and per CPU interrupt context is saved.
@@ -116,6 +121,9 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
 	if (omap4_mpuss_read_prev_context_state())
 		cpu_cluster_pm_exit();
 
+	if (state > &dev->states[0])
+		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
+
 	getnstimeofday(&ts_postidle);
 	ts_idle = timespec_sub(ts_postidle, ts_preidle);
 
Signature · 1 line
1.7.4.1
#23 lore raw

PATCH v2 23/24 OMAP3: CPUidle: Make use of CPU PM notifiers

In reply to Santosh Shilimkar

Save VFP CPU context using CPU PM notifier chain. VFP context is lost when CPU hits OFF state.

---
 arch/arm/mach-omap2/cpuidle34xx.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/cpuidle34xx.c +15 -0
index 4bf6e6e..861920a 100644
@@ -24,6 +24,7 @@
 
 #include <linux/sched.h>
 #include <linux/cpuidle.h>
+#include <linux/cpu_pm.h>
 
 #include <plat/prcm.h>
 #include <plat/irqs.h>
@@ -118,9 +119,23 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
 		pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
 	}
 
+	/*
+	 * Call idle CPU PM enter notifier chain so that
+	 * VFP context is saved.
+	 */
+	if (mpu_state == PWRDM_POWER_OFF)
+		cpu_pm_enter();
+
 	/* Execute ARM wfi */
 	omap_sram_idle();
 
+	/*
+	 * Call idle CPU PM enter notifier chain to restore
+	 * VFP context.
+	 */
+	if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)
+		cpu_pm_exit();
+
 	/* Re-allow idle for C1 */
 	if (state == &dev->states[0]) {
 		pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
Signature · 1 line
1.7.4.1
#24 lore raw

PATCH v2 24/24 OMAP4: Fix errata i688 with MPU interconnect barriers.

In reply to Santosh Shilimkar

On OMAP4 SOC, intecronnects has many write buffers in the async bridges and they need to be drained before CPU enters into standby state.

Patch 'OMAP4: PM: Add CPUX OFF mode support' added CPU PM support but OMAP errata i688 (Async Bridge Corruption) needs to be taken care to avoid issues like system freeze, CPU deadlocks, random crashes with register accesses, synchronisation loss on initiators operating on both interconnect port simultaneously.

As per the errata, if a data is stalled inside asynchronous bridge because of back pressure, it may be accepted multiple times, creating pointer misalignment that will corrupt next transfers on that data path until next reset of the system (No recovery procedure once the issue is hit, the path remains consistently broken). Async bridge can be found on path between MPU to EMIF and MPU to L3 interconnect. This situation can happen only when the idle is initiated by a Master Request Disconnection (which is trigged by software when executing WFI on CPU).

The work-around for this errata needs all the initiators connected through async bridge must ensure that data path is properly drained before issuing WFI. This condition will be met if one Strongly ordered access is performed to the target right before executing the WFI. In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained. IO barrier ensure that there is no synchronisation loss on initiators operating on both interconnect port simultaneously.

Thanks to Russell for a tip to conver assembly function to C fuction there by reducing 40 odd lines of code from the patch.

---
 arch/arm/mach-omap2/Kconfig                     |   21 +++++++++++
 arch/arm/mach-omap2/include/mach/barriers.h     |   31 ++++++++++++++++
 arch/arm/mach-omap2/include/mach/omap4-common.h |    4 ++
 arch/arm/mach-omap2/omap4-common.c              |   44 +++++++++++++++++++++++
 arch/arm/mach-omap2/sleep44xx.S                 |    8 ++++
 arch/arm/plat-omap/sram.c                       |   43 ++++++++++++++--------
 6 files changed, 136 insertions(+), 15 deletions(-)
 create mode 100644 arch/arm/mach-omap2/include/mach/barriers.h
arch/arm/mach-omap2/Kconfig +21 -0
index 57b66d5..767a587 100644
@@ -345,6 +345,27 @@ config OMAP3_SDRC_AC_TIMING
 	  wish to say no.  Selecting yes without understanding what is
 	  going on could result in system crashes;
 
+config OMAP4_ERRATA_I688
+	bool "OMAP4 errata: Async Bridge Corruption"
+	depends on ARCH_OMAP4
+	select ARCH_HAS_BARRIERS
+	help
+	  If a data is stalled inside asynchronous bridge because of back
+	  pressure, it may be accepted multiple times, creating pointer
+	  misalignment that will corrupt next transfers on that data path
+	  until next reset of the system (No recovery procedure once the
+	  issue is hit, the path remains consistently broken). Async bridge
+	  can be found on path between MPU to EMIF and MPU to L3 interconnect.
+	  This situation can happen only when the idle is initiated by a
+	  Master Request Disconnection (which is trigged by software when
+	  executing WFI on CPU).
+	  The work-around for this errata needs all the initiators connected
+	  through async bridge must ensure that data path is properly drained
+	  before issuing WFI. This condition will be met if one Strongly ordered
+	  access is performed to the target right before executing the WFI.
+	  In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained.
+	  IO barrier ensure that there is no synchronisation loss on initiators
+	  operating on both interconnect port simultaneously.
 endmenu
 
 endif
arch/arm/mach-omap2/include/mach/barriers.h new file +31 -0
new file mode 100644
index 0000000..4fa72c7
@@ -0,0 +1,31 @@
+/*
+ * OMAP memory barrier header.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *  Santosh Shilimkar <[email protected]>
+ *  Richard Woodruff <[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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MACH_BARRIERS_H
+#define __MACH_BARRIERS_H
+
+extern void omap_bus_sync(void);
+
+#define rmb()		dsb()
+#define wmb()		do { dsb(); outer_sync(); omap_bus_sync(); } while (0)
+#define mb()		wmb()
+
+#endif	/* __MACH_BARRIERS_H */
arch/arm/mach-omap2/include/mach/omap4-common.h +4 -0
index 1f6ae1d..8aa3420 100644
@@ -15,11 +15,15 @@
 
 #include <asm/proc-fns.h>
 
+/* Used to implement memory barrier on DRAM path */
+#define OMAP4_DRAM_BARRIER_VA			0xfe600000
+
 #ifndef __ASSEMBLER__
 
 #ifdef CONFIG_CACHE_L2X0
 extern void __iomem *omap4_get_l2cache_base(void);
 #endif
+extern void __iomem *dram_sync, *sram_sync;
 
 #ifdef CONFIG_SMP
 extern void __iomem *omap4_get_scu_base(void);
arch/arm/mach-omap2/omap4-common.c +44 -0

62 lines not on this page · raw message

arch/arm/mach-omap2/sleep44xx.S +8 -0
index 94935bc..5e3f474 100644
@@ -324,8 +324,16 @@ skip_l2en:
 ENDPROC(omap4_cpu_resume)
 #endif
 
+#ifndef CONFIG_OMAP4_ERRATA_I688
+ENTRY(omap_bus_sync)
+	mov	pc, lr
+ENDPROC(omap_bus_sync)
+#endif
+
 ENTRY(omap_do_wfi)
 	stmfd	sp!, {lr}
+	/* Drain interconnect write buffers. */
+	bl omap_bus_sync
 
 	/*
 	 * Execute an ISB instruction to ensure that all of the
arch/arm/plat-omap/sram.c +28 -15

79 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#25 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

In reply to Santosh Shilimkar

Hi Santosh,

Quoted 2 lines · Santosh Shilimkar

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

No need to repost, but can you update the versions in your branch to have an ARM: prefix in the subject per Arnd's recent request?

Thanks,

Kevin

#26 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

Quoted 10 lines · Kevin Hilman

Hi Santosh,

Quoted 2 lines · Santosh Shilimkar

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

No need to repost, but can you update the versions in your branch to have an ARM: prefix in the subject per Arnd's recent request?

Done. Branch for_3_2/omap4-mpuss-pm is updated with ARM on all patches.

Regards
Santosh

#27 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

In reply to Santosh Shilimkar

Hi Santosh,

Quoted 2 lines · Santosh Shilimkar

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

Just noticed when doing some final build/sanity testing that there are a few of compile/link warnings/problems when the kernel is built without CONFIG_PM

Some warnings:

/work/kernel/omap/pm/arch/arm/mach-omap2/omap-wakeupgen.c:203:13: warning: 'irq_save_context' defined but not used /work/kernel/omap/pm/arch/arm/mach-omap2/omap-wakeupgen.c:270:13: warning: 'irq_save_secure_context' defined but not used

and some failures (these happen when CONFIG_SUSPEND=n but CONFIG_PM_RUNTIME=y:

arch/arm/mach-omap2/built-in.o: In function `skip_l2en':
/work/kernel/omap/pm/arch/arm/mach-omap2/sleep44xx.S:323: undefined reference to cpu_resume' arch/arm/mach-omap2/built-in.o: In function omap_sram_idle':
/work/kernel/omap/pm/arch/arm/mach-omap2/pm34xx.c:429: undefined reference to cpu_suspend' arch/arm/mach-omap2/built-in.o: In function skipl2reen':
/work/kernel/omap/pm/arch/arm/mach-omap2/sleep34xx.S:534: undefined reference to cpu_resume' arch/arm/mach-omap2/built-in.o: In function omap4_enter_lowpower':
/work/kernel/omap/pm/arch/arm/mach-omap2/omap-mpuss-lowpower.c:281: undefined reference to `cpu_suspend'

Turns out these are not directly related to your series and OMAP3 exhibits the same problems.

I just posted a patch[1] to attempt to address these.

But could you fixup the first problem and test with [1] to see if things still build/work as expected.

Thanks,

Kevin

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2011-October/068606.html

#28 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

Quoted 27 lines · Kevin Hilman

Hi Santosh,

Quoted 2 lines · Santosh Shilimkar

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

Just noticed when doing some final build/sanity testing that there are a few of compile/link warnings/problems when the kernel is built without CONFIG_PM

Some warnings:

/work/kernel/omap/pm/arch/arm/mach-omap2/omap-wakeupgen.c:203:13: warning: 'irq_save_context' defined but not used /work/kernel/omap/pm/arch/arm/mach-omap2/omap-wakeupgen.c:270:13: warning: 'irq_save_secure_context' defined but not used

and some failures (these happen when CONFIG_SUSPEND=n but CONFIG_PM_RUNTIME=y:

arch/arm/mach-omap2/built-in.o: In function `skip_l2en':
/work/kernel/omap/pm/arch/arm/mach-omap2/sleep44xx.S:323: undefined reference to cpu_resume' arch/arm/mach-omap2/built-in.o: In function omap_sram_idle':
/work/kernel/omap/pm/arch/arm/mach-omap2/pm34xx.c:429: undefined reference to cpu_suspend' arch/arm/mach-omap2/built-in.o: In function skipl2reen':
/work/kernel/omap/pm/arch/arm/mach-omap2/sleep34xx.S:534: undefined reference to cpu_resume' arch/arm/mach-omap2/built-in.o: In function omap4_enter_lowpower':
/work/kernel/omap/pm/arch/arm/mach-omap2/omap-mpuss-lowpower.c:281: undefined reference to `cpu_suspend'

Quoted 7 lines

Turns out these are not directly related to your series and OMAP3 exhibits the same problems.

I just posted a patch[1] to attempt to address these.

But could you fixup the first problem and test with [1] to see if things still build/work as expected.

OK, ignore my patch.

Arnd already has a fix for these link problems in his randconfig/arm branch.

Please just cleanup the wakeupgen compile warnings and update your branch.

Kevin

#29 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

Quoted 13 lines · Kevin Hilman
Quoted 11 lines · Kevin Hilman

Hi Santosh,

Quoted 2 lines · Santosh Shilimkar

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

Just noticed when doing some final build/sanity testing that there are a few of compile/link warnings/problems when the kernel is built without CONFIG_PM

Quoted 5 lines
Quoted 5 lines

Some warnings:

/work/kernel/omap/pm/arch/arm/mach-omap2/omap-wakeupgen.c:203:13: warning: 'irq_save_context' defined but not used /work/kernel/omap/pm/arch/arm/mach-omap2/omap-wakeupgen.c:270:13: warning: 'irq_save_secure_context' defined but not used

Sory I missed it in my builds.

[...]

Quoted 3 lines

Please just cleanup the wakeupgen compile warnings and update your branch.

Done !!
Updated branch : for_3_2/omap4-mpuss-pm_2

Regards
Santosh

#30 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

In reply to Santosh Shilimkar

Hi Santosh,

Quoted 2 lines · Santosh Shilimkar

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

There are a few more compile errors when doing OMAP1-only builds. You'll need a way to eliminate the secure calls for OMAP1.

This series causes a couple build errors when doing OMAP1-only builds (I used omap1_defconfig):

First:

/work/kernel/omap/pm/arch/arm/plat-omap/common.c:24:30: fatal error: mach/omap-secure.h: No such file or directory

And trying creating a dummy header to see if it would continue to build gives:

/work/kernel/omap/pm/arch/arm/plat-omap/common.c: In function 'omap_reserve':
/work/kernel/omap/pm/arch/arm/plat-omap/common.c:70:2: error: implicit declaration of function 'omap_secure_ram_reserve_memblock' make[2]: *** [arch/arm/plat-omap/common.o] Error 1
make[1]: *** [arch/arm/plat-omap] Error 2

Kevin

#31 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

Quoted 4 lines · Kevin Hilman

Hi Santosh,

Santosh Shilimkar <[email protected]> writes:

Quoted 9 lines
Quoted 2 lines

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

There are a few more compile errors when doing OMAP1-only builds. You'll need a way to eliminate the secure calls for OMAP1.

This series causes a couple build errors when doing OMAP1-only builds (I used omap1_defconfig):

OK. Thanks for catching it.

Quoted 11 lines

First:

/work/kernel/omap/pm/arch/arm/plat-omap/common.c:24:30: fatal error: mach/omap-secure.h: No such file or directory

And trying creating a dummy header to see if it would continue to build gives:

/work/kernel/omap/pm/arch/arm/plat-omap/common.c: In function 'omap_reserve':
/work/kernel/omap/pm/arch/arm/plat-omap/common.c:70:2: error: implicit declaration of function 'omap_secure_ram_reserve_memblock' make[2]: *** [arch/arm/plat-omap/common.o] Error 1
make[1]: *** [arch/arm/plat-omap] Error 2

For OMAP1 build, omap_secure_ram_reserve_memblock() definition is needed since common.c is built for OMAP1 as well.
The trivial change in the end of this email fixes the omap1 build. Have folded that change in original patch and updated the OMAP4 PM branch - for_3_2/omap4-mpuss-pm_2

Regards
Santosh
P.S : Even with this fix, omap1_defconfig build breaks because of USB. I removed USB from build to check rest of the build and it was fine then.

---

(quoted diff) +0 -0

b/arch/arm/mach-omap2/include/mach/omap-secure.h
index 6e929c5..48247ce 100644

arch/arm/mach-omap2/include/mach/omap-secure.h +0 -0
@@ -51,7 +51,6 @@ extern u32 omap_secure_dispatcher(u32 idx, u32 flag,

u32 nargs,
u32 arg1, u32 arg2, u32 arg3, u32 arg4);
extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
extern phys_addr_t omap_secure_ram_mempool_base(void);
-extern int omap_secure_ram_reserve_memblock(void);

#endif /* __ASSEMBLER__ */
#endif /* OMAP_ARCH_OMAP_SECURE_H */

arch/arm/plat-omap/common.c +1 -1
index 827f896..d5ef8dc 100644
@@ -21,7 +21,7 @@
 #include <plat/vram.h>
 #include <plat/dsp.h>
 
-#include <mach/omap-secure.h>
+#include <plat/omap-secure.h>
 
 
 #define NO_LENGTH_CHECK 0xffffffff
(quoted diff) +0 -0

b/arch/arm/plat-omap/include/plat/omap-secure.h
new file mode 100644
index 0000000..64f9d1c

arch/arm/plat-omap/include/plat/omap-secure.h new file +13 -0
@@ -0,0 +1,13 @@
+#ifndef __OMAP_SECURE_H__
+#define __OMAP_SECURE_H__
+
+#include <linux/types.h>
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+extern int omap_secure_ram_reserve_memblock(void);
+#else
+static inline void omap_secure_ram_reserve_memblock(void)
+{ }
+#endif
+
+#endif /* __OMAP_SECURE_H__ */
#32 lore raw

v2 cover OMAP4: PM: suspend, CPU-hotplug and CPUilde support

Quoted 22 lines · Santosh Shilimkar
Quoted 4 lines · Kevin Hilman

Hi Santosh,

Santosh Shilimkar <[email protected]> writes:

Quoted 9 lines
Quoted 2 lines

The series adds OMAP4 MPUSS (MPU SubSystem) power management support for suspend (S2R), CPU hotplug and CPUidle.

There are a few more compile errors when doing OMAP1-only builds. You'll need a way to eliminate the secure calls for OMAP1.

This series causes a couple build errors when doing OMAP1-only builds (I used omap1_defconfig):

OK. Thanks for catching it.

Quoted 6 lines

First:

/work/kernel/omap/pm/arch/arm/plat-omap/common.c:24:30: fatal error: mach/omap-secure.h: No such file or directory

And trying creating a dummy header to see if it would continue to build gives:

Quoted 8 lines
Quoted 5 lines

/work/kernel/omap/pm/arch/arm/plat-omap/common.c: In function 'omap_reserve':
/work/kernel/omap/pm/arch/arm/plat-omap/common.c:70:2: error: implicit declaration of function 'omap_secure_ram_reserve_memblock' make[2]: *** [arch/arm/plat-omap/common.o] Error 1
make[1]: *** [arch/arm/plat-omap] Error 2

For OMAP1 build, omap_secure_ram_reserve_memblock() definition is needed since common.c is built for OMAP1 as well.
The trivial change in the end of this email fixes the omap1 build.

Looks good.

Quoted 2 lines

Have folded that change in original patch and updated the OMAP4 PM branch - for_3_2/omap4-mpuss-pm_2

Thanks.

Quoted 5 lines

Regards
Santosh
P.S : Even with this fix, omap1_defconfig build breaks because of USB. I removed USB from build to check rest of the build and it was fine then.

OK.

Kevin