All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] ARM: OMAP5: PM: Add MPUSS suspend and CPUidle support
@ 2013-03-01 12:10 ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

Series adds OMAP5 MPUSS power management support for system wide suspend
and CPUidle. Its heavy re-use from OMAP4 and hence only ~390 odd lines are
needed to add OMAP5 PM support on top of existing OMAP4 PM support.

OMAP5 adds a mercury retention feature which is an enhancement of
existing retention feature to reduce the leakage. No change in
programming model except one time enabling of mercury retention
during init.

One more notable change in OMAP5 vs OMAP4 devices, CPUx power domains
support retention state which lets you hit MPUSS and Core retention with
very low latency C-state.

Series is built on top of my OMAP5 clean-up series posted earlier but there
is no hard dependency as such. For testing though, you also need out
of tree data files and hence I have put together a testing branch which
can be found here [1]

Tested on OMAP4430 SDP, OMAP4460 Panda, OMAP5430 SDP and OMAP5432 Panda
devices with suspend and CPUIdle. On OMAP5 DT build though, there is an
issue with UART wakeup from suspend as discussed already on lists.

Nishanth Menon (1):
  ARM: OMAP5: PM: handle device instance for for coldreset

Santosh Shilimkar (14):
  ARM: OMAP4+: PM: Consolidate MPU subsystem PM code for re-use
  ARM: OMAP5: PM: Update CPU context register offset
  ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
  ARM: OMAP5: PM: Set MPUSS-EMIF clock-domain static dependency
  ARM: OMAP5: PM: Enables ES2 PM mode by default
  ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
  ARM: OMAP5: Add init_late() hook to enable pm initialization
  ARM: OMAP5: PM: Add CPU power off mode support
  ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force
    wakeup method
  ARM: OMAP5: PM: Add MPU Open Switch Retention support
  ARM: OMAP5: PM: Add L2 memory power down support
  ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support
  ARM: OMAP4+: CPUidle: Deprecate use of
    omap4_mpuss_read_prev_context_state()
  ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support

 arch/arm/mach-omap2/Kconfig                        |    1 +
 arch/arm/mach-omap2/Makefile                       |   13 +-
 arch/arm/mach-omap2/board-generic.c                |    1 +
 arch/arm/mach-omap2/common.h                       |    8 +-
 .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  133 ++++++++++++++++---
 arch/arm/mach-omap2/io.c                           |    8 ++
 arch/arm/mach-omap2/omap-mpuss-lowpower.c          |  134 ++++++++++++++------
 arch/arm/mach-omap2/omap-secure.h                  |    9 ++
 arch/arm/mach-omap2/omap-smp.c                     |   12 +-
 arch/arm/mach-omap2/omap-wakeupgen.c               |   25 +++-
 arch/arm/mach-omap2/omap-wakeupgen.h               |    1 +
 arch/arm/mach-omap2/omap4-sar-layout.h             |    2 +
 arch/arm/mach-omap2/{pm44xx.c => pm_omap4plus.c}   |  111 +++++++++++-----
 arch/arm/mach-omap2/prminst44xx.c                  |   10 +-
 .../mach-omap2/{sleep44xx.S => sleep_omap4plus.S}  |  133 +++++++++++++++++++
 15 files changed, 498 insertions(+), 103 deletions(-)
 rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (61%)
 rename arch/arm/mach-omap2/{pm44xx.c => pm_omap4plus.c} (66%)
 rename arch/arm/mach-omap2/{sleep44xx.S => sleep_omap4plus.S} (74%)

Regards,
Santosh

[1] git://github.com/SantoshShilimkar/linux.git	testing/3.10/omap5-int-rebuild

-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 00/15] ARM: OMAP5: PM: Add MPUSS suspend and CPUidle support
@ 2013-03-01 12:10 ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

Series adds OMAP5 MPUSS power management support for system wide suspend
and CPUidle. Its heavy re-use from OMAP4 and hence only ~390 odd lines are
needed to add OMAP5 PM support on top of existing OMAP4 PM support.

OMAP5 adds a mercury retention feature which is an enhancement of
existing retention feature to reduce the leakage. No change in
programming model except one time enabling of mercury retention
during init.

One more notable change in OMAP5 vs OMAP4 devices, CPUx power domains
support retention state which lets you hit MPUSS and Core retention with
very low latency C-state.

Series is built on top of my OMAP5 clean-up series posted earlier but there
is no hard dependency as such. For testing though, you also need out
of tree data files and hence I have put together a testing branch which
can be found here [1]

Tested on OMAP4430 SDP, OMAP4460 Panda, OMAP5430 SDP and OMAP5432 Panda
devices with suspend and CPUIdle. On OMAP5 DT build though, there is an
issue with UART wakeup from suspend as discussed already on lists.

Nishanth Menon (1):
  ARM: OMAP5: PM: handle device instance for for coldreset

Santosh Shilimkar (14):
  ARM: OMAP4+: PM: Consolidate MPU subsystem PM code for re-use
  ARM: OMAP5: PM: Update CPU context register offset
  ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
  ARM: OMAP5: PM: Set MPUSS-EMIF clock-domain static dependency
  ARM: OMAP5: PM: Enables ES2 PM mode by default
  ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
  ARM: OMAP5: Add init_late() hook to enable pm initialization
  ARM: OMAP5: PM: Add CPU power off mode support
  ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force
    wakeup method
  ARM: OMAP5: PM: Add MPU Open Switch Retention support
  ARM: OMAP5: PM: Add L2 memory power down support
  ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support
  ARM: OMAP4+: CPUidle: Deprecate use of
    omap4_mpuss_read_prev_context_state()
  ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support

 arch/arm/mach-omap2/Kconfig                        |    1 +
 arch/arm/mach-omap2/Makefile                       |   13 +-
 arch/arm/mach-omap2/board-generic.c                |    1 +
 arch/arm/mach-omap2/common.h                       |    8 +-
 .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  133 ++++++++++++++++---
 arch/arm/mach-omap2/io.c                           |    8 ++
 arch/arm/mach-omap2/omap-mpuss-lowpower.c          |  134 ++++++++++++++------
 arch/arm/mach-omap2/omap-secure.h                  |    9 ++
 arch/arm/mach-omap2/omap-smp.c                     |   12 +-
 arch/arm/mach-omap2/omap-wakeupgen.c               |   25 +++-
 arch/arm/mach-omap2/omap-wakeupgen.h               |    1 +
 arch/arm/mach-omap2/omap4-sar-layout.h             |    2 +
 arch/arm/mach-omap2/{pm44xx.c => pm_omap4plus.c}   |  111 +++++++++++-----
 arch/arm/mach-omap2/prminst44xx.c                  |   10 +-
 .../mach-omap2/{sleep44xx.S => sleep_omap4plus.S}  |  133 +++++++++++++++++++
 15 files changed, 498 insertions(+), 103 deletions(-)
 rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (61%)
 rename arch/arm/mach-omap2/{pm44xx.c => pm_omap4plus.c} (66%)
 rename arch/arm/mach-omap2/{sleep44xx.S => sleep_omap4plus.S} (74%)

Regards,
Santosh

[1] git://github.com/SantoshShilimkar/linux.git	testing/3.10/omap5-int-rebuild

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 01/15] ARM: OMAP4+: PM: Consolidate MPU subsystem PM code for re-use
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

OMAP5 and future OMAP based SOCs has backward compatible MPUSS
IP block with OMAP4. It's programming model is mostly similar.
Hence consolidate the OMAP MPUSS code so that it can be re-used
on OMAP5 and future SOCs.

No functional change.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   56 +++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index abdd0f6..ee8a1e4 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -71,10 +71,37 @@ struct omap4_cpu_pm_info {
 	void (*secondary_startup)(void);
 };
 
+struct cpu_pm_ops {
+	int (*finish_suspend)(unsigned long cpu_state);
+	void (*resume)(void);
+	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+};
+
+extern int omap4_finish_suspend(unsigned long cpu_state);
+extern void omap4_cpu_resume(void);
+
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
 
+static int default_finish_suspend(unsigned long cpu_state)
+{
+	omap_do_wfi();
+	return 0;
+}
+
+static void dummy_cpu_resume(void)
+{}
+
+void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
+{}
+
+struct cpu_pm_ops omap_pm_ops = {
+	.finish_suspend		= default_finish_suspend,
+	.resume			= dummy_cpu_resume,
+	.scu_prepare		= dummy_scu_prepare,
+};
+
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
  * used for OFF or DORMANT wakeup.
@@ -203,11 +230,12 @@ static void save_l2x0_context(void)
 {
 	u32 val;
 	void __iomem *l2x0_base = omap4_get_l2cache_base();
-
-	val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
-	__raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
-	val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
-	__raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
+	if (l2x0_base) {
+		val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
+		__raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
+		val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
+		__raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
+	}
 }
 #else
 static void save_l2x0_context(void)
@@ -269,17 +297,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 
 	cpu_clear_prev_logic_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
-	set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
-	scu_pwrst_prepare(cpu, power_state);
+	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume));
+	omap_pm_ops.scu_prepare(cpu, power_state);
 	l2x0_pwrst_prepare(cpu, save_state);
 
 	/*
 	 * Call low level function  with targeted low power state.
 	 */
 	if (save_state)
-		cpu_suspend(save_state, omap4_finish_suspend);
+		cpu_suspend(save_state, omap_pm_ops.finish_suspend);
 	else
-		omap4_finish_suspend(save_state);
+		omap_pm_ops.finish_suspend(save_state);
 
 	/*
 	 * Restore the CPUx power state to ON otherwise CPUx
@@ -315,14 +343,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 	clear_cpu_prev_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
 	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
-	scu_pwrst_prepare(cpu, power_state);
+	omap_pm_ops.scu_prepare(cpu, power_state);
 
 	/*
 	 * CPU never retuns back if targeted power state is OFF mode.
 	 * CPU ONLINE follows normal CPU ONLINE ptah via
 	 * omap_secondary_startup().
 	 */
-	omap4_finish_suspend(cpu_state);
+	omap_pm_ops.finish_suspend(cpu_state);
 
 	set_cpu_next_pwrst(cpu, PWRDM_POWER_ON);
 	return 0;
@@ -399,6 +427,12 @@ int __init omap4_mpuss_init(void)
 
 	save_l2x0_context();
 
+	if (cpu_is_omap44xx()) {
+		omap_pm_ops.finish_suspend = omap4_finish_suspend;
+		omap_pm_ops.resume = omap4_cpu_resume;
+		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
+	}
+
 	return 0;
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 01/15] ARM: OMAP4+: PM: Consolidate MPU subsystem PM code for re-use
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

OMAP5 and future OMAP based SOCs has backward compatible MPUSS
IP block with OMAP4. It's programming model is mostly similar.
Hence consolidate the OMAP MPUSS code so that it can be re-used
on OMAP5 and future SOCs.

No functional change.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   56 +++++++++++++++++++++++------
 1 file changed, 45 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index abdd0f6..ee8a1e4 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -71,10 +71,37 @@ struct omap4_cpu_pm_info {
 	void (*secondary_startup)(void);
 };
 
+struct cpu_pm_ops {
+	int (*finish_suspend)(unsigned long cpu_state);
+	void (*resume)(void);
+	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+};
+
+extern int omap4_finish_suspend(unsigned long cpu_state);
+extern void omap4_cpu_resume(void);
+
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
 
+static int default_finish_suspend(unsigned long cpu_state)
+{
+	omap_do_wfi();
+	return 0;
+}
+
+static void dummy_cpu_resume(void)
+{}
+
+void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
+{}
+
+struct cpu_pm_ops omap_pm_ops = {
+	.finish_suspend		= default_finish_suspend,
+	.resume			= dummy_cpu_resume,
+	.scu_prepare		= dummy_scu_prepare,
+};
+
 /*
  * Program the wakeup routine address for the CPU0 and CPU1
  * used for OFF or DORMANT wakeup.
@@ -203,11 +230,12 @@ static void save_l2x0_context(void)
 {
 	u32 val;
 	void __iomem *l2x0_base = omap4_get_l2cache_base();
-
-	val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
-	__raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
-	val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
-	__raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
+	if (l2x0_base) {
+		val = __raw_readl(l2x0_base + L2X0_AUX_CTRL);
+		__raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET);
+		val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL);
+		__raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
+	}
 }
 #else
 static void save_l2x0_context(void)
@@ -269,17 +297,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 
 	cpu_clear_prev_logic_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
-	set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));
-	scu_pwrst_prepare(cpu, power_state);
+	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.resume));
+	omap_pm_ops.scu_prepare(cpu, power_state);
 	l2x0_pwrst_prepare(cpu, save_state);
 
 	/*
 	 * Call low level function  with targeted low power state.
 	 */
 	if (save_state)
-		cpu_suspend(save_state, omap4_finish_suspend);
+		cpu_suspend(save_state, omap_pm_ops.finish_suspend);
 	else
-		omap4_finish_suspend(save_state);
+		omap_pm_ops.finish_suspend(save_state);
 
 	/*
 	 * Restore the CPUx power state to ON otherwise CPUx
@@ -315,14 +343,14 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 	clear_cpu_prev_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
 	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
-	scu_pwrst_prepare(cpu, power_state);
+	omap_pm_ops.scu_prepare(cpu, power_state);
 
 	/*
 	 * CPU never retuns back if targeted power state is OFF mode.
 	 * CPU ONLINE follows normal CPU ONLINE ptah via
 	 * omap_secondary_startup().
 	 */
-	omap4_finish_suspend(cpu_state);
+	omap_pm_ops.finish_suspend(cpu_state);
 
 	set_cpu_next_pwrst(cpu, PWRDM_POWER_ON);
 	return 0;
@@ -399,6 +427,12 @@ int __init omap4_mpuss_init(void)
 
 	save_l2x0_context();
 
+	if (cpu_is_omap44xx()) {
+		omap_pm_ops.finish_suspend = omap4_finish_suspend;
+		omap_pm_ops.resume = omap4_cpu_resume;
+		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
+	}
+
 	return 0;
 }
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 02/15] ARM: OMAP5: PM: Update CPU context register offset
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

On OMAP5, RM_CPUi_CPUi_CONTEXT offset has changed. Update the code
so that same code works for OMAP4+ devices.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index ee8a1e4..bcd2efb 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -56,6 +56,7 @@
 #include "omap4-sar-layout.h"
 #include "pm.h"
 #include "prcm_mpu44xx.h"
+#include "prcm_mpu54xx.h"
 #include "prminst44xx.h"
 #include "prcm44xx.h"
 #include "prm44xx.h"
@@ -83,6 +84,7 @@ extern void omap4_cpu_resume(void);
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
+static u32 cpu_context_offset;
 
 static int default_finish_suspend(unsigned long cpu_state)
 {
@@ -186,14 +188,14 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
 
 	if (cpu_id) {
 		reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST,
-					OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
+					cpu_context_offset);
 		omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST,
-					OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
+					cpu_context_offset);
 	} else {
 		reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST,
-					OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
+					cpu_context_offset);
 		omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST,
-					OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
+					cpu_context_offset);
 	}
 }
 
@@ -431,6 +433,9 @@ int __init omap4_mpuss_init(void)
 		omap_pm_ops.finish_suspend = omap4_finish_suspend;
 		omap_pm_ops.resume = omap4_cpu_resume;
 		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
+		cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
+	} else if (soc_is_omap54xx()) {
+		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
 	}
 
 	return 0;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 02/15] ARM: OMAP5: PM: Update CPU context register offset
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

On OMAP5, RM_CPUi_CPUi_CONTEXT offset has changed. Update the code
so that same code works for OMAP4+ devices.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index ee8a1e4..bcd2efb 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -56,6 +56,7 @@
 #include "omap4-sar-layout.h"
 #include "pm.h"
 #include "prcm_mpu44xx.h"
+#include "prcm_mpu54xx.h"
 #include "prminst44xx.h"
 #include "prcm44xx.h"
 #include "prm44xx.h"
@@ -83,6 +84,7 @@ extern void omap4_cpu_resume(void);
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
+static u32 cpu_context_offset;
 
 static int default_finish_suspend(unsigned long cpu_state)
 {
@@ -186,14 +188,14 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
 
 	if (cpu_id) {
 		reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST,
-					OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
+					cpu_context_offset);
 		omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST,
-					OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
+					cpu_context_offset);
 	} else {
 		reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST,
-					OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
+					cpu_context_offset);
 		omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST,
-					OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
+					cpu_context_offset);
 	}
 }
 
@@ -431,6 +433,9 @@ int __init omap4_mpuss_init(void)
 		omap_pm_ops.finish_suspend = omap4_finish_suspend;
 		omap_pm_ops.resume = omap4_cpu_resume;
 		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
+		cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
+	} else if (soc_is_omap54xx()) {
+		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
 	}
 
 	return 0;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

OMAP5 has backward compatible PRCM block and it's programming
model is mostly similar to OMAP4. Same is going to be maintained
for future OMAP4 based SOCs. Hence consolidate the OMAP4 power
management code so that it can be re-used on OMAP5 and later devices.

With consolidated code, let basic power management code build
and initialise on OMAP5 devices.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/Makefile                       |    9 +-
 arch/arm/mach-omap2/{pm44xx.c => pm_omap4plus.c}   |   87 +++++++++++++-------
 .../mach-omap2/{sleep44xx.S => sleep_omap4plus.S}  |    0
 3 files changed, 60 insertions(+), 36 deletions(-)
 rename arch/arm/mach-omap2/{pm44xx.c => pm_omap4plus.c} (74%)
 rename arch/arm/mach-omap2/{sleep44xx.S => sleep_omap4plus.S} (100%)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 947cafe..7c3c6b6 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -32,14 +32,14 @@ obj-$(CONFIG_SOC_HAS_OMAP2_SDRC)	+= sdrc.o
 obj-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= omap-hotplug.o
 omap-4-5-common				=  omap4-common.o omap-wakeupgen.o \
-					   sleep44xx.o
+					   sleep_omap4plus.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-common)
 obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-common)
 
 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)
+AFLAGS_sleep_omap4plus.o		:=-Wa,-march=armv7-a$(plus_sec)
 
 # Functions loaded to SRAM
 obj-$(CONFIG_SOC_OMAP2420)		+= sram242x.o
@@ -76,11 +76,12 @@ endif
 obj-$(CONFIG_OMAP_PM_NOOP)		+= omap-pm-noop.o
 
 ifeq ($(CONFIG_PM),y)
+omap4plus-common-pm			=  omap-mpuss-lowpower.o pm_omap4plus.o
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o
-obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o omap-mpuss-lowpower.o
-obj-$(CONFIG_SOC_OMAP5)			+= omap-mpuss-lowpower.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-pm)
+obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-pm)
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 
 obj-$(CONFIG_POWER_AVS_OMAP)		+= sr_device.o
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm_omap4plus.c
similarity index 74%
rename from arch/arm/mach-omap2/pm44xx.c
rename to arch/arm/mach-omap2/pm_omap4plus.c
index 1d03110..95d2712 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm_omap4plus.c
@@ -1,7 +1,7 @@
 /*
- * OMAP4 Power Management Routines
+ * OMAP4PLUS Power Management Routines
  *
- * Copyright (C) 2010-2011 Texas Instruments, Inc.
+ * Copyright (C) 2010-2013 Texas Instruments, Inc.
  * Rajendra Nayak <rnayak@ti.com>
  * Santosh Shilimkar <santosh.shilimkar@ti.com>
  *
@@ -125,55 +125,77 @@ static void omap_default_idle(void)
 }
 
 /**
- * omap4_pm_init - Init routine for OMAP4 PM
+ * omap4_init_static_deps - Init static clkdm dependencies on OMAP4
  *
- * Initializes all powerdomain and clockdomain target states
- * and all PRCM settings.
+ * 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.
+ * The L4 wakeup depedency is added to workaround the OCP sync hardware
+ * BUG with 32K synctimer which lead to incorrect timer value read
+ * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
+ * are part of L4 wakeup clockdomain.
  */
-int __init omap4_pm_init(void)
+static inline int omap4_init_static_deps(void)
 {
 	int ret;
-	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
-	struct clockdomain *ducati_clkdm, *l3_2_clkdm;
+	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
+	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
 
-	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);
-	if (ret) {
-		pr_err("Failed to setup powerdomains\n");
-		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");
+	l4wkup = clkdm_lookup("l4_wkup_clkdm");
 	ducati_clkdm = clkdm_lookup("ducati_clkdm");
-	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
-		(!l3_2_clkdm) || (!ducati_clkdm))
-		goto err2;
+	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
+		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
+		return -EINVAL;
 
 	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(mpuss_clkdm, l4wkup);
 	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");
+	}
+
+	return ret;
+}
+
+/**
+ * omap4_pm_init - Init routine for OMAP4+ devices
+ *
+ * Initializes all powerdomain and clockdomain target states
+ * and all PRCM settings.
+ */
+int __init omap4_pm_init(void)
+{
+	int ret;
+
+	if (omap_rev() == OMAP4430_REV_ES1_0) {
+		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
+		return -ENODEV;
+	}
+
+	pr_info("Power Management for TI OMAP4PLUS devices.\n");
+
+	ret = pwrdm_for_each(pwrdms_setup, NULL);
+	if (ret) {
+		pr_err("Failed to setup powerdomains.\n");
 		goto err2;
 	}
 
+	if (cpu_is_omap44xx()) {
+		ret = omap4_init_static_deps();
+		if (ret)
+			goto err2;
+	}
+
 	ret = omap4_mpuss_init();
 	if (ret) {
 		pr_err("Failed to initialise OMAP4 MPUSS\n");
@@ -186,10 +208,11 @@ int __init omap4_pm_init(void)
 	omap_pm_suspend = omap4_pm_suspend;
 #endif
 
-	/* Overwrite the default cpu_do_idle() */
+	/* Overwrite the default arch_idle() */
 	arm_pm_idle = omap_default_idle;
 
-	omap4_idle_init();
+	if (cpu_is_omap44xx())
+		omap4_idle_init();
 
 err2:
 	return ret;
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep_omap4plus.S
similarity index 100%
rename from arch/arm/mach-omap2/sleep44xx.S
rename to arch/arm/mach-omap2/sleep_omap4plus.S
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

OMAP5 has backward compatible PRCM block and it's programming
model is mostly similar to OMAP4. Same is going to be maintained
for future OMAP4 based SOCs. Hence consolidate the OMAP4 power
management code so that it can be re-used on OMAP5 and later devices.

With consolidated code, let basic power management code build
and initialise on OMAP5 devices.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/Makefile                       |    9 +-
 arch/arm/mach-omap2/{pm44xx.c => pm_omap4plus.c}   |   87 +++++++++++++-------
 .../mach-omap2/{sleep44xx.S => sleep_omap4plus.S}  |    0
 3 files changed, 60 insertions(+), 36 deletions(-)
 rename arch/arm/mach-omap2/{pm44xx.c => pm_omap4plus.c} (74%)
 rename arch/arm/mach-omap2/{sleep44xx.S => sleep_omap4plus.S} (100%)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 947cafe..7c3c6b6 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -32,14 +32,14 @@ obj-$(CONFIG_SOC_HAS_OMAP2_SDRC)	+= sdrc.o
 obj-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= omap-hotplug.o
 omap-4-5-common				=  omap4-common.o omap-wakeupgen.o \
-					   sleep44xx.o
+					   sleep_omap4plus.o
 obj-$(CONFIG_ARCH_OMAP4)		+= $(omap-4-5-common)
 obj-$(CONFIG_SOC_OMAP5)			+= $(omap-4-5-common)
 
 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)
+AFLAGS_sleep_omap4plus.o		:=-Wa,-march=armv7-a$(plus_sec)
 
 # Functions loaded to SRAM
 obj-$(CONFIG_SOC_OMAP2420)		+= sram242x.o
@@ -76,11 +76,12 @@ endif
 obj-$(CONFIG_OMAP_PM_NOOP)		+= omap-pm-noop.o
 
 ifeq ($(CONFIG_PM),y)
+omap4plus-common-pm			=  omap-mpuss-lowpower.o pm_omap4plus.o
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o
-obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o omap-mpuss-lowpower.o
-obj-$(CONFIG_SOC_OMAP5)			+= omap-mpuss-lowpower.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-pm)
+obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-pm)
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 
 obj-$(CONFIG_POWER_AVS_OMAP)		+= sr_device.o
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm_omap4plus.c
similarity index 74%
rename from arch/arm/mach-omap2/pm44xx.c
rename to arch/arm/mach-omap2/pm_omap4plus.c
index 1d03110..95d2712 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm_omap4plus.c
@@ -1,7 +1,7 @@
 /*
- * OMAP4 Power Management Routines
+ * OMAP4PLUS Power Management Routines
  *
- * Copyright (C) 2010-2011 Texas Instruments, Inc.
+ * Copyright (C) 2010-2013 Texas Instruments, Inc.
  * Rajendra Nayak <rnayak@ti.com>
  * Santosh Shilimkar <santosh.shilimkar@ti.com>
  *
@@ -125,55 +125,77 @@ static void omap_default_idle(void)
 }
 
 /**
- * omap4_pm_init - Init routine for OMAP4 PM
+ * omap4_init_static_deps - Init static clkdm dependencies on OMAP4
  *
- * Initializes all powerdomain and clockdomain target states
- * and all PRCM settings.
+ * 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.
+ * The L4 wakeup depedency is added to workaround the OCP sync hardware
+ * BUG with 32K synctimer which lead to incorrect timer value read
+ * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
+ * are part of L4 wakeup clockdomain.
  */
-int __init omap4_pm_init(void)
+static inline int omap4_init_static_deps(void)
 {
 	int ret;
-	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
-	struct clockdomain *ducati_clkdm, *l3_2_clkdm;
+	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
+	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
 
-	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);
-	if (ret) {
-		pr_err("Failed to setup powerdomains\n");
-		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");
+	l4wkup = clkdm_lookup("l4_wkup_clkdm");
 	ducati_clkdm = clkdm_lookup("ducati_clkdm");
-	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
-		(!l3_2_clkdm) || (!ducati_clkdm))
-		goto err2;
+	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
+		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
+		return -EINVAL;
 
 	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(mpuss_clkdm, l4wkup);
 	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");
+	}
+
+	return ret;
+}
+
+/**
+ * omap4_pm_init - Init routine for OMAP4+ devices
+ *
+ * Initializes all powerdomain and clockdomain target states
+ * and all PRCM settings.
+ */
+int __init omap4_pm_init(void)
+{
+	int ret;
+
+	if (omap_rev() == OMAP4430_REV_ES1_0) {
+		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
+		return -ENODEV;
+	}
+
+	pr_info("Power Management for TI OMAP4PLUS devices.\n");
+
+	ret = pwrdm_for_each(pwrdms_setup, NULL);
+	if (ret) {
+		pr_err("Failed to setup powerdomains.\n");
 		goto err2;
 	}
 
+	if (cpu_is_omap44xx()) {
+		ret = omap4_init_static_deps();
+		if (ret)
+			goto err2;
+	}
+
 	ret = omap4_mpuss_init();
 	if (ret) {
 		pr_err("Failed to initialise OMAP4 MPUSS\n");
@@ -186,10 +208,11 @@ int __init omap4_pm_init(void)
 	omap_pm_suspend = omap4_pm_suspend;
 #endif
 
-	/* Overwrite the default cpu_do_idle() */
+	/* Overwrite the default arch_idle() */
 	arm_pm_idle = omap_default_idle;
 
-	omap4_idle_init();
+	if (cpu_is_omap44xx())
+		omap4_idle_init();
 
 err2:
 	return ret;
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep_omap4plus.S
similarity index 100%
rename from arch/arm/mach-omap2/sleep44xx.S
rename to arch/arm/mach-omap2/sleep_omap4plus.S
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 04/15] ARM: OMAP5: PM: Set MPUSS-EMIF clock-domain static dependency
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

With EMIF clock-domain put under hardware supervised control, memory
corruption and untraceable crashes are observed on OMAP5. Further
investigation revealed that there is a weakness in the PRCM on this
specific dynamic depedency.

The recommendation is to set MPUSS static dependency towards EMIF
clock-domain to avoid issues.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/pm_omap4plus.c |   36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/pm_omap4plus.c b/arch/arm/mach-omap2/pm_omap4plus.c
index 95d2712..4c37c47 100644
--- a/arch/arm/mach-omap2/pm_omap4plus.c
+++ b/arch/arm/mach-omap2/pm_omap4plus.c
@@ -168,6 +168,32 @@ static inline int omap4_init_static_deps(void)
 }
 
 /**
+ * omap5_init_static_deps - Init static clkdm dependencies on OMAP5
+ *
+ * The dynamic dependency between MPUSS -> EMIF is broken and has
+ * not worked as expected. The hardware recommendation is to
+ * enable static dependencies for these to avoid system
+ * lock ups or random crashes.
+ */
+static inline int omap5_init_static_deps(void)
+{
+	struct clockdomain *mpuss_clkdm, *emif_clkdm;
+	int ret;
+
+	mpuss_clkdm = clkdm_lookup("mpu_clkdm");
+	emif_clkdm = clkdm_lookup("emif_clkdm");
+	if (!mpuss_clkdm || !emif_clkdm)
+		return -EINVAL;
+
+	ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
+	if (ret)
+		pr_err("Failed to add MPUSS -> EMIF wakeup dependency\n");
+
+	return ret;
+}
+
+
+/**
  * omap4_pm_init - Init routine for OMAP4+ devices
  *
  * Initializes all powerdomain and clockdomain target states
@@ -190,10 +216,14 @@ int __init omap4_pm_init(void)
 		goto err2;
 	}
 
-	if (cpu_is_omap44xx()) {
+	if (cpu_is_omap44xx())
 		ret = omap4_init_static_deps();
-		if (ret)
-			goto err2;
+	else if (soc_is_omap54xx())
+		ret = omap5_init_static_deps();
+
+	if (ret) {
+		pr_err("Failed to initialise static dependencies.\n");
+		goto err2;
 	}
 
 	ret = omap4_mpuss_init();
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 04/15] ARM: OMAP5: PM: Set MPUSS-EMIF clock-domain static dependency
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

With EMIF clock-domain put under hardware supervised control, memory
corruption and untraceable crashes are observed on OMAP5. Further
investigation revealed that there is a weakness in the PRCM on this
specific dynamic depedency.

The recommendation is to set MPUSS static dependency towards EMIF
clock-domain to avoid issues.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/pm_omap4plus.c |   36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/pm_omap4plus.c b/arch/arm/mach-omap2/pm_omap4plus.c
index 95d2712..4c37c47 100644
--- a/arch/arm/mach-omap2/pm_omap4plus.c
+++ b/arch/arm/mach-omap2/pm_omap4plus.c
@@ -168,6 +168,32 @@ static inline int omap4_init_static_deps(void)
 }
 
 /**
+ * omap5_init_static_deps - Init static clkdm dependencies on OMAP5
+ *
+ * The dynamic dependency between MPUSS -> EMIF is broken and has
+ * not worked as expected. The hardware recommendation is to
+ * enable static dependencies for these to avoid system
+ * lock ups or random crashes.
+ */
+static inline int omap5_init_static_deps(void)
+{
+	struct clockdomain *mpuss_clkdm, *emif_clkdm;
+	int ret;
+
+	mpuss_clkdm = clkdm_lookup("mpu_clkdm");
+	emif_clkdm = clkdm_lookup("emif_clkdm");
+	if (!mpuss_clkdm || !emif_clkdm)
+		return -EINVAL;
+
+	ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
+	if (ret)
+		pr_err("Failed to add MPUSS -> EMIF wakeup dependency\n");
+
+	return ret;
+}
+
+
+/**
  * omap4_pm_init - Init routine for OMAP4+ devices
  *
  * Initializes all powerdomain and clockdomain target states
@@ -190,10 +216,14 @@ int __init omap4_pm_init(void)
 		goto err2;
 	}
 
-	if (cpu_is_omap44xx()) {
+	if (cpu_is_omap44xx())
 		ret = omap4_init_static_deps();
-		if (ret)
-			goto err2;
+	else if (soc_is_omap54xx())
+		ret = omap5_init_static_deps();
+
+	if (ret) {
+		pr_err("Failed to initialise static dependencies.\n");
+		goto err2;
 	}
 
 	ret = omap4_mpuss_init();
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

Enables MPUSS ES2 power management mode using ES2_PM_MODE in
AMBA_IF_MODE register.

0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. Broken
0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode independently.

This is one time settings thanks to always ON domain.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-secure.h    |    2 ++
 arch/arm/mach-omap2/omap-wakeupgen.c |   14 ++++++++++++++
 arch/arm/mach-omap2/omap-wakeupgen.h |    1 +
 3 files changed, 17 insertions(+)

diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index 0e72917..82b3c4c 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -42,6 +42,8 @@
 #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 
+#define OMAP5_MON_AMBA_IF_INDEX		0x108
+
 /* Secure PPA(Primary Protected Application) APIs */
 #define OMAP4_PPA_L2_POR_INDEX		0x23
 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 5d3b4f4..a7350dd 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -403,6 +403,7 @@ int __init omap_wakeupgen_init(void)
 {
 	int i;
 	unsigned int boot_cpu = smp_processor_id();
+	u32 val;
 
 	/* Not supported on OMAP4 ES1.0 silicon */
 	if (omap_rev() == OMAP4430_REV_ES1_0) {
@@ -444,6 +445,19 @@ int __init omap_wakeupgen_init(void)
 	for (i = 0; i < max_irqs; i++)
 		irq_target_cpu[i] = boot_cpu;
 
+	/*
+	 * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
+	 * 0x0:	ES1 behavior, CPU cores would enter and exit OFF mode together.
+	 * 0x1:	ES2 behavior, CPU cores are allowed to enter/exit OFF mode
+	 * independently.
+	 * This needs to be set one time thanks to always ON domain.
+	 */
+	if (soc_is_omap54xx()) {
+		val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
+		val |= BIT(5);
+		omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
+	}
+
 	irq_hotplug_init();
 	irq_pm_init();
 
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
index b0fd16f..b3c8ecc 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.h
+++ b/arch/arm/mach-omap2/omap-wakeupgen.h
@@ -27,6 +27,7 @@
 #define OMAP_WKG_ENB_E_1			0x420
 #define OMAP_AUX_CORE_BOOT_0			0x800
 #define OMAP_AUX_CORE_BOOT_1			0x804
+#define OMAP_AMBA_IF_MODE			0x80c
 #define OMAP_PTMSYNCREQ_MASK			0xc00
 #define OMAP_PTMSYNCREQ_EN			0xc04
 #define OMAP_TIMESTAMPCYCLELO			0xc08
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

Enables MPUSS ES2 power management mode using ES2_PM_MODE in
AMBA_IF_MODE register.

0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. Broken
0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode independently.

This is one time settings thanks to always ON domain.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-secure.h    |    2 ++
 arch/arm/mach-omap2/omap-wakeupgen.c |   14 ++++++++++++++
 arch/arm/mach-omap2/omap-wakeupgen.h |    1 +
 3 files changed, 17 insertions(+)

diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index 0e72917..82b3c4c 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -42,6 +42,8 @@
 #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 
+#define OMAP5_MON_AMBA_IF_INDEX		0x108
+
 /* Secure PPA(Primary Protected Application) APIs */
 #define OMAP4_PPA_L2_POR_INDEX		0x23
 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index 5d3b4f4..a7350dd 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -403,6 +403,7 @@ int __init omap_wakeupgen_init(void)
 {
 	int i;
 	unsigned int boot_cpu = smp_processor_id();
+	u32 val;
 
 	/* Not supported on OMAP4 ES1.0 silicon */
 	if (omap_rev() == OMAP4430_REV_ES1_0) {
@@ -444,6 +445,19 @@ int __init omap_wakeupgen_init(void)
 	for (i = 0; i < max_irqs; i++)
 		irq_target_cpu[i] = boot_cpu;
 
+	/*
+	 * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
+	 * 0x0:	ES1 behavior, CPU cores would enter and exit OFF mode together.
+	 * 0x1:	ES2 behavior, CPU cores are allowed to enter/exit OFF mode
+	 * independently.
+	 * This needs to be set one time thanks to always ON domain.
+	 */
+	if (soc_is_omap54xx()) {
+		val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
+		val |= BIT(5);
+		omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
+	}
+
 	irq_hotplug_init();
 	irq_pm_init();
 
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
index b0fd16f..b3c8ecc 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.h
+++ b/arch/arm/mach-omap2/omap-wakeupgen.h
@@ -27,6 +27,7 @@
 #define OMAP_WKG_ENB_E_1			0x420
 #define OMAP_AUX_CORE_BOOT_0			0x800
 #define OMAP_AUX_CORE_BOOT_1			0x804
+#define OMAP_AMBA_IF_MODE			0x80c
 #define OMAP_PTMSYNCREQ_MASK			0xc00
 #define OMAP_PTMSYNCREQ_EN			0xc04
 #define OMAP_TIMESTAMPCYCLELO			0xc08
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

In addition to the standard power-management technique, the OMAP5
MPU subsystem also employs an SR3-APG (mercury) power management
technology to reduce leakage.

It allows for full logic and memories retention on MPU_C0 and MPU_C1 and
is controlled by the PRCM_MPU.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index bcd2efb..9fda96b 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -360,6 +360,20 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 
 
 /*
+ * Enable Mercury Fast HG retention mode by default.
+ */
+static void enable_mercury_retention_mode(void)
+{
+	u32 reg;
+
+	reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
+			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
+	reg |= BIT(24) | BIT(25);
+	omap4_prcm_mpu_write_inst_reg(reg, OMAP54XX_PRCM_MPU_DEVICE_INST,
+			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
+}
+
+/*
  * Initialise OMAP4 MPUSS
  */
 int __init omap4_mpuss_init(void)
@@ -438,6 +452,9 @@ int __init omap4_mpuss_init(void)
 		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
 	}
 
+	if (soc_is_omap54xx())
+		enable_mercury_retention_mode();
+
 	return 0;
 }
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

In addition to the standard power-management technique, the OMAP5
MPU subsystem also employs an SR3-APG (mercury) power management
technology to reduce leakage.

It allows for full logic and memories retention on MPU_C0 and MPU_C1 and
is controlled by the PRCM_MPU.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index bcd2efb..9fda96b 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -360,6 +360,20 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 
 
 /*
+ * Enable Mercury Fast HG retention mode by default.
+ */
+static void enable_mercury_retention_mode(void)
+{
+	u32 reg;
+
+	reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
+			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
+	reg |= BIT(24) | BIT(25);
+	omap4_prcm_mpu_write_inst_reg(reg, OMAP54XX_PRCM_MPU_DEVICE_INST,
+			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
+}
+
+/*
  * Initialise OMAP4 MPUSS
  */
 int __init omap4_mpuss_init(void)
@@ -438,6 +452,9 @@ int __init omap4_mpuss_init(void)
 		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
 	}
 
+	if (soc_is_omap54xx())
+		enable_mercury_retention_mode();
+
 	return 0;
 }
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

With consolidated code, now we can add the .init_late hook for
OMAP5 to enable power management and mux initialization.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/board-generic.c |    1 +
 arch/arm/mach-omap2/common.h        |    3 ++-
 arch/arm/mach-omap2/io.c            |    8 ++++++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 53cb380b..eac4ec5 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -179,6 +179,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
 	.init_irq	= omap_gic_of_init,
 	.handle_irq	= gic_handle_irq,
 	.init_machine	= omap_generic_init,
+	.init_late	= omap5_init_late,
 	.timer		= &omap5_timer,
 	.dt_compat	= omap5_boards_compat,
 	.restart	= omap44xx_restart,
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index e0f9ea7..44fcf65 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -59,7 +59,7 @@ static inline int omap3_pm_init(void)
 }
 #endif
 
-#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5))
 int omap4_pm_init(void);
 #else
 static inline int omap4_pm_init(void)
@@ -108,6 +108,7 @@ void omap35xx_init_late(void);
 void omap3630_init_late(void);
 void am35xx_init_late(void);
 void ti81xx_init_late(void);
+void omap5_init_late(void);
 int omap2_common_pm_late_init(void);
 
 #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 2c3fdd6..e6ba596 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -620,6 +620,14 @@ void __init omap5_init_early(void)
 	omap_cm_base_init();
 	omap5xxx_check_revision();
 }
+
+void __init omap5_init_late(void)
+{
+	omap_mux_late_init();
+	omap2_common_pm_late_init();
+	omap4_pm_init();
+	omap2_clk_enable_autoidle_all();
+}
 #endif
 
 void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

With consolidated code, now we can add the .init_late hook for
OMAP5 to enable power management and mux initialization.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/board-generic.c |    1 +
 arch/arm/mach-omap2/common.h        |    3 ++-
 arch/arm/mach-omap2/io.c            |    8 ++++++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 53cb380b..eac4ec5 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -179,6 +179,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
 	.init_irq	= omap_gic_of_init,
 	.handle_irq	= gic_handle_irq,
 	.init_machine	= omap_generic_init,
+	.init_late	= omap5_init_late,
 	.timer		= &omap5_timer,
 	.dt_compat	= omap5_boards_compat,
 	.restart	= omap44xx_restart,
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index e0f9ea7..44fcf65 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -59,7 +59,7 @@ static inline int omap3_pm_init(void)
 }
 #endif
 
-#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
+#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5))
 int omap4_pm_init(void);
 #else
 static inline int omap4_pm_init(void)
@@ -108,6 +108,7 @@ void omap35xx_init_late(void);
 void omap3630_init_late(void);
 void am35xx_init_late(void);
 void ti81xx_init_late(void);
+void omap5_init_late(void);
 int omap2_common_pm_late_init(void);
 
 #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 2c3fdd6..e6ba596 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -620,6 +620,14 @@ void __init omap5_init_early(void)
 	omap_cm_base_init();
 	omap5xxx_check_revision();
 }
+
+void __init omap5_init_late(void)
+{
+	omap_mux_late_init();
+	omap2_common_pm_late_init();
+	omap4_pm_init();
+	omap2_clk_enable_autoidle_all();
+}
 #endif
 
 void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

Add power management code to handle the CPU off mode. Separate
suspend finisher is used for OMAP5(Cortex-A15) because it doesn't
use SCU power status register and external PL310 L2 cache which makes
code flow bit different.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   31 +++++++----
 arch/arm/mach-omap2/omap-secure.h         |    1 +
 arch/arm/mach-omap2/omap4-sar-layout.h    |    2 +
 arch/arm/mach-omap2/sleep_omap4plus.S     |   80 +++++++++++++++++++++++++++++
 4 files changed, 104 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 9fda96b..275f9a4 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -76,10 +76,12 @@ struct cpu_pm_ops {
 	int (*finish_suspend)(unsigned long cpu_state);
 	void (*resume)(void);
 	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+	void (*hotplug_restart)(void);
 };
 
 extern int omap4_finish_suspend(unsigned long cpu_state);
 extern void omap4_cpu_resume(void);
+extern int omap5_finish_suspend(unsigned long cpu_state);
 
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
@@ -102,6 +104,7 @@ struct cpu_pm_ops omap_pm_ops = {
 	.finish_suspend		= default_finish_suspend,
 	.resume			= dummy_cpu_resume,
 	.scu_prepare		= dummy_scu_prepare,
+	.hotplug_restart	= dummy_cpu_resume,
 };
 
 /*
@@ -334,7 +337,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 {
 	unsigned int cpu_state = 0;
-	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
 
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		return -ENXIO;
@@ -344,7 +346,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 
 	clear_cpu_prev_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
-	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
+	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
 	omap_pm_ops.scu_prepare(cpu, power_state);
 
 	/*
@@ -379,6 +381,7 @@ static void enable_mercury_retention_mode(void)
 int __init omap4_mpuss_init(void)
 {
 	struct omap4_cpu_pm_info *pm_info;
+	u32 cpu_wakeup_addr = 0;
 
 	if (omap_rev() == OMAP4430_REV_ES1_0) {
 		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
@@ -388,9 +391,13 @@ int __init omap4_mpuss_init(void)
 	sar_base = omap4_get_sar_ram_base();
 
 	/* Initilaise per CPU PM information */
+	if (cpu_is_omap44xx())
+		cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+	else if (soc_is_omap54xx())
+		cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
 	pm_info = &per_cpu(omap4_pm_info, 0x0);
 	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
-	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
 	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
 	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
 	if (!pm_info->pwrdm) {
@@ -405,14 +412,14 @@ int __init omap4_mpuss_init(void)
 	/* Initialise CPU0 power domain state to ON */
 	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
 
+	if (cpu_is_omap44xx())
+		cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+	else if (soc_is_omap54xx())
+		cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
 	pm_info = &per_cpu(omap4_pm_info, 0x1);
 	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
-	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
 	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
-	if (cpu_is_omap446x())
-		pm_info->secondary_startup = omap_secondary_startup_4460;
-	else
-		pm_info->secondary_startup = omap_secondary_startup;
 
 	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
 	if (!pm_info->pwrdm) {
@@ -445,15 +452,19 @@ int __init omap4_mpuss_init(void)
 
 	if (cpu_is_omap44xx()) {
 		omap_pm_ops.finish_suspend = omap4_finish_suspend;
+		omap_pm_ops.hotplug_restart = omap_secondary_startup;
 		omap_pm_ops.resume = omap4_cpu_resume;
 		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
 		cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
 	} else if (soc_is_omap54xx()) {
+		omap_pm_ops.finish_suspend = omap5_finish_suspend;
+		omap_pm_ops.hotplug_restart = omap5_secondary_startup;
 		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
+		enable_mercury_retention_mode();
 	}
 
-	if (soc_is_omap54xx())
-		enable_mercury_retention_mode();
+	if (cpu_is_omap446x())
+		omap_pm_ops.hotplug_restart = omap_secondary_startup_4460;
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index 82b3c4c..6f4dbee 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -41,6 +41,7 @@
 #define OMAP4_MON_L2X0_CTRL_INDEX	0x102
 #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
+#define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
 
 #define OMAP5_MON_AMBA_IF_INDEX		0x108
 
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index 6822d0a..ee8215b 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -31,6 +31,8 @@
 /* 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
+#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
+#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
 
 #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
 #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
index 88ff83a..3322fc8 100644
--- a/arch/arm/mach-omap2/sleep_omap4plus.S
+++ b/arch/arm/mach-omap2/sleep_omap4plus.S
@@ -326,6 +326,86 @@ skip_l2en:
 
 	b	cpu_resume			@ Jump to generic resume
 ENDPROC(omap4_cpu_resume)
+
+/*
+ * ================================
+ * == OMAP5 CPU suspend finisher ==
+ * ================================
+ *
+ * OMAP5 MPUSS states for the context save:
+ * save_state =
+ *	0 - Nothing lost and no need to save: MPUSS INA/CSWR
+ *	1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR
+ *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
+ *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
+ */
+ENTRY(omap5_finish_suspend)
+	stmfd	sp!, {r4-r12, lr}
+	cmp	r0, #0x0
+	beq	do_wfi				@ No lowpower state, jump to WFI
+
+	/*
+	 * Flush all data from the L1 data cache before disabling
+	 * SCTLR.C bit.
+	 */
+	bl	omap4_get_sar_ram_base
+	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
+	cmp	r9, #0x1			@ Check for HS device
+	bne	skip_secure_l1_clean_op
+	mov	r0, #0				@ Clean secure L1
+	stmfd   r13!, {r4-r12, r14}
+	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
+	DO_SMC
+	ldmfd   r13!, {r4-r12, r14}
+skip_secure_l1_clean_op:
+	bl	v7_flush_dcache_louis
+
+	/*
+	 * Clear the SCTLR.C bit to prevent further data cache
+	 * allocation. Clearing SCTLR.C would make all the data accesses
+	 * strongly ordered and would not hit the cache.
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #(1 << 2)		@ Disable the C bit
+	mcr	p15, 0, r0, c1, c0, 0
+	isb
+
+	/* Clean and Invalidate L1 data cache. */
+	bl	v7_flush_dcache_louis
+
+	/*
+	 * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus
+	 * preventing the CPU from receiving cache, TLB, or BTB
+	 * maintenance operations broadcast by other CPUs in the cluster.
+	 */
+	mrc	p15, 0, r0, c1, c1, 2		@ Read NSACR data
+	tst	r0, #(1 << 18)
+	mrcne	p15, 0, r0, c1, c0, 1
+	bicne	r0, r0, #(1 << 6)		@ Disable SMP bit
+	mcrne	p15, 0, r0, c1, c0, 1
+	isb
+	dsb
+
+do_wfi:
+	bl	omap_do_wfi
+
+	/*
+	 * CPU is here when it failed to enter OFF/DORMANT or
+	 * no low power state was attempted.
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	tst	r0, #(1 << 2)			@ Check C bit enabled?
+	orreq	r0, r0, #(1 << 2)		@ Enable the C bit
+	mcreq	p15, 0, r0, c1, c0, 0
+	isb
+	mrc	p15, 0, r0, c1, c0, 1
+	tst	r0, #(1 << 6)			@ Check SMP bit enabled?
+	orreq	r0, r0, #(1 << 6)
+	mcreq	p15, 0, r0, c1, c0, 1
+	isb
+	dsb
+	ldmfd	sp!, {r4-r12, pc}
+ENDPROC(omap5_finish_suspend)
 #endif
 
 #ifndef CONFIG_OMAP4_ERRATA_I688
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

Add power management code to handle the CPU off mode. Separate
suspend finisher is used for OMAP5(Cortex-A15) because it doesn't
use SCU power status register and external PL310 L2 cache which makes
code flow bit different.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   31 +++++++----
 arch/arm/mach-omap2/omap-secure.h         |    1 +
 arch/arm/mach-omap2/omap4-sar-layout.h    |    2 +
 arch/arm/mach-omap2/sleep_omap4plus.S     |   80 +++++++++++++++++++++++++++++
 4 files changed, 104 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 9fda96b..275f9a4 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -76,10 +76,12 @@ struct cpu_pm_ops {
 	int (*finish_suspend)(unsigned long cpu_state);
 	void (*resume)(void);
 	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
+	void (*hotplug_restart)(void);
 };
 
 extern int omap4_finish_suspend(unsigned long cpu_state);
 extern void omap4_cpu_resume(void);
+extern int omap5_finish_suspend(unsigned long cpu_state);
 
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
@@ -102,6 +104,7 @@ struct cpu_pm_ops omap_pm_ops = {
 	.finish_suspend		= default_finish_suspend,
 	.resume			= dummy_cpu_resume,
 	.scu_prepare		= dummy_scu_prepare,
+	.hotplug_restart	= dummy_cpu_resume,
 };
 
 /*
@@ -334,7 +337,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 {
 	unsigned int cpu_state = 0;
-	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
 
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		return -ENXIO;
@@ -344,7 +346,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
 
 	clear_cpu_prev_pwrst(cpu);
 	set_cpu_next_pwrst(cpu, power_state);
-	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
+	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
 	omap_pm_ops.scu_prepare(cpu, power_state);
 
 	/*
@@ -379,6 +381,7 @@ static void enable_mercury_retention_mode(void)
 int __init omap4_mpuss_init(void)
 {
 	struct omap4_cpu_pm_info *pm_info;
+	u32 cpu_wakeup_addr = 0;
 
 	if (omap_rev() == OMAP4430_REV_ES1_0) {
 		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
@@ -388,9 +391,13 @@ int __init omap4_mpuss_init(void)
 	sar_base = omap4_get_sar_ram_base();
 
 	/* Initilaise per CPU PM information */
+	if (cpu_is_omap44xx())
+		cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+	else if (soc_is_omap54xx())
+		cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
 	pm_info = &per_cpu(omap4_pm_info, 0x0);
 	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
-	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
+	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
 	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
 	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
 	if (!pm_info->pwrdm) {
@@ -405,14 +412,14 @@ int __init omap4_mpuss_init(void)
 	/* Initialise CPU0 power domain state to ON */
 	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
 
+	if (cpu_is_omap44xx())
+		cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+	else if (soc_is_omap54xx())
+		cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
 	pm_info = &per_cpu(omap4_pm_info, 0x1);
 	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
-	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
+	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
 	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
-	if (cpu_is_omap446x())
-		pm_info->secondary_startup = omap_secondary_startup_4460;
-	else
-		pm_info->secondary_startup = omap_secondary_startup;
 
 	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
 	if (!pm_info->pwrdm) {
@@ -445,15 +452,19 @@ int __init omap4_mpuss_init(void)
 
 	if (cpu_is_omap44xx()) {
 		omap_pm_ops.finish_suspend = omap4_finish_suspend;
+		omap_pm_ops.hotplug_restart = omap_secondary_startup;
 		omap_pm_ops.resume = omap4_cpu_resume;
 		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
 		cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
 	} else if (soc_is_omap54xx()) {
+		omap_pm_ops.finish_suspend = omap5_finish_suspend;
+		omap_pm_ops.hotplug_restart = omap5_secondary_startup;
 		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
+		enable_mercury_retention_mode();
 	}
 
-	if (soc_is_omap54xx())
-		enable_mercury_retention_mode();
+	if (cpu_is_omap446x())
+		omap_pm_ops.hotplug_restart = omap_secondary_startup_4460;
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index 82b3c4c..6f4dbee 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -41,6 +41,7 @@
 #define OMAP4_MON_L2X0_CTRL_INDEX	0x102
 #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
+#define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
 
 #define OMAP5_MON_AMBA_IF_INDEX		0x108
 
diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
index 6822d0a..ee8215b 100644
--- a/arch/arm/mach-omap2/omap4-sar-layout.h
+++ b/arch/arm/mach-omap2/omap4-sar-layout.h
@@ -31,6 +31,8 @@
 /* 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
+#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
+#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
 
 #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
 #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
index 88ff83a..3322fc8 100644
--- a/arch/arm/mach-omap2/sleep_omap4plus.S
+++ b/arch/arm/mach-omap2/sleep_omap4plus.S
@@ -326,6 +326,86 @@ skip_l2en:
 
 	b	cpu_resume			@ Jump to generic resume
 ENDPROC(omap4_cpu_resume)
+
+/*
+ * ================================
+ * == OMAP5 CPU suspend finisher ==
+ * ================================
+ *
+ * OMAP5 MPUSS states for the context save:
+ * save_state =
+ *	0 - Nothing lost and no need to save: MPUSS INA/CSWR
+ *	1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR
+ *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
+ *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
+ */
+ENTRY(omap5_finish_suspend)
+	stmfd	sp!, {r4-r12, lr}
+	cmp	r0, #0x0
+	beq	do_wfi				@ No lowpower state, jump to WFI
+
+	/*
+	 * Flush all data from the L1 data cache before disabling
+	 * SCTLR.C bit.
+	 */
+	bl	omap4_get_sar_ram_base
+	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
+	cmp	r9, #0x1			@ Check for HS device
+	bne	skip_secure_l1_clean_op
+	mov	r0, #0				@ Clean secure L1
+	stmfd   r13!, {r4-r12, r14}
+	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
+	DO_SMC
+	ldmfd   r13!, {r4-r12, r14}
+skip_secure_l1_clean_op:
+	bl	v7_flush_dcache_louis
+
+	/*
+	 * Clear the SCTLR.C bit to prevent further data cache
+	 * allocation. Clearing SCTLR.C would make all the data accesses
+	 * strongly ordered and would not hit the cache.
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #(1 << 2)		@ Disable the C bit
+	mcr	p15, 0, r0, c1, c0, 0
+	isb
+
+	/* Clean and Invalidate L1 data cache. */
+	bl	v7_flush_dcache_louis
+
+	/*
+	 * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus
+	 * preventing the CPU from receiving cache, TLB, or BTB
+	 * maintenance operations broadcast by other CPUs in the cluster.
+	 */
+	mrc	p15, 0, r0, c1, c1, 2		@ Read NSACR data
+	tst	r0, #(1 << 18)
+	mrcne	p15, 0, r0, c1, c0, 1
+	bicne	r0, r0, #(1 << 6)		@ Disable SMP bit
+	mcrne	p15, 0, r0, c1, c0, 1
+	isb
+	dsb
+
+do_wfi:
+	bl	omap_do_wfi
+
+	/*
+	 * CPU is here when it failed to enter OFF/DORMANT or
+	 * no low power state was attempted.
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	tst	r0, #(1 << 2)			@ Check C bit enabled?
+	orreq	r0, r0, #(1 << 2)		@ Enable the C bit
+	mcreq	p15, 0, r0, c1, c0, 0
+	isb
+	mrc	p15, 0, r0, c1, c0, 1
+	tst	r0, #(1 << 6)			@ Check SMP bit enabled?
+	orreq	r0, r0, #(1 << 6)
+	mcreq	p15, 0, r0, c1, c0, 1
+	isb
+	dsb
+	ldmfd	sp!, {r4-r12, pc}
+ENDPROC(omap5_finish_suspend)
 #endif
 
 #ifndef CONFIG_OMAP4_ERRATA_I688
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 09/15] ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

While waking up CPU from off state using clock domain force wakeup, restore
the CPU power state to ON state before putting CPU clock domain under
hardware control. Otherwise CPU wakeup might fail. The change is recommended\
for all OMAP4+ devices though the PRCM weakness was observed on OMAP5
devices first.

So update the code accordingly.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c |    1 +
 arch/arm/mach-omap2/omap-smp.c    |   12 ++++++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 944e64a..9de47a7 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -131,6 +131,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
 	/* Wakeup CPU1 only if it is not offlined */
 	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
 		clkdm_wakeup(cpu_clkdm[1]);
+		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
 		clkdm_allow_idle(cpu_clkdm[1]);
 	}
 
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 9711ecd..ba63b14 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -83,6 +83,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
 {
 	static struct clockdomain *cpu1_clkdm;
 	static bool booted;
+	static struct powerdomain *cpu1_pwrdm;
 	void __iomem *base = omap_get_wakeupgen_base();
 
 	/*
@@ -102,8 +103,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
 	else
 		__raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0);
 
-	if (!cpu1_clkdm)
+	if (!cpu1_clkdm && !cpu1_pwrdm) {
 		cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
+		cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
+	}
 
 	/*
 	 * The SGI(Software Generated Interrupts) are not wakeup capable
@@ -116,7 +119,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
 	 * Section :
 	 *	4.3.4.2 Power States of CPU0 and CPU1
 	 */
-	if (booted) {
+	if (booted && cpu1_pwrdm && cpu1_clkdm) {
 		/*
 		 * GIC distributor control register has changed between
 		 * CortexA9 r1pX and r2pX. The Control Register secure
@@ -137,7 +140,12 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
 			gic_dist_disable();
 		}
 
+		/*
+		 * Ensure that CPU power state is set to ON to avoid CPU
+		 * powerdomain transition on wfi
+		 */
 		clkdm_wakeup(cpu1_clkdm);
+		omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);
 		clkdm_allow_idle(cpu1_clkdm);
 
 		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 09/15] ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

While waking up CPU from off state using clock domain force wakeup, restore
the CPU power state to ON state before putting CPU clock domain under
hardware control. Otherwise CPU wakeup might fail. The change is recommended\
for all OMAP4+ devices though the PRCM weakness was observed on OMAP5
devices first.

So update the code accordingly.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c |    1 +
 arch/arm/mach-omap2/omap-smp.c    |   12 ++++++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 944e64a..9de47a7 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -131,6 +131,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
 	/* Wakeup CPU1 only if it is not offlined */
 	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
 		clkdm_wakeup(cpu_clkdm[1]);
+		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
 		clkdm_allow_idle(cpu_clkdm[1]);
 	}
 
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 9711ecd..ba63b14 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -83,6 +83,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
 {
 	static struct clockdomain *cpu1_clkdm;
 	static bool booted;
+	static struct powerdomain *cpu1_pwrdm;
 	void __iomem *base = omap_get_wakeupgen_base();
 
 	/*
@@ -102,8 +103,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
 	else
 		__raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0);
 
-	if (!cpu1_clkdm)
+	if (!cpu1_clkdm && !cpu1_pwrdm) {
 		cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
+		cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
+	}
 
 	/*
 	 * The SGI(Software Generated Interrupts) are not wakeup capable
@@ -116,7 +119,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
 	 * Section :
 	 *	4.3.4.2 Power States of CPU0 and CPU1
 	 */
-	if (booted) {
+	if (booted && cpu1_pwrdm && cpu1_clkdm) {
 		/*
 		 * GIC distributor control register has changed between
 		 * CortexA9 r1pX and r2pX. The Control Register secure
@@ -137,7 +140,12 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
 			gic_dist_disable();
 		}
 
+		/*
+		 * Ensure that CPU power state is set to ON to avoid CPU
+		 * powerdomain transition on wfi
+		 */
 		clkdm_wakeup(cpu1_clkdm);
+		omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);
 		clkdm_allow_idle(cpu1_clkdm);
 
 		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 10/15] ARM: OMAP5: PM: Add MPU Open Switch Retention support
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:10   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

In MPUSS OSWR(Open Switch Retention), entire CPU cluster is powered down
except L2 cache memory. For MPUSS OSWR state, both CPU's needs to be in
power off state.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |    2 ++
 arch/arm/mach-omap2/omap-secure.h         |    5 +++++
 arch/arm/mach-omap2/omap-wakeupgen.c      |   11 ++++++-----
 arch/arm/mach-omap2/sleep_omap4plus.S     |   23 +++++++++++++++++++++++
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 275f9a4..c1c6b9d 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -82,6 +82,7 @@ struct cpu_pm_ops {
 extern int omap4_finish_suspend(unsigned long cpu_state);
 extern void omap4_cpu_resume(void);
 extern int omap5_finish_suspend(unsigned long cpu_state);
+extern void omap5_cpu_resume(void);
 
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
@@ -459,6 +460,7 @@ int __init omap4_mpuss_init(void)
 	} else if (soc_is_omap54xx()) {
 		omap_pm_ops.finish_suspend = omap5_finish_suspend;
 		omap_pm_ops.hotplug_restart = omap5_secondary_startup;
+		omap_pm_ops.resume = omap5_cpu_resume;
 		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
 		enable_mercury_retention_mode();
 	}
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index 6f4dbee..1739468 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -34,6 +34,10 @@
 #define OMAP4_HAL_SAVEHW_INDEX		0x1b
 #define OMAP4_HAL_SAVEALL_INDEX		0x1c
 #define OMAP4_HAL_SAVEGIC_INDEX		0x1d
+#define OMAP5_HAL_SAVESECURERAM_INDEX	0x1c
+#define OMAP5_HAL_SAVEHW_INDEX		0x1d
+#define OMAP5_HAL_SAVEALL_INDEX		0x1e
+#define OMAP5_HAL_SAVEGIC_INDEX		0x1f
 
 /* Secure Monitor mode APIs */
 #define OMAP4_MON_SCU_PWR_INDEX		0x108
@@ -42,6 +46,7 @@
 #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
+#define OMAP5_MON_AUX_CTRL_INDEX	0x107
 
 #define OMAP5_MON_AMBA_IF_INDEX		0x108
 
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index a7350dd..f57b0b8 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[MAX_IRQS];
 static unsigned int irq_banks = MAX_NR_REG_BANKS;
 static unsigned int max_irqs = MAX_IRQS;
-static unsigned int omap_secure_apis;
+static unsigned int omap_secure_apis, secure_api_index;
 
 /*
  * Static helper functions.
@@ -315,7 +315,7 @@ static void irq_sar_clear(void)
 static void irq_save_secure_context(void)
 {
 	u32 ret;
-	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
+	ret = omap_secure_dispatcher(secure_api_index,
 				FLAG_START_CRITICAL,
 				0, 0, 0, 0, 0);
 	if (ret != API_HAL_RET_VALUE_OK)
@@ -377,9 +377,7 @@ static struct notifier_block irq_notifier_block = {
 
 static void __init irq_pm_init(void)
 {
-	/* FIXME: Remove this when MPU OSWR support is added */
-	if (!soc_is_omap54xx())
-		cpu_pm_register_notifier(&irq_notifier_block);
+	cpu_pm_register_notifier(&irq_notifier_block);
 }
 #else
 static void __init irq_pm_init(void)
@@ -420,6 +418,9 @@ int __init omap_wakeupgen_init(void)
 		irq_banks = OMAP4_NR_BANKS;
 		max_irqs = OMAP4_NR_IRQS;
 		omap_secure_apis = 1;
+		secure_api_index = OMAP4_HAL_SAVEGIC_INDEX;
+	} else if (soc_is_omap54xx()) {
+		secure_api_index = OMAP5_HAL_SAVEGIC_INDEX;
 	}
 
 	/* Clear all IRQ bitmasks at wakeupGen level */
diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
index 3322fc8..f4874e5 100644
--- a/arch/arm/mach-omap2/sleep_omap4plus.S
+++ b/arch/arm/mach-omap2/sleep_omap4plus.S
@@ -406,6 +406,29 @@ do_wfi:
 	dsb
 	ldmfd	sp!, {r4-r12, pc}
 ENDPROC(omap5_finish_suspend)
+
+ENTRY(omap5_cpu_resume)
+#ifdef CONFIG_ARM_ERRATA_761171
+	/*
+	 * Work around for errata for 761171. Streaming write that will not
+	 * allocate in L2 could lead to data corruption.
+	 */
+	mrc	p15, 0, r0, c0, c0, 0		@ read main ID register
+	and	r5, r0, #0x00f00000		@ variant
+	and	r6, r0, #0x0000000f		@ revision
+	orr	r6, r6, r5, lsr #20-4		@ combine variant and revision
+	cmp	r6, #0x03			@ Present before r0p3
+	bgt	1f
+	mrc	p15, 0, r0, c1, c0, 1		@ Read Auxctrl
+	orr	r0, r0, #0x3 << 27		@ bits[28:27]-L1_mode3_threshold
+	ldr	r12, =OMAP5_MON_AUX_CTRL_INDEX
+	dsb
+	smc	#0
+	dsb
+1:
+#endif
+	b	cpu_resume			@ Jump to generic resume
+ENDPROC(omap5_cpu_resume)
 #endif
 
 #ifndef CONFIG_OMAP4_ERRATA_I688
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 10/15] ARM: OMAP5: PM: Add MPU Open Switch Retention support
@ 2013-03-01 12:10   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:10 UTC (permalink / raw)
  To: linux-arm-kernel

In MPUSS OSWR(Open Switch Retention), entire CPU cluster is powered down
except L2 cache memory. For MPUSS OSWR state, both CPU's needs to be in
power off state.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |    2 ++
 arch/arm/mach-omap2/omap-secure.h         |    5 +++++
 arch/arm/mach-omap2/omap-wakeupgen.c      |   11 ++++++-----
 arch/arm/mach-omap2/sleep_omap4plus.S     |   23 +++++++++++++++++++++++
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 275f9a4..c1c6b9d 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -82,6 +82,7 @@ struct cpu_pm_ops {
 extern int omap4_finish_suspend(unsigned long cpu_state);
 extern void omap4_cpu_resume(void);
 extern int omap5_finish_suspend(unsigned long cpu_state);
+extern void omap5_cpu_resume(void);
 
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
@@ -459,6 +460,7 @@ int __init omap4_mpuss_init(void)
 	} else if (soc_is_omap54xx()) {
 		omap_pm_ops.finish_suspend = omap5_finish_suspend;
 		omap_pm_ops.hotplug_restart = omap5_secondary_startup;
+		omap_pm_ops.resume = omap5_cpu_resume;
 		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
 		enable_mercury_retention_mode();
 	}
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index 6f4dbee..1739468 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -34,6 +34,10 @@
 #define OMAP4_HAL_SAVEHW_INDEX		0x1b
 #define OMAP4_HAL_SAVEALL_INDEX		0x1c
 #define OMAP4_HAL_SAVEGIC_INDEX		0x1d
+#define OMAP5_HAL_SAVESECURERAM_INDEX	0x1c
+#define OMAP5_HAL_SAVEHW_INDEX		0x1d
+#define OMAP5_HAL_SAVEALL_INDEX		0x1e
+#define OMAP5_HAL_SAVEGIC_INDEX		0x1f
 
 /* Secure Monitor mode APIs */
 #define OMAP4_MON_SCU_PWR_INDEX		0x108
@@ -42,6 +46,7 @@
 #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
+#define OMAP5_MON_AUX_CTRL_INDEX	0x107
 
 #define OMAP5_MON_AMBA_IF_INDEX		0x108
 
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
index a7350dd..f57b0b8 100644
--- a/arch/arm/mach-omap2/omap-wakeupgen.c
+++ b/arch/arm/mach-omap2/omap-wakeupgen.c
@@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(wakeupgen_lock);
 static unsigned int irq_target_cpu[MAX_IRQS];
 static unsigned int irq_banks = MAX_NR_REG_BANKS;
 static unsigned int max_irqs = MAX_IRQS;
-static unsigned int omap_secure_apis;
+static unsigned int omap_secure_apis, secure_api_index;
 
 /*
  * Static helper functions.
@@ -315,7 +315,7 @@ static void irq_sar_clear(void)
 static void irq_save_secure_context(void)
 {
 	u32 ret;
-	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
+	ret = omap_secure_dispatcher(secure_api_index,
 				FLAG_START_CRITICAL,
 				0, 0, 0, 0, 0);
 	if (ret != API_HAL_RET_VALUE_OK)
@@ -377,9 +377,7 @@ static struct notifier_block irq_notifier_block = {
 
 static void __init irq_pm_init(void)
 {
-	/* FIXME: Remove this when MPU OSWR support is added */
-	if (!soc_is_omap54xx())
-		cpu_pm_register_notifier(&irq_notifier_block);
+	cpu_pm_register_notifier(&irq_notifier_block);
 }
 #else
 static void __init irq_pm_init(void)
@@ -420,6 +418,9 @@ int __init omap_wakeupgen_init(void)
 		irq_banks = OMAP4_NR_BANKS;
 		max_irqs = OMAP4_NR_IRQS;
 		omap_secure_apis = 1;
+		secure_api_index = OMAP4_HAL_SAVEGIC_INDEX;
+	} else if (soc_is_omap54xx()) {
+		secure_api_index = OMAP5_HAL_SAVEGIC_INDEX;
 	}
 
 	/* Clear all IRQ bitmasks at wakeupGen level */
diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
index 3322fc8..f4874e5 100644
--- a/arch/arm/mach-omap2/sleep_omap4plus.S
+++ b/arch/arm/mach-omap2/sleep_omap4plus.S
@@ -406,6 +406,29 @@ do_wfi:
 	dsb
 	ldmfd	sp!, {r4-r12, pc}
 ENDPROC(omap5_finish_suspend)
+
+ENTRY(omap5_cpu_resume)
+#ifdef CONFIG_ARM_ERRATA_761171
+	/*
+	 * Work around for errata for 761171. Streaming write that will not
+	 * allocate in L2 could lead to data corruption.
+	 */
+	mrc	p15, 0, r0, c0, c0, 0		@ read main ID register
+	and	r5, r0, #0x00f00000		@ variant
+	and	r6, r0, #0x0000000f		@ revision
+	orr	r6, r6, r5, lsr #20-4		@ combine variant and revision
+	cmp	r6, #0x03			@ Present before r0p3
+	bgt	1f
+	mrc	p15, 0, r0, c1, c0, 1		@ Read Auxctrl
+	orr	r0, r0, #0x3 << 27		@ bits[28:27]-L1_mode3_threshold
+	ldr	r12, =OMAP5_MON_AUX_CTRL_INDEX
+	dsb
+	smc	#0
+	dsb
+1:
+#endif
+	b	cpu_resume			@ Jump to generic resume
+ENDPROC(omap5_cpu_resume)
 #endif
 
 #ifndef CONFIG_OMAP4_ERRATA_I688
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:11   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

When the entire MPUSS cluster is powered down in device off state, L2 cache
memory looses it's content and hence while targetting such a state,
l2 cache needs to be flushed to main memory.

Add the necessary low power code support for the same.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-secure.h     |    1 +
 arch/arm/mach-omap2/sleep_omap4plus.S |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index 1739468..a171a5a 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -47,6 +47,7 @@
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
 #define OMAP5_MON_AUX_CTRL_INDEX	0x107
+#define OMAP5_MON_L2AUX_CTRL_INDEX	0x104
 
 #define OMAP5_MON_AMBA_IF_INDEX		0x108
 
diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
index f4874e5..ea318be 100644
--- a/arch/arm/mach-omap2/sleep_omap4plus.S
+++ b/arch/arm/mach-omap2/sleep_omap4plus.S
@@ -386,6 +386,27 @@ skip_secure_l1_clean_op:
 	isb
 	dsb
 
+	bl	omap4_get_sar_ram_base
+	mov	r8, r0
+	mrc	p15, 0, r5, c0, c0, 5		@ Read MPIDR
+	ands	r5, r5, #0x0f
+	ldreq	r0, [r8, #L2X0_SAVE_OFFSET0]	@ Retrieve L2 state
+	ldrne	r0, [r8, #L2X0_SAVE_OFFSET1]
+	cmp	r0, #3
+	bne	do_wfi
+	bl	omap4_get_sar_ram_base
+	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
+	cmp	r9, #0x1			@ Check for HS device
+	bne	skip_secure_l2_clean_op
+	mov	r0, #1				@ Clean secure L2
+	stmfd   r13!, {r4-r12, r14}
+	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
+	DO_SMC
+	ldmfd   r13!, {r4-r12, r14}
+skip_secure_l2_clean_op:
+	mov	r0, #2				@ Flush L2
+	bl	v7_flush_dcache_all
+
 do_wfi:
 	bl	omap_do_wfi
 
@@ -427,6 +448,15 @@ ENTRY(omap5_cpu_resume)
 	dsb
 1:
 #endif
+	mrc	p15, 1, r0, c15, c0, 0		@ Read L2 ACTLR
+	cmp	r0, #0x118			@ Check if it is already set
+	beq	skip_sec_l2
+	ldr	r0, =0x118			@ Setup L2 ACTLR = 0x118
+	ldr	r12, =OMAP5_MON_L2AUX_CTRL_INDEX
+	dsb
+	smc     #0
+	dsb
+skip_sec_l2:
 	b	cpu_resume			@ Jump to generic resume
 ENDPROC(omap5_cpu_resume)
 #endif
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support
@ 2013-03-01 12:11   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

When the entire MPUSS cluster is powered down in device off state, L2 cache
memory looses it's content and hence while targetting such a state,
l2 cache needs to be flushed to main memory.

Add the necessary low power code support for the same.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/omap-secure.h     |    1 +
 arch/arm/mach-omap2/sleep_omap4plus.S |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index 1739468..a171a5a 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -47,6 +47,7 @@
 #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
 #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
 #define OMAP5_MON_AUX_CTRL_INDEX	0x107
+#define OMAP5_MON_L2AUX_CTRL_INDEX	0x104
 
 #define OMAP5_MON_AMBA_IF_INDEX		0x108
 
diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
index f4874e5..ea318be 100644
--- a/arch/arm/mach-omap2/sleep_omap4plus.S
+++ b/arch/arm/mach-omap2/sleep_omap4plus.S
@@ -386,6 +386,27 @@ skip_secure_l1_clean_op:
 	isb
 	dsb
 
+	bl	omap4_get_sar_ram_base
+	mov	r8, r0
+	mrc	p15, 0, r5, c0, c0, 5		@ Read MPIDR
+	ands	r5, r5, #0x0f
+	ldreq	r0, [r8, #L2X0_SAVE_OFFSET0]	@ Retrieve L2 state
+	ldrne	r0, [r8, #L2X0_SAVE_OFFSET1]
+	cmp	r0, #3
+	bne	do_wfi
+	bl	omap4_get_sar_ram_base
+	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
+	cmp	r9, #0x1			@ Check for HS device
+	bne	skip_secure_l2_clean_op
+	mov	r0, #1				@ Clean secure L2
+	stmfd   r13!, {r4-r12, r14}
+	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
+	DO_SMC
+	ldmfd   r13!, {r4-r12, r14}
+skip_secure_l2_clean_op:
+	mov	r0, #2				@ Flush L2
+	bl	v7_flush_dcache_all
+
 do_wfi:
 	bl	omap_do_wfi
 
@@ -427,6 +448,15 @@ ENTRY(omap5_cpu_resume)
 	dsb
 1:
 #endif
+	mrc	p15, 1, r0, c15, c0, 0		@ Read L2 ACTLR
+	cmp	r0, #0x118			@ Check if it is already set
+	beq	skip_sec_l2
+	ldr	r0, =0x118			@ Setup L2 ACTLR = 0x118
+	ldr	r12, =OMAP5_MON_L2AUX_CTRL_INDEX
+	dsb
+	smc     #0
+	dsb
+skip_sec_l2:
 	b	cpu_resume			@ Jump to generic resume
 ENDPROC(omap5_cpu_resume)
 #endif
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 12/15] ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:11   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

The OMAP5 idle driver can re-use most of OMAP4 CPUidle driver
implementation. Also the next derivative SOCs are going to re-use
the MPUSS so, same driver with minor updates can be re-used.

Prepare the code so that its easier to add CPUidle support for
OMAP5 devices.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c |   30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 9de47a7..df81243 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -1,7 +1,7 @@
 /*
- * OMAP4 CPU idle Routines
+ * OMAP4PLUS CPU idle Routines
  *
- * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011-2013 Texas Instruments, Inc.
  * Santosh Shilimkar <santosh.shilimkar@ti.com>
  * Rajendra Nayak <rnayak@ti.com>
  *
@@ -22,15 +22,16 @@
 #include "pm.h"
 #include "prm.h"
 #include "clockdomain.h"
+#include "soc.h"
 
 /* Machine specific information */
-struct omap4_idle_statedata {
+struct idle_statedata {
 	u32 cpu_state;
 	u32 mpu_logic_state;
 	u32 mpu_state;
 };
 
-static struct omap4_idle_statedata omap4_idle_data[] = {
+static struct idle_statedata omap4_idle_data[] = {
 	{
 		.cpu_state = PWRDM_POWER_ON,
 		.mpu_state = PWRDM_POWER_ON,
@@ -53,11 +54,12 @@ static struct clockdomain *cpu_clkdm[NR_CPUS];
 
 static atomic_t abort_barrier;
 static bool cpu_done[NR_CPUS];
+static struct idle_statedata *state_ptr;
 
 /* Private functions */
 
 /**
- * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions
+ * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
  * @dev: cpuidle device
  * @drv: cpuidle driver
  * @index: the index of state to be entered
@@ -66,7 +68,7 @@ static bool cpu_done[NR_CPUS];
  * specified low power state selected by the governor.
  * Returns the amount of time spent in the low power state.
  */
-static int omap4_enter_idle_simple(struct cpuidle_device *dev,
+static int omap_enter_idle_simple(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv,
 			int index)
 {
@@ -74,11 +76,11 @@ static int omap4_enter_idle_simple(struct cpuidle_device *dev,
 	return index;
 }
 
-static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
+static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv,
 			int index)
 {
-	struct omap4_idle_statedata *cx = &omap4_idle_data[index];
+	struct idle_statedata *cx = state_ptr + index;
 	int cpu_id = smp_processor_id();
 
 	/*
@@ -167,7 +169,7 @@ static void omap_setup_broadcast_timer(void *arg)
 	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
 }
 
-static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
+static DEFINE_PER_CPU(struct cpuidle_device, omap_idle_dev);
 
 static struct cpuidle_driver omap4_idle_driver = {
 	.name				= "omap4_idle",
@@ -179,7 +181,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 			.exit_latency = 2 + 2,
 			.target_residency = 5,
 			.flags = CPUIDLE_FLAG_TIME_VALID,
-			.enter = omap4_enter_idle_simple,
+			.enter = omap_enter_idle_simple,
 			.name = "C1",
 			.desc = "MPUSS ON"
 		},
@@ -188,7 +190,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 			.exit_latency = 328 + 440,
 			.target_residency = 960,
 			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
-			.enter = omap4_enter_idle_coupled,
+			.enter = omap_enter_idle_coupled,
 			.name = "C2",
 			.desc = "MPUSS CSWR",
 		},
@@ -197,7 +199,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 			.exit_latency = 460 + 518,
 			.target_residency = 1100,
 			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
-			.enter = omap4_enter_idle_coupled,
+			.enter = omap_enter_idle_coupled,
 			.name = "C3",
 			.desc = "MPUSS OSWR",
 		},
@@ -219,6 +221,7 @@ int __init omap4_idle_init(void)
 	struct cpuidle_device *dev;
 	unsigned int cpu_id = 0;
 
+	/* Configure the broadcast timer on each cpu */
 	mpu_pd = pwrdm_lookup("mpu_pwrdm");
 	cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
 	cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
@@ -234,11 +237,12 @@ int __init omap4_idle_init(void)
 	on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
 
 	for_each_cpu(cpu_id, cpu_online_mask) {
-		dev = &per_cpu(omap4_idle_dev, cpu_id);
+		dev = &per_cpu(omap_idle_dev, cpu_id);
 		dev->cpu = cpu_id;
 #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
 		dev->coupled_cpus = *cpu_online_mask;
 #endif
+		state_ptr = &omap4_idle_data[0];
 		cpuidle_register_driver(&omap4_idle_driver);
 
 		if (cpuidle_register_device(dev)) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 12/15] ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support
@ 2013-03-01 12:11   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

The OMAP5 idle driver can re-use most of OMAP4 CPUidle driver
implementation. Also the next derivative SOCs are going to re-use
the MPUSS so, same driver with minor updates can be re-used.

Prepare the code so that its easier to add CPUidle support for
OMAP5 devices.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/cpuidle44xx.c |   30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index 9de47a7..df81243 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -1,7 +1,7 @@
 /*
- * OMAP4 CPU idle Routines
+ * OMAP4PLUS CPU idle Routines
  *
- * Copyright (C) 2011 Texas Instruments, Inc.
+ * Copyright (C) 2011-2013 Texas Instruments, Inc.
  * Santosh Shilimkar <santosh.shilimkar@ti.com>
  * Rajendra Nayak <rnayak@ti.com>
  *
@@ -22,15 +22,16 @@
 #include "pm.h"
 #include "prm.h"
 #include "clockdomain.h"
+#include "soc.h"
 
 /* Machine specific information */
-struct omap4_idle_statedata {
+struct idle_statedata {
 	u32 cpu_state;
 	u32 mpu_logic_state;
 	u32 mpu_state;
 };
 
-static struct omap4_idle_statedata omap4_idle_data[] = {
+static struct idle_statedata omap4_idle_data[] = {
 	{
 		.cpu_state = PWRDM_POWER_ON,
 		.mpu_state = PWRDM_POWER_ON,
@@ -53,11 +54,12 @@ static struct clockdomain *cpu_clkdm[NR_CPUS];
 
 static atomic_t abort_barrier;
 static bool cpu_done[NR_CPUS];
+static struct idle_statedata *state_ptr;
 
 /* Private functions */
 
 /**
- * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions
+ * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
  * @dev: cpuidle device
  * @drv: cpuidle driver
  * @index: the index of state to be entered
@@ -66,7 +68,7 @@ static bool cpu_done[NR_CPUS];
  * specified low power state selected by the governor.
  * Returns the amount of time spent in the low power state.
  */
-static int omap4_enter_idle_simple(struct cpuidle_device *dev,
+static int omap_enter_idle_simple(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv,
 			int index)
 {
@@ -74,11 +76,11 @@ static int omap4_enter_idle_simple(struct cpuidle_device *dev,
 	return index;
 }
 
-static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
+static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv,
 			int index)
 {
-	struct omap4_idle_statedata *cx = &omap4_idle_data[index];
+	struct idle_statedata *cx = state_ptr + index;
 	int cpu_id = smp_processor_id();
 
 	/*
@@ -167,7 +169,7 @@ static void omap_setup_broadcast_timer(void *arg)
 	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu);
 }
 
-static DEFINE_PER_CPU(struct cpuidle_device, omap4_idle_dev);
+static DEFINE_PER_CPU(struct cpuidle_device, omap_idle_dev);
 
 static struct cpuidle_driver omap4_idle_driver = {
 	.name				= "omap4_idle",
@@ -179,7 +181,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 			.exit_latency = 2 + 2,
 			.target_residency = 5,
 			.flags = CPUIDLE_FLAG_TIME_VALID,
-			.enter = omap4_enter_idle_simple,
+			.enter = omap_enter_idle_simple,
 			.name = "C1",
 			.desc = "MPUSS ON"
 		},
@@ -188,7 +190,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 			.exit_latency = 328 + 440,
 			.target_residency = 960,
 			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
-			.enter = omap4_enter_idle_coupled,
+			.enter = omap_enter_idle_coupled,
 			.name = "C2",
 			.desc = "MPUSS CSWR",
 		},
@@ -197,7 +199,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 			.exit_latency = 460 + 518,
 			.target_residency = 1100,
 			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
-			.enter = omap4_enter_idle_coupled,
+			.enter = omap_enter_idle_coupled,
 			.name = "C3",
 			.desc = "MPUSS OSWR",
 		},
@@ -219,6 +221,7 @@ int __init omap4_idle_init(void)
 	struct cpuidle_device *dev;
 	unsigned int cpu_id = 0;
 
+	/* Configure the broadcast timer on each cpu */
 	mpu_pd = pwrdm_lookup("mpu_pwrdm");
 	cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm");
 	cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm");
@@ -234,11 +237,12 @@ int __init omap4_idle_init(void)
 	on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
 
 	for_each_cpu(cpu_id, cpu_online_mask) {
-		dev = &per_cpu(omap4_idle_dev, cpu_id);
+		dev = &per_cpu(omap_idle_dev, cpu_id);
 		dev->cpu = cpu_id;
 #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
 		dev->coupled_cpus = *cpu_online_mask;
 #endif
+		state_ptr = &omap4_idle_data[0];
 		cpuidle_register_driver(&omap4_idle_driver);
 
 		if (cpuidle_register_device(dev)) {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 13/15] ARM: OMAP4+: CPUidle: Deprecate use of omap4_mpuss_read_prev_context_state()
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:11   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

Current OMAP4 CPUIdle driver is using omap4_mpuss_read_prev_context_state()
function to check whether the MPU cluster lost context or not. Thanks to
couple CPUIdle, cluster low power entry is almost guaranteed and hence
the programmed cluster check is enough in idle exit path. The API was
more of an optimization for corner cases, where if the cluster low power
entry fails for some reason, the cluster context restore gets skipped.

Moving forward, OMAP CPUidle drivers needs to be moved to drivers/idle/*
once the PRM/CM code gets moved to drivers. This patch also reduces one
dependency with platform code for idle driver movement.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/common.h              |    5 -----
 arch/arm/mach-omap2/cpuidle44xx.c         |    3 ++-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   14 --------------
 3 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 44fcf65..7f9b217 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -242,7 +242,6 @@ 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)
@@ -270,10 +269,6 @@ 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
 
 struct omap_sdrc_params;
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index df81243..23286c1 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -147,7 +147,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 	 * Call idle CPU cluster PM exit notifier chain
 	 * to restore GIC and wakeupgen context.
 	 */
-	if (omap4_mpuss_read_prev_context_state())
+	if ((cx->mpu_state == PWRDM_POWER_RET) &&
+		(cx->mpu_logic_state == PWRDM_POWER_OFF))
 		cpu_cluster_pm_exit();
 
 	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index c1c6b9d..5d32444 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -203,20 +203,6 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
 	}
 }
 
-/**
- * omap4_mpuss_read_prev_context_state:
- * Function returns the MPUSS previous context state
- */
-u32 omap4_mpuss_read_prev_context_state(void)
-{
-	u32 reg;
-
-	reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
-		OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
-	reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
-	return reg;
-}
-
 /*
  * Store the CPU cluster state for L2X0 low power operations.
  */
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 13/15] ARM: OMAP4+: CPUidle: Deprecate use of omap4_mpuss_read_prev_context_state()
@ 2013-03-01 12:11   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

Current OMAP4 CPUIdle driver is using omap4_mpuss_read_prev_context_state()
function to check whether the MPU cluster lost context or not. Thanks to
couple CPUIdle, cluster low power entry is almost guaranteed and hence
the programmed cluster check is enough in idle exit path. The API was
more of an optimization for corner cases, where if the cluster low power
entry fails for some reason, the cluster context restore gets skipped.

Moving forward, OMAP CPUidle drivers needs to be moved to drivers/idle/*
once the PRM/CM code gets moved to drivers. This patch also reduces one
dependency with platform code for idle driver movement.

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/common.h              |    5 -----
 arch/arm/mach-omap2/cpuidle44xx.c         |    3 ++-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c |   14 --------------
 3 files changed, 2 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 44fcf65..7f9b217 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -242,7 +242,6 @@ 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)
@@ -270,10 +269,6 @@ 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
 
 struct omap_sdrc_params;
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index df81243..23286c1 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -147,7 +147,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 	 * Call idle CPU cluster PM exit notifier chain
 	 * to restore GIC and wakeupgen context.
 	 */
-	if (omap4_mpuss_read_prev_context_state())
+	if ((cx->mpu_state == PWRDM_POWER_RET) &&
+		(cx->mpu_logic_state == PWRDM_POWER_OFF))
 		cpu_cluster_pm_exit();
 
 	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index c1c6b9d..5d32444 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -203,20 +203,6 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
 	}
 }
 
-/**
- * omap4_mpuss_read_prev_context_state:
- * Function returns the MPUSS previous context state
- */
-u32 omap4_mpuss_read_prev_context_state(void)
-{
-	u32 reg;
-
-	reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
-		OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
-	reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
-	return reg;
-}
-
 /*
  * Store the CPU cluster state for L2X0 low power operations.
  */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:11   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Santosh Shilimkar

The OMAP5 idle driver can re-use OMAP4 CPUidle driver implementation thanks
to compatible MPUSS design.

Though unlike OMAP4, on OMAP5 devices, MPUSS CSWR (Close Switch Retention)
power states can be achieved with respective power states on CPU0 and CPU1
power domain. This mode was broken on OMAP4 devices because of hardware
limitation. Also there is no CPU low power entry order requirement like
master CPU etc for CSWR C-state, which is icing on the cake. Code makes
use of voting scheme for cluster low power state to support MPUSS CSWR
C-state.

Supported OMAP5 CPUidle C-states:
        C1 - CPU0 ON(WFI) + CPU1 ON(WFI) + MPUSS ON
        C2 - CPU0 CSWR + CPU1 CSWR + MPUSS CSWR
        C3 - CPU0 OFF + CPU1 Force OFF + MPUSS OSWR

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/Kconfig                        |    1 +
 arch/arm/mach-omap2/Makefile                       |    4 +-
 .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  103 +++++++++++++++++++-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    7 +-
 arch/arm/mach-omap2/pm_omap4plus.c                 |    2 +-
 5 files changed, 110 insertions(+), 7 deletions(-)
 rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (70%)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 41b581f..2df91dc 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -82,6 +82,7 @@ config SOC_OMAP5
 	select CPU_V7
 	select HAVE_SMP
 	select COMMON_CLK
+	select ARCH_NEEDS_CPU_IDLE_COUPLED
 
 comment "OMAP Core Type"
 	depends on ARCH_OMAP2
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 7c3c6b6..f6ff88f 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -97,8 +97,10 @@ endif
 endif
 
 ifeq ($(CONFIG_CPU_IDLE),y)
+omap4plus-common-idle			= cpuidle_omap4plus.o
 obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
-obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-idle)
+obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-idle)
 endif
 
 # PRCM
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle_omap4plus.c
similarity index 70%
rename from arch/arm/mach-omap2/cpuidle44xx.c
rename to arch/arm/mach-omap2/cpuidle_omap4plus.c
index 23286c1..8681fa6 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle_omap4plus.c
@@ -29,6 +29,7 @@ struct idle_statedata {
 	u32 cpu_state;
 	u32 mpu_logic_state;
 	u32 mpu_state;
+	u32 mpu_state_vote;
 };
 
 static struct idle_statedata omap4_idle_data[] = {
@@ -49,17 +50,36 @@ static struct idle_statedata omap4_idle_data[] = {
 	},
 };
 
+static struct idle_statedata omap5_idle_data[] = {
+	{
+		.cpu_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_POWER_ON,
+		.mpu_logic_state = PWRDM_POWER_RET,
+	},
+	{
+		.cpu_state = PWRDM_POWER_RET,
+		.mpu_state = PWRDM_POWER_RET,
+		.mpu_logic_state = PWRDM_POWER_RET,
+	},
+	{
+		.cpu_state = PWRDM_POWER_OFF,
+		.mpu_state = PWRDM_POWER_RET,
+		.mpu_logic_state = PWRDM_POWER_OFF,
+	},
+};
+
 static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS];
 static struct clockdomain *cpu_clkdm[NR_CPUS];
 
 static atomic_t abort_barrier;
 static bool cpu_done[NR_CPUS];
 static struct idle_statedata *state_ptr;
+static DEFINE_RAW_SPINLOCK(mpu_lock);
 
 /* Private functions */
 
 /**
- * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
+ * omap_enter_idle_[simple/smp/coupled] - OMAP4PLUS cpuidle entry functions
  * @dev: cpuidle device
  * @drv: cpuidle driver
  * @index: the index of state to be entered
@@ -132,6 +152,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 
 	/* Wakeup CPU1 only if it is not offlined */
 	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
+		/* Restore MPU PD state post idle */
+		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
 		clkdm_wakeup(cpu_clkdm[1]);
 		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
 		clkdm_allow_idle(cpu_clkdm[1]);
@@ -160,6 +182,37 @@ fail:
 	return index;
 }
 
+static int omap_enter_idle_smp(struct cpuidle_device *dev,
+			struct cpuidle_driver *drv,
+			int index)
+{
+	struct idle_statedata *cx = state_ptr + index;
+	int cpu_id = smp_processor_id();
+	unsigned long flag;
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
+
+	raw_spin_lock_irqsave(&mpu_lock, flag);
+	cx->mpu_state_vote++;
+	if (cx->mpu_state_vote == num_online_cpus()) {
+		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
+		omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+	}
+	raw_spin_unlock_irqrestore(&mpu_lock, flag);
+
+	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
+
+	raw_spin_lock_irqsave(&mpu_lock, flag);
+	if (cx->mpu_state_vote == num_online_cpus())
+		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
+	cx->mpu_state_vote--;
+	raw_spin_unlock_irqrestore(&mpu_lock, flag);
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
+
+	return index;
+}
+
 /*
  * For each cpu, setup the broadcast timer because local timers
  * stops for the states above C1.
@@ -209,6 +262,43 @@ static struct cpuidle_driver omap4_idle_driver = {
 	.safe_state_index = 0,
 };
 
+static struct cpuidle_driver omap5_idle_driver = {
+	.name				= "omap5_idle",
+	.owner				= THIS_MODULE,
+	.en_core_tk_irqen		= 1,
+	.states = {
+		{
+			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
+			.exit_latency = 2 + 2,
+			.target_residency = 5,
+			.flags = CPUIDLE_FLAG_TIME_VALID,
+			.enter = omap_enter_idle_simple,
+			.name = "C1",
+			.desc = "MPUSS ON"
+		},
+		{
+			/* C2 - CPU0 CSWR + CPU1 CSWR + MPU CSWR */
+			.exit_latency = 16 + 16,
+			.target_residency = 40,
+			.flags = CPUIDLE_FLAG_TIME_VALID,
+			.enter = omap_enter_idle_smp,
+			.name = "C2",
+			.desc = "MPUSS CSWR",
+		},
+		{
+			/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
+			.exit_latency = 460 + 518,
+			.target_residency = 1100,
+			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
+			.enter = omap_enter_idle_coupled,
+			.name = "C3",
+			.desc = "MPUSS OSWR",
+		},
+	},
+	.state_count = ARRAY_SIZE(omap5_idle_data),
+	.safe_state_index = 0,
+};
+
 /* Public functions */
 
 /**
@@ -220,7 +310,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 int __init omap4_idle_init(void)
 {
 	struct cpuidle_device *dev;
-	unsigned int cpu_id = 0;
+	unsigned cpu_id = 0;
 
 	/* Configure the broadcast timer on each cpu */
 	mpu_pd = pwrdm_lookup("mpu_pwrdm");
@@ -243,8 +333,13 @@ int __init omap4_idle_init(void)
 #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
 		dev->coupled_cpus = *cpu_online_mask;
 #endif
-		state_ptr = &omap4_idle_data[0];
-		cpuidle_register_driver(&omap4_idle_driver);
+		if (cpu_is_omap44xx()) {
+			state_ptr = &omap4_idle_data[0];
+			cpuidle_register_driver(&omap4_idle_driver);
+		} else if (soc_is_omap54xx()) {
+			state_ptr = &omap5_idle_data[0];
+			cpuidle_register_driver(&omap5_idle_driver);
+		}
 
 		if (cpuidle_register_device(dev)) {
 			pr_err("%s: CPUidle register failed\n", __func__);
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 5d32444..0ccb76e 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -87,7 +87,7 @@ extern void omap5_cpu_resume(void);
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
-static u32 cpu_context_offset;
+static u32 cpu_context_offset, cpu_cswr_supported;
 
 static int default_finish_suspend(unsigned long cpu_state)
 {
@@ -265,6 +265,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		save_state = 1;
 		break;
 	case PWRDM_POWER_RET:
+		if (cpu_cswr_supported) {
+			save_state = 0;
+			break;
+		}
 	default:
 		/*
 		 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
@@ -449,6 +453,7 @@ int __init omap4_mpuss_init(void)
 		omap_pm_ops.resume = omap5_cpu_resume;
 		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
 		enable_mercury_retention_mode();
+		cpu_cswr_supported = 1;
 	}
 
 	if (cpu_is_omap446x())
diff --git a/arch/arm/mach-omap2/pm_omap4plus.c b/arch/arm/mach-omap2/pm_omap4plus.c
index 4c37c47..d62edf5 100644
--- a/arch/arm/mach-omap2/pm_omap4plus.c
+++ b/arch/arm/mach-omap2/pm_omap4plus.c
@@ -241,7 +241,7 @@ int __init omap4_pm_init(void)
 	/* Overwrite the default arch_idle() */
 	arm_pm_idle = omap_default_idle;
 
-	if (cpu_is_omap44xx())
+	if (cpu_is_omap44xx() || soc_is_omap54xx())
 		omap4_idle_init();
 
 err2:
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support
@ 2013-03-01 12:11   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

The OMAP5 idle driver can re-use OMAP4 CPUidle driver implementation thanks
to compatible MPUSS design.

Though unlike OMAP4, on OMAP5 devices, MPUSS CSWR (Close Switch Retention)
power states can be achieved with respective power states on CPU0 and CPU1
power domain. This mode was broken on OMAP4 devices because of hardware
limitation. Also there is no CPU low power entry order requirement like
master CPU etc for CSWR C-state, which is icing on the cake. Code makes
use of voting scheme for cluster low power state to support MPUSS CSWR
C-state.

Supported OMAP5 CPUidle C-states:
        C1 - CPU0 ON(WFI) + CPU1 ON(WFI) + MPUSS ON
        C2 - CPU0 CSWR + CPU1 CSWR + MPUSS CSWR
        C3 - CPU0 OFF + CPU1 Force OFF + MPUSS OSWR

Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/Kconfig                        |    1 +
 arch/arm/mach-omap2/Makefile                       |    4 +-
 .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  103 +++++++++++++++++++-
 arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    7 +-
 arch/arm/mach-omap2/pm_omap4plus.c                 |    2 +-
 5 files changed, 110 insertions(+), 7 deletions(-)
 rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (70%)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 41b581f..2df91dc 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -82,6 +82,7 @@ config SOC_OMAP5
 	select CPU_V7
 	select HAVE_SMP
 	select COMMON_CLK
+	select ARCH_NEEDS_CPU_IDLE_COUPLED
 
 comment "OMAP Core Type"
 	depends on ARCH_OMAP2
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 7c3c6b6..f6ff88f 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -97,8 +97,10 @@ endif
 endif
 
 ifeq ($(CONFIG_CPU_IDLE),y)
+omap4plus-common-idle			= cpuidle_omap4plus.o
 obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
-obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
+obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-idle)
+obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-idle)
 endif
 
 # PRCM
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle_omap4plus.c
similarity index 70%
rename from arch/arm/mach-omap2/cpuidle44xx.c
rename to arch/arm/mach-omap2/cpuidle_omap4plus.c
index 23286c1..8681fa6 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle_omap4plus.c
@@ -29,6 +29,7 @@ struct idle_statedata {
 	u32 cpu_state;
 	u32 mpu_logic_state;
 	u32 mpu_state;
+	u32 mpu_state_vote;
 };
 
 static struct idle_statedata omap4_idle_data[] = {
@@ -49,17 +50,36 @@ static struct idle_statedata omap4_idle_data[] = {
 	},
 };
 
+static struct idle_statedata omap5_idle_data[] = {
+	{
+		.cpu_state = PWRDM_POWER_ON,
+		.mpu_state = PWRDM_POWER_ON,
+		.mpu_logic_state = PWRDM_POWER_RET,
+	},
+	{
+		.cpu_state = PWRDM_POWER_RET,
+		.mpu_state = PWRDM_POWER_RET,
+		.mpu_logic_state = PWRDM_POWER_RET,
+	},
+	{
+		.cpu_state = PWRDM_POWER_OFF,
+		.mpu_state = PWRDM_POWER_RET,
+		.mpu_logic_state = PWRDM_POWER_OFF,
+	},
+};
+
 static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS];
 static struct clockdomain *cpu_clkdm[NR_CPUS];
 
 static atomic_t abort_barrier;
 static bool cpu_done[NR_CPUS];
 static struct idle_statedata *state_ptr;
+static DEFINE_RAW_SPINLOCK(mpu_lock);
 
 /* Private functions */
 
 /**
- * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
+ * omap_enter_idle_[simple/smp/coupled] - OMAP4PLUS cpuidle entry functions
  * @dev: cpuidle device
  * @drv: cpuidle driver
  * @index: the index of state to be entered
@@ -132,6 +152,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
 
 	/* Wakeup CPU1 only if it is not offlined */
 	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
+		/* Restore MPU PD state post idle */
+		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
 		clkdm_wakeup(cpu_clkdm[1]);
 		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
 		clkdm_allow_idle(cpu_clkdm[1]);
@@ -160,6 +182,37 @@ fail:
 	return index;
 }
 
+static int omap_enter_idle_smp(struct cpuidle_device *dev,
+			struct cpuidle_driver *drv,
+			int index)
+{
+	struct idle_statedata *cx = state_ptr + index;
+	int cpu_id = smp_processor_id();
+	unsigned long flag;
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
+
+	raw_spin_lock_irqsave(&mpu_lock, flag);
+	cx->mpu_state_vote++;
+	if (cx->mpu_state_vote == num_online_cpus()) {
+		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
+		omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
+	}
+	raw_spin_unlock_irqrestore(&mpu_lock, flag);
+
+	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
+
+	raw_spin_lock_irqsave(&mpu_lock, flag);
+	if (cx->mpu_state_vote == num_online_cpus())
+		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
+	cx->mpu_state_vote--;
+	raw_spin_unlock_irqrestore(&mpu_lock, flag);
+
+	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
+
+	return index;
+}
+
 /*
  * For each cpu, setup the broadcast timer because local timers
  * stops for the states above C1.
@@ -209,6 +262,43 @@ static struct cpuidle_driver omap4_idle_driver = {
 	.safe_state_index = 0,
 };
 
+static struct cpuidle_driver omap5_idle_driver = {
+	.name				= "omap5_idle",
+	.owner				= THIS_MODULE,
+	.en_core_tk_irqen		= 1,
+	.states = {
+		{
+			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
+			.exit_latency = 2 + 2,
+			.target_residency = 5,
+			.flags = CPUIDLE_FLAG_TIME_VALID,
+			.enter = omap_enter_idle_simple,
+			.name = "C1",
+			.desc = "MPUSS ON"
+		},
+		{
+			/* C2 - CPU0 CSWR + CPU1 CSWR + MPU CSWR */
+			.exit_latency = 16 + 16,
+			.target_residency = 40,
+			.flags = CPUIDLE_FLAG_TIME_VALID,
+			.enter = omap_enter_idle_smp,
+			.name = "C2",
+			.desc = "MPUSS CSWR",
+		},
+		{
+			/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
+			.exit_latency = 460 + 518,
+			.target_residency = 1100,
+			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
+			.enter = omap_enter_idle_coupled,
+			.name = "C3",
+			.desc = "MPUSS OSWR",
+		},
+	},
+	.state_count = ARRAY_SIZE(omap5_idle_data),
+	.safe_state_index = 0,
+};
+
 /* Public functions */
 
 /**
@@ -220,7 +310,7 @@ static struct cpuidle_driver omap4_idle_driver = {
 int __init omap4_idle_init(void)
 {
 	struct cpuidle_device *dev;
-	unsigned int cpu_id = 0;
+	unsigned cpu_id = 0;
 
 	/* Configure the broadcast timer on each cpu */
 	mpu_pd = pwrdm_lookup("mpu_pwrdm");
@@ -243,8 +333,13 @@ int __init omap4_idle_init(void)
 #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
 		dev->coupled_cpus = *cpu_online_mask;
 #endif
-		state_ptr = &omap4_idle_data[0];
-		cpuidle_register_driver(&omap4_idle_driver);
+		if (cpu_is_omap44xx()) {
+			state_ptr = &omap4_idle_data[0];
+			cpuidle_register_driver(&omap4_idle_driver);
+		} else if (soc_is_omap54xx()) {
+			state_ptr = &omap5_idle_data[0];
+			cpuidle_register_driver(&omap5_idle_driver);
+		}
 
 		if (cpuidle_register_device(dev)) {
 			pr_err("%s: CPUidle register failed\n", __func__);
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
index 5d32444..0ccb76e 100644
--- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
+++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
@@ -87,7 +87,7 @@ extern void omap5_cpu_resume(void);
 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
 static struct powerdomain *mpuss_pd;
 static void __iomem *sar_base;
-static u32 cpu_context_offset;
+static u32 cpu_context_offset, cpu_cswr_supported;
 
 static int default_finish_suspend(unsigned long cpu_state)
 {
@@ -265,6 +265,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
 		save_state = 1;
 		break;
 	case PWRDM_POWER_RET:
+		if (cpu_cswr_supported) {
+			save_state = 0;
+			break;
+		}
 	default:
 		/*
 		 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
@@ -449,6 +453,7 @@ int __init omap4_mpuss_init(void)
 		omap_pm_ops.resume = omap5_cpu_resume;
 		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
 		enable_mercury_retention_mode();
+		cpu_cswr_supported = 1;
 	}
 
 	if (cpu_is_omap446x())
diff --git a/arch/arm/mach-omap2/pm_omap4plus.c b/arch/arm/mach-omap2/pm_omap4plus.c
index 4c37c47..d62edf5 100644
--- a/arch/arm/mach-omap2/pm_omap4plus.c
+++ b/arch/arm/mach-omap2/pm_omap4plus.c
@@ -241,7 +241,7 @@ int __init omap4_pm_init(void)
 	/* Overwrite the default arch_idle() */
 	arm_pm_idle = omap_default_idle;
 
-	if (cpu_is_omap44xx())
+	if (cpu_is_omap44xx() || soc_is_omap54xx())
 		omap4_idle_init();
 
 err2:
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
  2013-03-01 12:10 ` Santosh Shilimkar
@ 2013-03-01 12:11   ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-omap; +Cc: khilman, linux-arm-kernel, Nishanth Menon, Santosh Shilimkar

From: Nishanth Menon <nm@ti.com>

OMAP5 and OMAP4 have different device instance offsets.

So to handle them properly, use a runtime detected instance offset
Other bit offsets and register offsets remained constant.

Creating a new function is not really worthwhile here as the logic
will be replicated without much benefit.

Signed-off-by: Nishanth Menon <nm@ti.com>
santosh.shilimkar@ti.com: Refreshed patch against 3.8
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/prminst44xx.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
index c12320c..430fb1d 100644
--- a/arch/arm/mach-omap2/prminst44xx.c
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -20,10 +20,12 @@
 #include "common.h"
 #include "prcm-common.h"
 #include "prm44xx.h"
+#include "prm54xx.h"
 #include "prminst44xx.h"
 #include "prm-regbits-44xx.h"
 #include "prcm44xx.h"
 #include "prcm_mpu44xx.h"
+#include "soc.h"
 
 static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS];
 
@@ -165,17 +167,19 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst,
 void omap4_prminst_global_warm_sw_reset(void)
 {
 	u32 v;
+	s16 dev_inst = cpu_is_omap44xx() ? OMAP4430_PRM_DEVICE_INST :
+					   OMAP54XX_PRM_DEVICE_INST;
 
 	v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
-				    OMAP4430_PRM_DEVICE_INST,
+				    dev_inst,
 				    OMAP4_PRM_RSTCTRL_OFFSET);
 	v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
 	omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
-				 OMAP4430_PRM_DEVICE_INST,
+				 dev_inst,
 				 OMAP4_PRM_RSTCTRL_OFFSET);
 
 	/* OCP barrier */
 	v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
-				    OMAP4430_PRM_DEVICE_INST,
+				    dev_inst,
 				    OMAP4_PRM_RSTCTRL_OFFSET);
 }
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 100+ messages in thread

* [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
@ 2013-03-01 12:11   ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

From: Nishanth Menon <nm@ti.com>

OMAP5 and OMAP4 have different device instance offsets.

So to handle them properly, use a runtime detected instance offset
Other bit offsets and register offsets remained constant.

Creating a new function is not really worthwhile here as the logic
will be replicated without much benefit.

Signed-off-by: Nishanth Menon <nm@ti.com>
santosh.shilimkar at ti.com: Refreshed patch against 3.8
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mach-omap2/prminst44xx.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
index c12320c..430fb1d 100644
--- a/arch/arm/mach-omap2/prminst44xx.c
+++ b/arch/arm/mach-omap2/prminst44xx.c
@@ -20,10 +20,12 @@
 #include "common.h"
 #include "prcm-common.h"
 #include "prm44xx.h"
+#include "prm54xx.h"
 #include "prminst44xx.h"
 #include "prm-regbits-44xx.h"
 #include "prcm44xx.h"
 #include "prcm_mpu44xx.h"
+#include "soc.h"
 
 static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS];
 
@@ -165,17 +167,19 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst,
 void omap4_prminst_global_warm_sw_reset(void)
 {
 	u32 v;
+	s16 dev_inst = cpu_is_omap44xx() ? OMAP4430_PRM_DEVICE_INST :
+					   OMAP54XX_PRM_DEVICE_INST;
 
 	v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
-				    OMAP4430_PRM_DEVICE_INST,
+				    dev_inst,
 				    OMAP4_PRM_RSTCTRL_OFFSET);
 	v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
 	omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
-				 OMAP4430_PRM_DEVICE_INST,
+				 dev_inst,
 				 OMAP4_PRM_RSTCTRL_OFFSET);
 
 	/* OCP barrier */
 	v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
-				    OMAP4430_PRM_DEVICE_INST,
+				    dev_inst,
 				    OMAP4_PRM_RSTCTRL_OFFSET);
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 100+ messages in thread

* Re: [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
  2013-03-01 12:11   ` Santosh Shilimkar
@ 2013-03-01 13:04     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 13:04 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

$subject - warm reset

On 17:41-20130301, Santosh Shilimkar wrote:
> From: Nishanth Menon <nm@ti.com>
> 
> OMAP5 and OMAP4 have different device instance offsets.
> 
> So to handle them properly, use a runtime detected instance offset
> Other bit offsets and register offsets remained constant.
> 
> Creating a new function is not really worthwhile here as the logic
> will be replicated without much benefit.
> 
> Signed-off-by: Nishanth Menon <nm@ti.com>
> santosh.shilimkar@ti.com: Refreshed patch against 3.8
[santosh.shilimkar@ti.com: Refreshed patch against 3.8]
?
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/prminst44xx.c |   10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
> index c12320c..430fb1d 100644
> --- a/arch/arm/mach-omap2/prminst44xx.c
> +++ b/arch/arm/mach-omap2/prminst44xx.c
> @@ -20,10 +20,12 @@
>  #include "common.h"
>  #include "prcm-common.h"
>  #include "prm44xx.h"
> +#include "prm54xx.h"
>  #include "prminst44xx.h"
>  #include "prm-regbits-44xx.h"
>  #include "prcm44xx.h"
>  #include "prcm_mpu44xx.h"
> +#include "soc.h"
>  
>  static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS];
>  
> @@ -165,17 +167,19 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst,
>  void omap4_prminst_global_warm_sw_reset(void)
>  {
>  	u32 v;
> +	s16 dev_inst = cpu_is_omap44xx() ? OMAP4430_PRM_DEVICE_INST :
> +					   OMAP54XX_PRM_DEVICE_INST;
>  
>  	v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
> -				    OMAP4430_PRM_DEVICE_INST,
> +				    dev_inst,
>  				    OMAP4_PRM_RSTCTRL_OFFSET);
>  	v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
>  	omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
> -				 OMAP4430_PRM_DEVICE_INST,
> +				 dev_inst,
>  				 OMAP4_PRM_RSTCTRL_OFFSET);
>  
>  	/* OCP barrier */
>  	v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
> -				    OMAP4430_PRM_DEVICE_INST,
> +				    dev_inst,
>  				    OMAP4_PRM_RSTCTRL_OFFSET);
>  }
> -- 
> 1.7.9.5
> 

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
@ 2013-03-01 13:04     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 13:04 UTC (permalink / raw)
  To: linux-arm-kernel

$subject - warm reset

On 17:41-20130301, Santosh Shilimkar wrote:
> From: Nishanth Menon <nm@ti.com>
> 
> OMAP5 and OMAP4 have different device instance offsets.
> 
> So to handle them properly, use a runtime detected instance offset
> Other bit offsets and register offsets remained constant.
> 
> Creating a new function is not really worthwhile here as the logic
> will be replicated without much benefit.
> 
> Signed-off-by: Nishanth Menon <nm@ti.com>
> santosh.shilimkar at ti.com: Refreshed patch against 3.8
[santosh.shilimkar at ti.com: Refreshed patch against 3.8]
?
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/prminst44xx.c |   10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c
> index c12320c..430fb1d 100644
> --- a/arch/arm/mach-omap2/prminst44xx.c
> +++ b/arch/arm/mach-omap2/prminst44xx.c
> @@ -20,10 +20,12 @@
>  #include "common.h"
>  #include "prcm-common.h"
>  #include "prm44xx.h"
> +#include "prm54xx.h"
>  #include "prminst44xx.h"
>  #include "prm-regbits-44xx.h"
>  #include "prcm44xx.h"
>  #include "prcm_mpu44xx.h"
> +#include "soc.h"
>  
>  static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS];
>  
> @@ -165,17 +167,19 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst,
>  void omap4_prminst_global_warm_sw_reset(void)
>  {
>  	u32 v;
> +	s16 dev_inst = cpu_is_omap44xx() ? OMAP4430_PRM_DEVICE_INST :
> +					   OMAP54XX_PRM_DEVICE_INST;
>  
>  	v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
> -				    OMAP4430_PRM_DEVICE_INST,
> +				    dev_inst,
>  				    OMAP4_PRM_RSTCTRL_OFFSET);
>  	v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
>  	omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
> -				 OMAP4430_PRM_DEVICE_INST,
> +				 dev_inst,
>  				 OMAP4_PRM_RSTCTRL_OFFSET);
>  
>  	/* OCP barrier */
>  	v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
> -				    OMAP4430_PRM_DEVICE_INST,
> +				    dev_inst,
>  				    OMAP4_PRM_RSTCTRL_OFFSET);
>  }
> -- 
> 1.7.9.5
> 

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
  2013-03-01 13:04     ` Nishanth Menon
@ 2013-03-01 13:09       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 13:09 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Friday 01 March 2013 06:34 PM, Nishanth Menon wrote:
> $subject - warm reset
> 
ok
> On 17:41-20130301, Santosh Shilimkar wrote:
>> From: Nishanth Menon <nm@ti.com>
>>
>> OMAP5 and OMAP4 have different device instance offsets.
>>
>> So to handle them properly, use a runtime detected instance offset
>> Other bit offsets and register offsets remained constant.
>>
>> Creating a new function is not really worthwhile here as the logic
>> will be replicated without much benefit.
>>
>> Signed-off-by: Nishanth Menon <nm@ti.com>
>> santosh.shilimkar@ti.com: Refreshed patch against 3.8
> [santosh.shilimkar@ti.com: Refreshed patch against 3.8]
> ?
#include "soc.h" :)


^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
@ 2013-03-01 13:09       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 13:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 01 March 2013 06:34 PM, Nishanth Menon wrote:
> $subject - warm reset
> 
ok
> On 17:41-20130301, Santosh Shilimkar wrote:
>> From: Nishanth Menon <nm@ti.com>
>>
>> OMAP5 and OMAP4 have different device instance offsets.
>>
>> So to handle them properly, use a runtime detected instance offset
>> Other bit offsets and register offsets remained constant.
>>
>> Creating a new function is not really worthwhile here as the logic
>> will be replicated without much benefit.
>>
>> Signed-off-by: Nishanth Menon <nm@ti.com>
>> santosh.shilimkar at ti.com: Refreshed patch against 3.8
> [santosh.shilimkar at ti.com: Refreshed patch against 3.8]
> ?
#include "soc.h" :)

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
  2013-03-01 13:09       ` Santosh Shilimkar
@ 2013-03-01 13:13         ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 13:13 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 18:39-20130301, Santosh Shilimkar wrote:
> On Friday 01 March 2013 06:34 PM, Nishanth Menon wrote:
> > $subject - warm reset
> > 
> ok
> > On 17:41-20130301, Santosh Shilimkar wrote:
> >> From: Nishanth Menon <nm@ti.com>
> >>
> >> OMAP5 and OMAP4 have different device instance offsets.
> >>
> >> So to handle them properly, use a runtime detected instance offset
> >> Other bit offsets and register offsets remained constant.
> >>
> >> Creating a new function is not really worthwhile here as the logic
> >> will be replicated without much benefit.
> >>
> >> Signed-off-by: Nishanth Menon <nm@ti.com>
> >> santosh.shilimkar@ti.com: Refreshed patch against 3.8
> > [santosh.shilimkar@ti.com: Refreshed patch against 3.8]
> > ?
> #include "soc.h" :)
I should have been clear: Did you mean to have it in [] to indicate
contribution? A style comment based on Documentation/SubmittingPatches
+360

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
@ 2013-03-01 13:13         ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 13:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 18:39-20130301, Santosh Shilimkar wrote:
> On Friday 01 March 2013 06:34 PM, Nishanth Menon wrote:
> > $subject - warm reset
> > 
> ok
> > On 17:41-20130301, Santosh Shilimkar wrote:
> >> From: Nishanth Menon <nm@ti.com>
> >>
> >> OMAP5 and OMAP4 have different device instance offsets.
> >>
> >> So to handle them properly, use a runtime detected instance offset
> >> Other bit offsets and register offsets remained constant.
> >>
> >> Creating a new function is not really worthwhile here as the logic
> >> will be replicated without much benefit.
> >>
> >> Signed-off-by: Nishanth Menon <nm@ti.com>
> >> santosh.shilimkar at ti.com: Refreshed patch against 3.8
> > [santosh.shilimkar at ti.com: Refreshed patch against 3.8]
> > ?
> #include "soc.h" :)
I should have been clear: Did you mean to have it in [] to indicate
contribution? A style comment based on Documentation/SubmittingPatches
+360

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
  2013-03-01 13:13         ` Nishanth Menon
@ 2013-03-01 13:16           ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 13:16 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Friday 01 March 2013 06:43 PM, Nishanth Menon wrote:
> On 18:39-20130301, Santosh Shilimkar wrote:
>> On Friday 01 March 2013 06:34 PM, Nishanth Menon wrote:
>>> $subject - warm reset
>>>
>> ok
>>> On 17:41-20130301, Santosh Shilimkar wrote:
>>>> From: Nishanth Menon <nm@ti.com>
>>>>
>>>> OMAP5 and OMAP4 have different device instance offsets.
>>>>
>>>> So to handle them properly, use a runtime detected instance offset
>>>> Other bit offsets and register offsets remained constant.
>>>>
>>>> Creating a new function is not really worthwhile here as the logic
>>>> will be replicated without much benefit.
>>>>
>>>> Signed-off-by: Nishanth Menon <nm@ti.com>
>>>> santosh.shilimkar@ti.com: Refreshed patch against 3.8
>>> [santosh.shilimkar@ti.com: Refreshed patch against 3.8]
>>> ?
>> #include "soc.h" :)
> I should have been clear: Did you mean to have it in [] to indicate
> contribution? A style comment based on Documentation/SubmittingPatches
> +360
> 
Ahhh. I mean that to be in []. Just missed to add the bracket.
Regards
santosh


^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset
@ 2013-03-01 13:16           ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-01 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 01 March 2013 06:43 PM, Nishanth Menon wrote:
> On 18:39-20130301, Santosh Shilimkar wrote:
>> On Friday 01 March 2013 06:34 PM, Nishanth Menon wrote:
>>> $subject - warm reset
>>>
>> ok
>>> On 17:41-20130301, Santosh Shilimkar wrote:
>>>> From: Nishanth Menon <nm@ti.com>
>>>>
>>>> OMAP5 and OMAP4 have different device instance offsets.
>>>>
>>>> So to handle them properly, use a runtime detected instance offset
>>>> Other bit offsets and register offsets remained constant.
>>>>
>>>> Creating a new function is not really worthwhile here as the logic
>>>> will be replicated without much benefit.
>>>>
>>>> Signed-off-by: Nishanth Menon <nm@ti.com>
>>>> santosh.shilimkar at ti.com: Refreshed patch against 3.8
>>> [santosh.shilimkar at ti.com: Refreshed patch against 3.8]
>>> ?
>> #include "soc.h" :)
> I should have been clear: Did you mean to have it in [] to indicate
> contribution? A style comment based on Documentation/SubmittingPatches
> +360
> 
Ahhh. I mean that to be in []. Just missed to add the bracket.
Regards
santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 01/15] ARM: OMAP4+: PM: Consolidate MPU subsystem PM code for re-use
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 13:50     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 13:50 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   56 +++++++++++++++++++++++------
>  1 file changed, 45 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index abdd0f6..ee8a1e4 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -71,10 +71,37 @@ struct omap4_cpu_pm_info {
>  	void (*secondary_startup)(void);
>  };
>  
> +struct cpu_pm_ops {
> +	int (*finish_suspend)(unsigned long cpu_state);
> +	void (*resume)(void);
> +	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
> +};
> +
> +extern int omap4_finish_suspend(unsigned long cpu_state);
> +extern void omap4_cpu_resume(void);
> +
>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
>  static void __iomem *sar_base;
>  
> +static int default_finish_suspend(unsigned long cpu_state)
> +{
> +	omap_do_wfi();
> +	return 0;
> +}
> +
> +static void dummy_cpu_resume(void)
> +{}
> +
> +void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
static?
> +{}
> +
> +struct cpu_pm_ops omap_pm_ops = {
> +	.finish_suspend		= default_finish_suspend,
> +	.resume			= dummy_cpu_resume,
> +	.scu_prepare		= dummy_scu_prepare,
> +};
> +
Otherwise,
Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 01/15] ARM: OMAP4+: PM: Consolidate MPU subsystem PM code for re-use
@ 2013-03-01 13:50     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 13:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   56 +++++++++++++++++++++++------
>  1 file changed, 45 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index abdd0f6..ee8a1e4 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -71,10 +71,37 @@ struct omap4_cpu_pm_info {
>  	void (*secondary_startup)(void);
>  };
>  
> +struct cpu_pm_ops {
> +	int (*finish_suspend)(unsigned long cpu_state);
> +	void (*resume)(void);
> +	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
> +};
> +
> +extern int omap4_finish_suspend(unsigned long cpu_state);
> +extern void omap4_cpu_resume(void);
> +
>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
>  static void __iomem *sar_base;
>  
> +static int default_finish_suspend(unsigned long cpu_state)
> +{
> +	omap_do_wfi();
> +	return 0;
> +}
> +
> +static void dummy_cpu_resume(void)
> +{}
> +
> +void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state)
static?
> +{}
> +
> +struct cpu_pm_ops omap_pm_ops = {
> +	.finish_suspend		= default_finish_suspend,
> +	.resume			= dummy_cpu_resume,
> +	.scu_prepare		= dummy_scu_prepare,
> +};
> +
Otherwise,
Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 02/15] ARM: OMAP5: PM: Update CPU context register offset
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 17:34     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 17:34 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> On OMAP5, RM_CPUi_CPUi_CONTEXT offset has changed. Update the code
> so that same code works for OMAP4+ devices.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 02/15] ARM: OMAP5: PM: Update CPU context register offset
@ 2013-03-01 17:34     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> On OMAP5, RM_CPUi_CPUi_CONTEXT offset has changed. Update the code
> so that same code works for OMAP4+ devices.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 17:43     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 17:43 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm_omap4plus.c
> similarity index 74%
> rename from arch/arm/mach-omap2/pm44xx.c
> rename to arch/arm/mach-omap2/pm_omap4plus.c
> index 1d03110..95d2712 100644
> --- a/arch/arm/mach-omap2/pm44xx.c
> +++ b/arch/arm/mach-omap2/pm_omap4plus.c
> @@ -1,7 +1,7 @@
>  /*
> - * OMAP4 Power Management Routines
> + * OMAP4PLUS Power Management Routines
>   *
> - * Copyright (C) 2010-2011 Texas Instruments, Inc.
> + * Copyright (C) 2010-2013 Texas Instruments, Inc.
>   * Rajendra Nayak <rnayak@ti.com>
>   * Santosh Shilimkar <santosh.shilimkar@ti.com>
>   *
> @@ -125,55 +125,77 @@ static void omap_default_idle(void)
>  }
>  
>  /**
> - * omap4_pm_init - Init routine for OMAP4 PM
> + * omap4_init_static_deps - Init static clkdm dependencies on OMAP4
>   *
> - * Initializes all powerdomain and clockdomain target states
> - * and all PRCM settings.
> + * 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.
> + * The L4 wakeup depedency is added to workaround the OCP sync hardware
> + * BUG with 32K synctimer which lead to incorrect timer value read
> + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
> + * are part of L4 wakeup clockdomain.
>   */
> -int __init omap4_pm_init(void)
> +static inline int omap4_init_static_deps(void)
>  {
>  	int ret;
> -	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
> -	struct clockdomain *ducati_clkdm, *l3_2_clkdm;
> +	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
> +	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
>  
> -	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);
> -	if (ret) {
> -		pr_err("Failed to setup powerdomains\n");
> -		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");
> +	l4wkup = clkdm_lookup("l4_wkup_clkdm");
These static dependencies now seems added for OMAP4?
Sounds like a separate patch as it is not exactly what $subject claims.
>  	ducati_clkdm = clkdm_lookup("ducati_clkdm");
> -	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
> -		(!l3_2_clkdm) || (!ducati_clkdm))
> -		goto err2;
> +	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
> +		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
> +		return -EINVAL;
>  
>  	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(mpuss_clkdm, l4wkup);
>  	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");
> +	}
> +
> +	return ret;
> +}
> +
> +/**
> + * omap4_pm_init - Init routine for OMAP4+ devices
> + *
> + * Initializes all powerdomain and clockdomain target states
> + * and all PRCM settings.
> + */
> +int __init omap4_pm_init(void)
could we rename it as omap4plus_pm_init while we are at it?
This will help differentiate at least functions which are omap4 only and
ones which we reuse for omap4plus?
> +{
> +	int ret;
> +
> +	if (omap_rev() == OMAP4430_REV_ES1_0) {
we have ID detection for OMAP5430_REV_ES1_0 in arch/arm/mach-omap2/id.c
However, we do not support PM, so might as well use it to skip init?
> +		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
> +		return -ENODEV;
> +	}
> +
> +	pr_info("Power Management for TI OMAP4PLUS devices.\n");
> +
> +	ret = pwrdm_for_each(pwrdms_setup, NULL);
> +	if (ret) {
> +		pr_err("Failed to setup powerdomains.\n");
>  		goto err2;
>  	}
>  
> +	if (cpu_is_omap44xx()) {
> +		ret = omap4_init_static_deps();
> +		if (ret)
> +			goto err2;
> +	}
> +
>  	ret = omap4_mpuss_init();
>  	if (ret) {
>  		pr_err("Failed to initialise OMAP4 MPUSS\n");
> @@ -186,10 +208,11 @@ int __init omap4_pm_init(void)
>  	omap_pm_suspend = omap4_pm_suspend;
>  #endif
>  
> -	/* Overwrite the default cpu_do_idle() */
> +	/* Overwrite the default arch_idle() */
>  	arm_pm_idle = omap_default_idle;
>  
> -	omap4_idle_init();
> +	if (cpu_is_omap44xx())
> +		omap4_idle_init();
>  
>  err2:
>  	return ret;
> diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> similarity index 100%
> rename from arch/arm/mach-omap2/sleep44xx.S
> rename to arch/arm/mach-omap2/sleep_omap4plus.S
> -- 
> 1.7.9.5

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
@ 2013-03-01 17:43     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 17:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm_omap4plus.c
> similarity index 74%
> rename from arch/arm/mach-omap2/pm44xx.c
> rename to arch/arm/mach-omap2/pm_omap4plus.c
> index 1d03110..95d2712 100644
> --- a/arch/arm/mach-omap2/pm44xx.c
> +++ b/arch/arm/mach-omap2/pm_omap4plus.c
> @@ -1,7 +1,7 @@
>  /*
> - * OMAP4 Power Management Routines
> + * OMAP4PLUS Power Management Routines
>   *
> - * Copyright (C) 2010-2011 Texas Instruments, Inc.
> + * Copyright (C) 2010-2013 Texas Instruments, Inc.
>   * Rajendra Nayak <rnayak@ti.com>
>   * Santosh Shilimkar <santosh.shilimkar@ti.com>
>   *
> @@ -125,55 +125,77 @@ static void omap_default_idle(void)
>  }
>  
>  /**
> - * omap4_pm_init - Init routine for OMAP4 PM
> + * omap4_init_static_deps - Init static clkdm dependencies on OMAP4
>   *
> - * Initializes all powerdomain and clockdomain target states
> - * and all PRCM settings.
> + * 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.
> + * The L4 wakeup depedency is added to workaround the OCP sync hardware
> + * BUG with 32K synctimer which lead to incorrect timer value read
> + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
> + * are part of L4 wakeup clockdomain.
>   */
> -int __init omap4_pm_init(void)
> +static inline int omap4_init_static_deps(void)
>  {
>  	int ret;
> -	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
> -	struct clockdomain *ducati_clkdm, *l3_2_clkdm;
> +	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
> +	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
>  
> -	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);
> -	if (ret) {
> -		pr_err("Failed to setup powerdomains\n");
> -		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");
> +	l4wkup = clkdm_lookup("l4_wkup_clkdm");
These static dependencies now seems added for OMAP4?
Sounds like a separate patch as it is not exactly what $subject claims.
>  	ducati_clkdm = clkdm_lookup("ducati_clkdm");
> -	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
> -		(!l3_2_clkdm) || (!ducati_clkdm))
> -		goto err2;
> +	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
> +		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
> +		return -EINVAL;
>  
>  	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(mpuss_clkdm, l4wkup);
>  	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");
> +	}
> +
> +	return ret;
> +}
> +
> +/**
> + * omap4_pm_init - Init routine for OMAP4+ devices
> + *
> + * Initializes all powerdomain and clockdomain target states
> + * and all PRCM settings.
> + */
> +int __init omap4_pm_init(void)
could we rename it as omap4plus_pm_init while we are at it?
This will help differentiate at least functions which are omap4 only and
ones which we reuse for omap4plus?
> +{
> +	int ret;
> +
> +	if (omap_rev() == OMAP4430_REV_ES1_0) {
we have ID detection for OMAP5430_REV_ES1_0 in arch/arm/mach-omap2/id.c
However, we do not support PM, so might as well use it to skip init?
> +		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
> +		return -ENODEV;
> +	}
> +
> +	pr_info("Power Management for TI OMAP4PLUS devices.\n");
> +
> +	ret = pwrdm_for_each(pwrdms_setup, NULL);
> +	if (ret) {
> +		pr_err("Failed to setup powerdomains.\n");
>  		goto err2;
>  	}
>  
> +	if (cpu_is_omap44xx()) {
> +		ret = omap4_init_static_deps();
> +		if (ret)
> +			goto err2;
> +	}
> +
>  	ret = omap4_mpuss_init();
>  	if (ret) {
>  		pr_err("Failed to initialise OMAP4 MPUSS\n");
> @@ -186,10 +208,11 @@ int __init omap4_pm_init(void)
>  	omap_pm_suspend = omap4_pm_suspend;
>  #endif
>  
> -	/* Overwrite the default cpu_do_idle() */
> +	/* Overwrite the default arch_idle() */
>  	arm_pm_idle = omap_default_idle;
>  
> -	omap4_idle_init();
> +	if (cpu_is_omap44xx())
> +		omap4_idle_init();
>  
>  err2:
>  	return ret;
> diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> similarity index 100%
> rename from arch/arm/mach-omap2/sleep44xx.S
> rename to arch/arm/mach-omap2/sleep_omap4plus.S
> -- 
> 1.7.9.5

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 19:37     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 19:37 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> Enables MPUSS ES2 power management mode using ES2_PM_MODE in
> AMBA_IF_MODE register.
> 
> 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. Broken
> 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode independently.
> 
> This is one time settings thanks to always ON domain.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-secure.h    |    2 ++
>  arch/arm/mach-omap2/omap-wakeupgen.c |   14 ++++++++++++++
>  arch/arm/mach-omap2/omap-wakeupgen.h |    1 +
>  3 files changed, 17 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index 0e72917..82b3c4c 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -42,6 +42,8 @@
>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>  
> +#define OMAP5_MON_AMBA_IF_INDEX		0x108
> +
>  /* Secure PPA(Primary Protected Application) APIs */
>  #define OMAP4_PPA_L2_POR_INDEX		0x23
>  #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
> index 5d3b4f4..a7350dd 100644
> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
> @@ -403,6 +403,7 @@ int __init omap_wakeupgen_init(void)
>  {
>  	int i;
>  	unsigned int boot_cpu = smp_processor_id();
> +	u32 val;
>  
>  	/* Not supported on OMAP4 ES1.0 silicon */
>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
> @@ -444,6 +445,19 @@ int __init omap_wakeupgen_init(void)
>  	for (i = 0; i < max_irqs; i++)
>  		irq_target_cpu[i] = boot_cpu;
>  
> +	/*
> +	 * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
> +	 * 0x0:	ES1 behavior, CPU cores would enter and exit OFF mode together.
> +	 * 0x1:	ES2 behavior, CPU cores are allowed to enter/exit OFF mode
> +	 * independently.
> +	 * This needs to be set one time thanks to always ON domain.
> +	 */
> +	if (soc_is_omap54xx()) {
> +		val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
> +		val |= BIT(5);
BIT(5) is ES2_PM_MODE for es2.0 only - we dont have a OMAP5 revision check atm.
maybe 
> +		omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
> +	}
> +
>  	irq_hotplug_init();
>  	irq_pm_init();
>  
> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
> index b0fd16f..b3c8ecc 100644
> --- a/arch/arm/mach-omap2/omap-wakeupgen.h
> +++ b/arch/arm/mach-omap2/omap-wakeupgen.h
> @@ -27,6 +27,7 @@
>  #define OMAP_WKG_ENB_E_1			0x420
>  #define OMAP_AUX_CORE_BOOT_0			0x800
>  #define OMAP_AUX_CORE_BOOT_1			0x804
> +#define OMAP_AMBA_IF_MODE			0x80c
>  #define OMAP_PTMSYNCREQ_MASK			0xc00
>  #define OMAP_PTMSYNCREQ_EN			0xc04
>  #define OMAP_TIMESTAMPCYCLELO			0xc08

Curious, I see OMAP5_AMBA_IF_MODE_OFFSET in
arch/arm/mach-omap2/omap4-sar-layout.h
if we dont save new modified contents there, Wont restore logic just
reset it back to 0?

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
@ 2013-03-01 19:37     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 19:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> Enables MPUSS ES2 power management mode using ES2_PM_MODE in
> AMBA_IF_MODE register.
> 
> 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. Broken
> 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode independently.
> 
> This is one time settings thanks to always ON domain.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-secure.h    |    2 ++
>  arch/arm/mach-omap2/omap-wakeupgen.c |   14 ++++++++++++++
>  arch/arm/mach-omap2/omap-wakeupgen.h |    1 +
>  3 files changed, 17 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index 0e72917..82b3c4c 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -42,6 +42,8 @@
>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>  
> +#define OMAP5_MON_AMBA_IF_INDEX		0x108
> +
>  /* Secure PPA(Primary Protected Application) APIs */
>  #define OMAP4_PPA_L2_POR_INDEX		0x23
>  #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
> index 5d3b4f4..a7350dd 100644
> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
> @@ -403,6 +403,7 @@ int __init omap_wakeupgen_init(void)
>  {
>  	int i;
>  	unsigned int boot_cpu = smp_processor_id();
> +	u32 val;
>  
>  	/* Not supported on OMAP4 ES1.0 silicon */
>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
> @@ -444,6 +445,19 @@ int __init omap_wakeupgen_init(void)
>  	for (i = 0; i < max_irqs; i++)
>  		irq_target_cpu[i] = boot_cpu;
>  
> +	/*
> +	 * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
> +	 * 0x0:	ES1 behavior, CPU cores would enter and exit OFF mode together.
> +	 * 0x1:	ES2 behavior, CPU cores are allowed to enter/exit OFF mode
> +	 * independently.
> +	 * This needs to be set one time thanks to always ON domain.
> +	 */
> +	if (soc_is_omap54xx()) {
> +		val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
> +		val |= BIT(5);
BIT(5) is ES2_PM_MODE for es2.0 only - we dont have a OMAP5 revision check atm.
maybe 
> +		omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
> +	}
> +
>  	irq_hotplug_init();
>  	irq_pm_init();
>  
> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
> index b0fd16f..b3c8ecc 100644
> --- a/arch/arm/mach-omap2/omap-wakeupgen.h
> +++ b/arch/arm/mach-omap2/omap-wakeupgen.h
> @@ -27,6 +27,7 @@
>  #define OMAP_WKG_ENB_E_1			0x420
>  #define OMAP_AUX_CORE_BOOT_0			0x800
>  #define OMAP_AUX_CORE_BOOT_1			0x804
> +#define OMAP_AMBA_IF_MODE			0x80c
>  #define OMAP_PTMSYNCREQ_MASK			0xc00
>  #define OMAP_PTMSYNCREQ_EN			0xc04
>  #define OMAP_TIMESTAMPCYCLELO			0xc08

Curious, I see OMAP5_AMBA_IF_MODE_OFFSET in
arch/arm/mach-omap2/omap4-sar-layout.h
if we dont save new modified contents there, Wont restore logic just
reset it back to 0?

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 19:42     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 19:42 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> In addition to the standard power-management technique, the OMAP5
> MPU subsystem also employs an SR3-APG (mercury) power management
> technology to reduce leakage.
Mercury fast is employed here - might be good to note that.
> 
> It allows for full logic and memories retention on MPU_C0 and MPU_C1 and
> is controlled by the PRCM_MPU.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index bcd2efb..9fda96b 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -360,6 +360,20 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>  
>  
>  /*
> + * Enable Mercury Fast HG retention mode by default.
> + */
> +static void enable_mercury_retention_mode(void)
> +{
> +	u32 reg;
> +
> +	reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
> +			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
> +	reg |= BIT(24) | BIT(25);
Can we please use macros here?
we are setting BIT(25) - fast ramp-up (Mercury fast) Vs 0 (which would
have been mercury slow)
BIT(24) is mercury enable basically. OMAP4 prm-regbits-44xx.h did not
have these ofcourse, so might be a different bit file or so?
> +	omap4_prcm_mpu_write_inst_reg(reg, OMAP54XX_PRCM_MPU_DEVICE_INST,
> +			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
> +}
> +
> +/*
>   * Initialise OMAP4 MPUSS
>   */
>  int __init omap4_mpuss_init(void)
> @@ -438,6 +452,9 @@ int __init omap4_mpuss_init(void)
>  		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
>  	}
>  
> +	if (soc_is_omap54xx())
> +		enable_mercury_retention_mode();
> +
>  	return 0;
>  }
>  
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
@ 2013-03-01 19:42     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 19:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> In addition to the standard power-management technique, the OMAP5
> MPU subsystem also employs an SR3-APG (mercury) power management
> technology to reduce leakage.
Mercury fast is employed here - might be good to note that.
> 
> It allows for full logic and memories retention on MPU_C0 and MPU_C1 and
> is controlled by the PRCM_MPU.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index bcd2efb..9fda96b 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -360,6 +360,20 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>  
>  
>  /*
> + * Enable Mercury Fast HG retention mode by default.
> + */
> +static void enable_mercury_retention_mode(void)
> +{
> +	u32 reg;
> +
> +	reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
> +			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
> +	reg |= BIT(24) | BIT(25);
Can we please use macros here?
we are setting BIT(25) - fast ramp-up (Mercury fast) Vs 0 (which would
have been mercury slow)
BIT(24) is mercury enable basically. OMAP4 prm-regbits-44xx.h did not
have these ofcourse, so might be a different bit file or so?
> +	omap4_prcm_mpu_write_inst_reg(reg, OMAP54XX_PRCM_MPU_DEVICE_INST,
> +			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
> +}
> +
> +/*
>   * Initialise OMAP4 MPUSS
>   */
>  int __init omap4_mpuss_init(void)
> @@ -438,6 +452,9 @@ int __init omap4_mpuss_init(void)
>  		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
>  	}
>  
> +	if (soc_is_omap54xx())
> +		enable_mercury_retention_mode();
> +
>  	return 0;
>  }
>  
> -- 
> 1.7.9.5
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 20:12     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 20:12 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> With consolidated code, now we can add the .init_late hook for
> OMAP5 to enable power management and mux initialization.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/board-generic.c |    1 +
>  arch/arm/mach-omap2/common.h        |    3 ++-
>  arch/arm/mach-omap2/io.c            |    8 ++++++++
>  3 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
> index 53cb380b..eac4ec5 100644
> --- a/arch/arm/mach-omap2/board-generic.c
> +++ b/arch/arm/mach-omap2/board-generic.c
> @@ -179,6 +179,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
>  	.init_irq	= omap_gic_of_init,
>  	.handle_irq	= gic_handle_irq,
>  	.init_machine	= omap_generic_init,
> +	.init_late	= omap5_init_late,
>  	.timer		= &omap5_timer,
>  	.dt_compat	= omap5_boards_compat,
>  	.restart	= omap44xx_restart,
> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
> index e0f9ea7..44fcf65 100644
> --- a/arch/arm/mach-omap2/common.h
> +++ b/arch/arm/mach-omap2/common.h
> @@ -59,7 +59,7 @@ static inline int omap3_pm_init(void)
>  }
>  #endif
>  
> -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
> +#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5))
>  int omap4_pm_init(void);
>  #else
>  static inline int omap4_pm_init(void)
> @@ -108,6 +108,7 @@ void omap35xx_init_late(void);
>  void omap3630_init_late(void);
>  void am35xx_init_late(void);
>  void ti81xx_init_late(void);
> +void omap5_init_late(void);
>  int omap2_common_pm_late_init(void);
>  
>  #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
> index 2c3fdd6..e6ba596 100644
> --- a/arch/arm/mach-omap2/io.c
> +++ b/arch/arm/mach-omap2/io.c
> @@ -620,6 +620,14 @@ void __init omap5_init_early(void)
>  	omap_cm_base_init();
>  	omap5xxx_check_revision();
>  }
> +
> +void __init omap5_init_late(void)
> +{
> +	omap_mux_late_init();
> +	omap2_common_pm_late_init();
> +	omap4_pm_init();
as part of init sequence, we'd late_initcall *after* module_inits,
implying probes of drivers will be called (for built-in drivers) prior
to PM getting ready.

This basically makes key features like dvfs not available for drivers until
late_init is complete.

We have faced tons of problems in the past with this approach, cant we
improve this? One solution(we used in Android kernel fork) might be to
ensure all core framework initialized before module_init either in
arch_init or subsys_init. I am aware that machine_desc does not provide us
that flexibility - should'nt we rather extend it for the same instead of
having to go through the same pain all over again?

> +	omap2_clk_enable_autoidle_all();
> +}
>  #endif
>  
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization
@ 2013-03-01 20:12     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 20:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> With consolidated code, now we can add the .init_late hook for
> OMAP5 to enable power management and mux initialization.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/board-generic.c |    1 +
>  arch/arm/mach-omap2/common.h        |    3 ++-
>  arch/arm/mach-omap2/io.c            |    8 ++++++++
>  3 files changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
> index 53cb380b..eac4ec5 100644
> --- a/arch/arm/mach-omap2/board-generic.c
> +++ b/arch/arm/mach-omap2/board-generic.c
> @@ -179,6 +179,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
>  	.init_irq	= omap_gic_of_init,
>  	.handle_irq	= gic_handle_irq,
>  	.init_machine	= omap_generic_init,
> +	.init_late	= omap5_init_late,
>  	.timer		= &omap5_timer,
>  	.dt_compat	= omap5_boards_compat,
>  	.restart	= omap44xx_restart,
> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
> index e0f9ea7..44fcf65 100644
> --- a/arch/arm/mach-omap2/common.h
> +++ b/arch/arm/mach-omap2/common.h
> @@ -59,7 +59,7 @@ static inline int omap3_pm_init(void)
>  }
>  #endif
>  
> -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
> +#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5))
>  int omap4_pm_init(void);
>  #else
>  static inline int omap4_pm_init(void)
> @@ -108,6 +108,7 @@ void omap35xx_init_late(void);
>  void omap3630_init_late(void);
>  void am35xx_init_late(void);
>  void ti81xx_init_late(void);
> +void omap5_init_late(void);
>  int omap2_common_pm_late_init(void);
>  
>  #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
> index 2c3fdd6..e6ba596 100644
> --- a/arch/arm/mach-omap2/io.c
> +++ b/arch/arm/mach-omap2/io.c
> @@ -620,6 +620,14 @@ void __init omap5_init_early(void)
>  	omap_cm_base_init();
>  	omap5xxx_check_revision();
>  }
> +
> +void __init omap5_init_late(void)
> +{
> +	omap_mux_late_init();
> +	omap2_common_pm_late_init();
> +	omap4_pm_init();
as part of init sequence, we'd late_initcall *after* module_inits,
implying probes of drivers will be called (for built-in drivers) prior
to PM getting ready.

This basically makes key features like dvfs not available for drivers until
late_init is complete.

We have faced tons of problems in the past with this approach, cant we
improve this? One solution(we used in Android kernel fork) might be to
ensure all core framework initialized before module_init either in
arch_init or subsys_init. I am aware that machine_desc does not provide us
that flexibility - should'nt we rather extend it for the same instead of
having to go through the same pain all over again?

> +	omap2_clk_enable_autoidle_all();
> +}
>  #endif
>  
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 21:36     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 21:36 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> Add power management code to handle the CPU off mode. Separate
> suspend finisher is used for OMAP5(Cortex-A15) because it doesn't
> use SCU power status register and external PL310 L2 cache which makes
> code flow bit different.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   31 +++++++----
>  arch/arm/mach-omap2/omap-secure.h         |    1 +
>  arch/arm/mach-omap2/omap4-sar-layout.h    |    2 +
>  arch/arm/mach-omap2/sleep_omap4plus.S     |   80 +++++++++++++++++++++++++++++
>  4 files changed, 104 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index 9fda96b..275f9a4 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -76,10 +76,12 @@ struct cpu_pm_ops {
>  	int (*finish_suspend)(unsigned long cpu_state);
>  	void (*resume)(void);
>  	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
> +	void (*hotplug_restart)(void);
>  };
>  
>  extern int omap4_finish_suspend(unsigned long cpu_state);
>  extern void omap4_cpu_resume(void);
> +extern int omap5_finish_suspend(unsigned long cpu_state);
>  
>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
> @@ -102,6 +104,7 @@ struct cpu_pm_ops omap_pm_ops = {
>  	.finish_suspend		= default_finish_suspend,
>  	.resume			= dummy_cpu_resume,
>  	.scu_prepare		= dummy_scu_prepare,
> +	.hotplug_restart	= dummy_cpu_resume,
>  };
>  
>  /*
> @@ -334,7 +337,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>  {
>  	unsigned int cpu_state = 0;
> -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
>  
>  	if (omap_rev() == OMAP4430_REV_ES1_0)
>  		return -ENXIO;
> @@ -344,7 +346,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>  
>  	clear_cpu_prev_pwrst(cpu);
>  	set_cpu_next_pwrst(cpu, power_state);
> -	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
> +	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
>  	omap_pm_ops.scu_prepare(cpu, power_state);
>  
>  	/*
> @@ -379,6 +381,7 @@ static void enable_mercury_retention_mode(void)
>  int __init omap4_mpuss_init(void)
>  {
>  	struct omap4_cpu_pm_info *pm_info;
> +	u32 cpu_wakeup_addr = 0;
>  
>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
>  		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
> @@ -388,9 +391,13 @@ int __init omap4_mpuss_init(void)
>  	sar_base = omap4_get_sar_ram_base();
>  
>  	/* Initilaise per CPU PM information */
> +	if (cpu_is_omap44xx())
> +		cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> +	else if (soc_is_omap54xx())
> +		cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
>  	pm_info = &per_cpu(omap4_pm_info, 0x0);
>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
> -	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
>  	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
>  	if (!pm_info->pwrdm) {
> @@ -405,14 +412,14 @@ int __init omap4_mpuss_init(void)
>  	/* Initialise CPU0 power domain state to ON */
>  	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
>  
> +	if (cpu_is_omap44xx())
> +		cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> +	else if (soc_is_omap54xx())
> +		cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
>  	pm_info = &per_cpu(omap4_pm_info, 0x1);
>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
> -	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
> -	if (cpu_is_omap446x())
> -		pm_info->secondary_startup = omap_secondary_startup_4460;
> -	else
> -		pm_info->secondary_startup = omap_secondary_startup;
>  
>  	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
>  	if (!pm_info->pwrdm) {
> @@ -445,15 +452,19 @@ int __init omap4_mpuss_init(void)
>  
>  	if (cpu_is_omap44xx()) {
>  		omap_pm_ops.finish_suspend = omap4_finish_suspend;
> +		omap_pm_ops.hotplug_restart = omap_secondary_startup;
could we handle omap_pm_ops.hotplug_restart = omap_secondary_startup_4460
here as well with the interest of keeping all function inits
in consecutive source location?
>  		omap_pm_ops.resume = omap4_cpu_resume;
>  		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
>  		cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
>  	} else if (soc_is_omap54xx()) {
> +		omap_pm_ops.finish_suspend = omap5_finish_suspend;
> +		omap_pm_ops.hotplug_restart = omap5_secondary_startup;
>  		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
> +		enable_mercury_retention_mode();
>  	}
>  
> -	if (soc_is_omap54xx())
> -		enable_mercury_retention_mode();
> +	if (cpu_is_omap446x())
> +		omap_pm_ops.hotplug_restart = omap_secondary_startup_4460;
>  
>  	return 0;
>  }
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index 82b3c4c..6f4dbee 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -41,6 +41,7 @@
>  #define OMAP4_MON_L2X0_CTRL_INDEX	0x102
>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
> +#define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
>  
>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
>  
> diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
> index 6822d0a..ee8215b 100644
> --- a/arch/arm/mach-omap2/omap4-sar-layout.h
> +++ b/arch/arm/mach-omap2/omap4-sar-layout.h
> @@ -31,6 +31,8 @@
>  /* 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
> +#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
> +#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
>  
>  #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
>  #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> index 88ff83a..3322fc8 100644
> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> @@ -326,6 +326,86 @@ skip_l2en:
>  
>  	b	cpu_resume			@ Jump to generic resume
>  ENDPROC(omap4_cpu_resume)
> +
> +/*
> + * ================================
> + * == OMAP5 CPU suspend finisher ==
> + * ================================
> + *
> + * OMAP5 MPUSS states for the context save:
> + * save_state =
> + *	0 - Nothing lost and no need to save: MPUSS INA/CSWR
> + *	1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR
> + *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
> + *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> + */
> +ENTRY(omap5_finish_suspend)
> +	stmfd	sp!, {r4-r12, lr}
> +	cmp	r0, #0x0
> +	beq	do_wfi				@ No lowpower state, jump to WFI
> +
> +	/*
> +	 * Flush all data from the L1 data cache before disabling
> +	 * SCTLR.C bit.
> +	 */
> +	bl	omap4_get_sar_ram_base
> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
> +	cmp	r9, #0x1			@ Check for HS device
> +	bne	skip_secure_l1_clean_op
> +	mov	r0, #0				@ Clean secure L1
> +	stmfd   r13!, {r4-r12, r14}
> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
> +	DO_SMC
> +	ldmfd   r13!, {r4-r12, r14}
> +skip_secure_l1_clean_op:
> +	bl	v7_flush_dcache_louis
> +
> +	/*
> +	 * Clear the SCTLR.C bit to prevent further data cache
> +	 * allocation. Clearing SCTLR.C would make all the data accesses
> +	 * strongly ordered and would not hit the cache.
> +	 */
> +	mrc	p15, 0, r0, c1, c0, 0
> +	bic	r0, r0, #(1 << 2)		@ Disable the C bit
> +	mcr	p15, 0, r0, c1, c0, 0
> +	isb
> +
> +	/* Clean and Invalidate L1 data cache. */
> +	bl	v7_flush_dcache_louis
Curious question - once we have flushed and invalidated L1 on
skip_secure_l1_clean_op:, we disable SCTLR.C to make all accesses SO,
what is the need to go through clean and invalidate again? is'nt it an
un-necessary cycle consuming NOP? What kind of data are we cleaning out
here?
> +
> +	/*
> +	 * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus
> +	 * preventing the CPU from receiving cache, TLB, or BTB
> +	 * maintenance operations broadcast by other CPUs in the cluster.
> +	 */
> +	mrc	p15, 0, r0, c1, c1, 2		@ Read NSACR data
> +	tst	r0, #(1 << 18)
> +	mrcne	p15, 0, r0, c1, c0, 1
> +	bicne	r0, r0, #(1 << 6)		@ Disable SMP bit
> +	mcrne	p15, 0, r0, c1, c0, 1
> +	isb
> +	dsb
> +
when save_state=3, as per the function comment:
 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
But we dont flush L2 nonsecure OR secure at this point. results wont be
pretty.
If we dont want to deal with "3", then should'nt we add an adequate
handler on entry and remove the code comment claiming we support
it?
is'nt it better to squash in "[PATCH 11/15] ARM: OMAP5: PM: Add L2
memory power down support" here?
> +do_wfi:
> +	bl	omap_do_wfi
> +
> +	/*
> +	 * CPU is here when it failed to enter OFF/DORMANT or
> +	 * no low power state was attempted.
This might need a bit more clarity IMHO. successful WFI (which is
arguably an power state if we consider ARM internal clock gating takes
place), will reach here as well. So would OMAP CPU INA state. The
comment is probably valid for the defined save_states in code comments
for CPU OFF which is un-successful.
> +	 */
> +	mrc	p15, 0, r0, c1, c0, 0
> +	tst	r0, #(1 << 2)			@ Check C bit enabled?
> +	orreq	r0, r0, #(1 << 2)		@ Enable the C bit
> +	mcreq	p15, 0, r0, c1, c0, 0
> +	isb
> +	mrc	p15, 0, r0, c1, c0, 1
> +	tst	r0, #(1 << 6)			@ Check SMP bit enabled?
> +	orreq	r0, r0, #(1 << 6)
> +	mcreq	p15, 0, r0, c1, c0, 1
> +	isb
> +	dsb
> +	ldmfd	sp!, {r4-r12, pc}
> +ENDPROC(omap5_finish_suspend)
>  #endif
>  
>  #ifndef CONFIG_OMAP4_ERRATA_I688

I was curious at this point -> given that we added documentation that
we will be able to go to CPU OFF here, but I did not see an resume
handler registered. Untill I looked down in the series to see:
[PATCH 10/15] ARM: OMAP5: PM: Add MPU Open Switch Retention support
Might be better to squash things  up? or maybe remove the
"documentation"? for example:
patch 10 introduces OSWR support, but part of the required support for
it is suspend code - which is introduced here! There is no point IMHO
introducing code to enter OFF mode in one patch and exit off mode in
another patch - just my 2 cents. if we wanted to organize it as per
feature, then maybe:
patch 9 supports just WFI. patch 10 brings in additional suspend and
resume handler for OSWR, patch 11 for device OFF,
in each stage adding documentation for save_state - so that it is
appropriate and in context.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support
@ 2013-03-01 21:36     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 21:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> Add power management code to handle the CPU off mode. Separate
> suspend finisher is used for OMAP5(Cortex-A15) because it doesn't
> use SCU power status register and external PL310 L2 cache which makes
> code flow bit different.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   31 +++++++----
>  arch/arm/mach-omap2/omap-secure.h         |    1 +
>  arch/arm/mach-omap2/omap4-sar-layout.h    |    2 +
>  arch/arm/mach-omap2/sleep_omap4plus.S     |   80 +++++++++++++++++++++++++++++
>  4 files changed, 104 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index 9fda96b..275f9a4 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -76,10 +76,12 @@ struct cpu_pm_ops {
>  	int (*finish_suspend)(unsigned long cpu_state);
>  	void (*resume)(void);
>  	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
> +	void (*hotplug_restart)(void);
>  };
>  
>  extern int omap4_finish_suspend(unsigned long cpu_state);
>  extern void omap4_cpu_resume(void);
> +extern int omap5_finish_suspend(unsigned long cpu_state);
>  
>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
> @@ -102,6 +104,7 @@ struct cpu_pm_ops omap_pm_ops = {
>  	.finish_suspend		= default_finish_suspend,
>  	.resume			= dummy_cpu_resume,
>  	.scu_prepare		= dummy_scu_prepare,
> +	.hotplug_restart	= dummy_cpu_resume,
>  };
>  
>  /*
> @@ -334,7 +337,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>  {
>  	unsigned int cpu_state = 0;
> -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
>  
>  	if (omap_rev() == OMAP4430_REV_ES1_0)
>  		return -ENXIO;
> @@ -344,7 +346,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>  
>  	clear_cpu_prev_pwrst(cpu);
>  	set_cpu_next_pwrst(cpu, power_state);
> -	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
> +	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
>  	omap_pm_ops.scu_prepare(cpu, power_state);
>  
>  	/*
> @@ -379,6 +381,7 @@ static void enable_mercury_retention_mode(void)
>  int __init omap4_mpuss_init(void)
>  {
>  	struct omap4_cpu_pm_info *pm_info;
> +	u32 cpu_wakeup_addr = 0;
>  
>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
>  		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
> @@ -388,9 +391,13 @@ int __init omap4_mpuss_init(void)
>  	sar_base = omap4_get_sar_ram_base();
>  
>  	/* Initilaise per CPU PM information */
> +	if (cpu_is_omap44xx())
> +		cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> +	else if (soc_is_omap54xx())
> +		cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
>  	pm_info = &per_cpu(omap4_pm_info, 0x0);
>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
> -	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
>  	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
>  	if (!pm_info->pwrdm) {
> @@ -405,14 +412,14 @@ int __init omap4_mpuss_init(void)
>  	/* Initialise CPU0 power domain state to ON */
>  	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
>  
> +	if (cpu_is_omap44xx())
> +		cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> +	else if (soc_is_omap54xx())
> +		cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
>  	pm_info = &per_cpu(omap4_pm_info, 0x1);
>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
> -	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
> -	if (cpu_is_omap446x())
> -		pm_info->secondary_startup = omap_secondary_startup_4460;
> -	else
> -		pm_info->secondary_startup = omap_secondary_startup;
>  
>  	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
>  	if (!pm_info->pwrdm) {
> @@ -445,15 +452,19 @@ int __init omap4_mpuss_init(void)
>  
>  	if (cpu_is_omap44xx()) {
>  		omap_pm_ops.finish_suspend = omap4_finish_suspend;
> +		omap_pm_ops.hotplug_restart = omap_secondary_startup;
could we handle omap_pm_ops.hotplug_restart = omap_secondary_startup_4460
here as well with the interest of keeping all function inits
in consecutive source location?
>  		omap_pm_ops.resume = omap4_cpu_resume;
>  		omap_pm_ops.scu_prepare = scu_pwrst_prepare;
>  		cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
>  	} else if (soc_is_omap54xx()) {
> +		omap_pm_ops.finish_suspend = omap5_finish_suspend;
> +		omap_pm_ops.hotplug_restart = omap5_secondary_startup;
>  		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
> +		enable_mercury_retention_mode();
>  	}
>  
> -	if (soc_is_omap54xx())
> -		enable_mercury_retention_mode();
> +	if (cpu_is_omap446x())
> +		omap_pm_ops.hotplug_restart = omap_secondary_startup_4460;
>  
>  	return 0;
>  }
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index 82b3c4c..6f4dbee 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -41,6 +41,7 @@
>  #define OMAP4_MON_L2X0_CTRL_INDEX	0x102
>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
> +#define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
>  
>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
>  
> diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
> index 6822d0a..ee8215b 100644
> --- a/arch/arm/mach-omap2/omap4-sar-layout.h
> +++ b/arch/arm/mach-omap2/omap4-sar-layout.h
> @@ -31,6 +31,8 @@
>  /* 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
> +#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
> +#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
>  
>  #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
>  #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> index 88ff83a..3322fc8 100644
> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> @@ -326,6 +326,86 @@ skip_l2en:
>  
>  	b	cpu_resume			@ Jump to generic resume
>  ENDPROC(omap4_cpu_resume)
> +
> +/*
> + * ================================
> + * == OMAP5 CPU suspend finisher ==
> + * ================================
> + *
> + * OMAP5 MPUSS states for the context save:
> + * save_state =
> + *	0 - Nothing lost and no need to save: MPUSS INA/CSWR
> + *	1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR
> + *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
> + *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> + */
> +ENTRY(omap5_finish_suspend)
> +	stmfd	sp!, {r4-r12, lr}
> +	cmp	r0, #0x0
> +	beq	do_wfi				@ No lowpower state, jump to WFI
> +
> +	/*
> +	 * Flush all data from the L1 data cache before disabling
> +	 * SCTLR.C bit.
> +	 */
> +	bl	omap4_get_sar_ram_base
> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
> +	cmp	r9, #0x1			@ Check for HS device
> +	bne	skip_secure_l1_clean_op
> +	mov	r0, #0				@ Clean secure L1
> +	stmfd   r13!, {r4-r12, r14}
> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
> +	DO_SMC
> +	ldmfd   r13!, {r4-r12, r14}
> +skip_secure_l1_clean_op:
> +	bl	v7_flush_dcache_louis
> +
> +	/*
> +	 * Clear the SCTLR.C bit to prevent further data cache
> +	 * allocation. Clearing SCTLR.C would make all the data accesses
> +	 * strongly ordered and would not hit the cache.
> +	 */
> +	mrc	p15, 0, r0, c1, c0, 0
> +	bic	r0, r0, #(1 << 2)		@ Disable the C bit
> +	mcr	p15, 0, r0, c1, c0, 0
> +	isb
> +
> +	/* Clean and Invalidate L1 data cache. */
> +	bl	v7_flush_dcache_louis
Curious question - once we have flushed and invalidated L1 on
skip_secure_l1_clean_op:, we disable SCTLR.C to make all accesses SO,
what is the need to go through clean and invalidate again? is'nt it an
un-necessary cycle consuming NOP? What kind of data are we cleaning out
here?
> +
> +	/*
> +	 * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus
> +	 * preventing the CPU from receiving cache, TLB, or BTB
> +	 * maintenance operations broadcast by other CPUs in the cluster.
> +	 */
> +	mrc	p15, 0, r0, c1, c1, 2		@ Read NSACR data
> +	tst	r0, #(1 << 18)
> +	mrcne	p15, 0, r0, c1, c0, 1
> +	bicne	r0, r0, #(1 << 6)		@ Disable SMP bit
> +	mcrne	p15, 0, r0, c1, c0, 1
> +	isb
> +	dsb
> +
when save_state=3, as per the function comment:
 3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
But we dont flush L2 nonsecure OR secure at this point. results wont be
pretty.
If we dont want to deal with "3", then should'nt we add an adequate
handler on entry and remove the code comment claiming we support
it?
is'nt it better to squash in "[PATCH 11/15] ARM: OMAP5: PM: Add L2
memory power down support" here?
> +do_wfi:
> +	bl	omap_do_wfi
> +
> +	/*
> +	 * CPU is here when it failed to enter OFF/DORMANT or
> +	 * no low power state was attempted.
This might need a bit more clarity IMHO. successful WFI (which is
arguably an power state if we consider ARM internal clock gating takes
place), will reach here as well. So would OMAP CPU INA state. The
comment is probably valid for the defined save_states in code comments
for CPU OFF which is un-successful.
> +	 */
> +	mrc	p15, 0, r0, c1, c0, 0
> +	tst	r0, #(1 << 2)			@ Check C bit enabled?
> +	orreq	r0, r0, #(1 << 2)		@ Enable the C bit
> +	mcreq	p15, 0, r0, c1, c0, 0
> +	isb
> +	mrc	p15, 0, r0, c1, c0, 1
> +	tst	r0, #(1 << 6)			@ Check SMP bit enabled?
> +	orreq	r0, r0, #(1 << 6)
> +	mcreq	p15, 0, r0, c1, c0, 1
> +	isb
> +	dsb
> +	ldmfd	sp!, {r4-r12, pc}
> +ENDPROC(omap5_finish_suspend)
>  #endif
>  
>  #ifndef CONFIG_OMAP4_ERRATA_I688

I was curious at this point -> given that we added documentation that
we will be able to go to CPU OFF here, but I did not see an resume
handler registered. Untill I looked down in the series to see:
[PATCH 10/15] ARM: OMAP5: PM: Add MPU Open Switch Retention support
Might be better to squash things  up? or maybe remove the
"documentation"? for example:
patch 10 introduces OSWR support, but part of the required support for
it is suspend code - which is introduced here! There is no point IMHO
introducing code to enter OFF mode in one patch and exit off mode in
another patch - just my 2 cents. if we wanted to organize it as per
feature, then maybe:
patch 9 supports just WFI. patch 10 brings in additional suspend and
resume handler for OSWR, patch 11 for device OFF,
in each stage adding documentation for save_state - so that it is
appropriate and in context.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 09/15] ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 21:53     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 21:53 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> While waking up CPU from off state using clock domain force wakeup, restore
> the CPU power state to ON state before putting CPU clock domain under
> hardware control. Otherwise CPU wakeup might fail. The change is recommended\
the trailing \ was unintentional I suppose.
> for all OMAP4+ devices though the PRCM weakness was observed on OMAP5
> devices first.
> 
> So update the code accordingly.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/cpuidle44xx.c |    1 +
>  arch/arm/mach-omap2/omap-smp.c    |   12 ++++++++++--
>  2 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
> index 944e64a..9de47a7 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
> @@ -131,6 +131,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
>  	/* Wakeup CPU1 only if it is not offlined */
>  	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
>  		clkdm_wakeup(cpu_clkdm[1]);
> +		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
>  		clkdm_allow_idle(cpu_clkdm[1]);
>  	}
>  
> diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
> index 9711ecd..ba63b14 100644
> --- a/arch/arm/mach-omap2/omap-smp.c
> +++ b/arch/arm/mach-omap2/omap-smp.c
> @@ -83,6 +83,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
>  {
>  	static struct clockdomain *cpu1_clkdm;
>  	static bool booted;
> +	static struct powerdomain *cpu1_pwrdm;
>  	void __iomem *base = omap_get_wakeupgen_base();
>  
>  	/*
> @@ -102,8 +103,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
>  	else
>  		__raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0);
>  
> -	if (!cpu1_clkdm)
> +	if (!cpu1_clkdm && !cpu1_pwrdm) {
>  		cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
> +		cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
> +	}
>  
>  	/*
>  	 * The SGI(Software Generated Interrupts) are not wakeup capable
> @@ -116,7 +119,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
>  	 * Section :
>  	 *	4.3.4.2 Power States of CPU0 and CPU1
>  	 */
> -	if (booted) {
> +	if (booted && cpu1_pwrdm && cpu1_clkdm) {
>  		/*
>  		 * GIC distributor control register has changed between
>  		 * CortexA9 r1pX and r2pX. The Control Register secure
> @@ -137,7 +140,12 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
>  			gic_dist_disable();
>  		}
>  
> +		/*
> +		 * Ensure that CPU power state is set to ON to avoid CPU
> +		 * powerdomain transition on wfi
> +		 */
>  		clkdm_wakeup(cpu1_clkdm);
> +		omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);
>  		clkdm_allow_idle(cpu1_clkdm);
>  
>  		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
Otherwise:
Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 09/15] ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method
@ 2013-03-01 21:53     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 21:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> While waking up CPU from off state using clock domain force wakeup, restore
> the CPU power state to ON state before putting CPU clock domain under
> hardware control. Otherwise CPU wakeup might fail. The change is recommended\
the trailing \ was unintentional I suppose.
> for all OMAP4+ devices though the PRCM weakness was observed on OMAP5
> devices first.
> 
> So update the code accordingly.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/cpuidle44xx.c |    1 +
>  arch/arm/mach-omap2/omap-smp.c    |   12 ++++++++++--
>  2 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
> index 944e64a..9de47a7 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
> @@ -131,6 +131,7 @@ static int omap4_enter_idle_coupled(struct cpuidle_device *dev,
>  	/* Wakeup CPU1 only if it is not offlined */
>  	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
>  		clkdm_wakeup(cpu_clkdm[1]);
> +		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
>  		clkdm_allow_idle(cpu_clkdm[1]);
>  	}
>  
> diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
> index 9711ecd..ba63b14 100644
> --- a/arch/arm/mach-omap2/omap-smp.c
> +++ b/arch/arm/mach-omap2/omap-smp.c
> @@ -83,6 +83,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
>  {
>  	static struct clockdomain *cpu1_clkdm;
>  	static bool booted;
> +	static struct powerdomain *cpu1_pwrdm;
>  	void __iomem *base = omap_get_wakeupgen_base();
>  
>  	/*
> @@ -102,8 +103,10 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
>  	else
>  		__raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0);
>  
> -	if (!cpu1_clkdm)
> +	if (!cpu1_clkdm && !cpu1_pwrdm) {
>  		cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
> +		cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
> +	}
>  
>  	/*
>  	 * The SGI(Software Generated Interrupts) are not wakeup capable
> @@ -116,7 +119,7 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
>  	 * Section :
>  	 *	4.3.4.2 Power States of CPU0 and CPU1
>  	 */
> -	if (booted) {
> +	if (booted && cpu1_pwrdm && cpu1_clkdm) {
>  		/*
>  		 * GIC distributor control register has changed between
>  		 * CortexA9 r1pX and r2pX. The Control Register secure
> @@ -137,7 +140,12 @@ static int __cpuinit omap4_boot_secondary(unsigned int cpu, struct task_struct *
>  			gic_dist_disable();
>  		}
>  
> +		/*
> +		 * Ensure that CPU power state is set to ON to avoid CPU
> +		 * powerdomain transition on wfi
> +		 */
>  		clkdm_wakeup(cpu1_clkdm);
> +		omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON);
>  		clkdm_allow_idle(cpu1_clkdm);
>  
>  		if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
Otherwise:
Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 10/15] ARM: OMAP5: PM: Add MPU Open Switch Retention support
  2013-03-01 12:10   ` Santosh Shilimkar
@ 2013-03-01 22:05     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 22:05 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> In MPUSS OSWR(Open Switch Retention), entire CPU cluster is powered down
> except L2 cache memory. For MPUSS OSWR state, both CPU's needs to be in
> power off state.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |    2 ++
>  arch/arm/mach-omap2/omap-secure.h         |    5 +++++
>  arch/arm/mach-omap2/omap-wakeupgen.c      |   11 ++++++-----
>  arch/arm/mach-omap2/sleep_omap4plus.S     |   23 +++++++++++++++++++++++
>  4 files changed, 36 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index 275f9a4..c1c6b9d 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -82,6 +82,7 @@ struct cpu_pm_ops {
>  extern int omap4_finish_suspend(unsigned long cpu_state);
>  extern void omap4_cpu_resume(void);
>  extern int omap5_finish_suspend(unsigned long cpu_state);
> +extern void omap5_cpu_resume(void);
>  
>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
> @@ -459,6 +460,7 @@ int __init omap4_mpuss_init(void)
>  	} else if (soc_is_omap54xx()) {
>  		omap_pm_ops.finish_suspend = omap5_finish_suspend;
>  		omap_pm_ops.hotplug_restart = omap5_secondary_startup;
> +		omap_pm_ops.resume = omap5_cpu_resume;
>  		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
>  		enable_mercury_retention_mode();
>  	}
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index 6f4dbee..1739468 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -34,6 +34,10 @@
>  #define OMAP4_HAL_SAVEHW_INDEX		0x1b
>  #define OMAP4_HAL_SAVEALL_INDEX		0x1c
>  #define OMAP4_HAL_SAVEGIC_INDEX		0x1d
> +#define OMAP5_HAL_SAVESECURERAM_INDEX	0x1c
> +#define OMAP5_HAL_SAVEHW_INDEX		0x1d
> +#define OMAP5_HAL_SAVEALL_INDEX		0x1e
> +#define OMAP5_HAL_SAVEGIC_INDEX		0x1f
>  
>  /* Secure Monitor mode APIs */
>  #define OMAP4_MON_SCU_PWR_INDEX		0x108
> @@ -42,6 +46,7 @@
>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>  #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
> +#define OMAP5_MON_AUX_CTRL_INDEX	0x107
>  
>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
>  
> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
> index a7350dd..f57b0b8 100644
> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
> @@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(wakeupgen_lock);
>  static unsigned int irq_target_cpu[MAX_IRQS];
>  static unsigned int irq_banks = MAX_NR_REG_BANKS;
>  static unsigned int max_irqs = MAX_IRQS;
> -static unsigned int omap_secure_apis;
> +static unsigned int omap_secure_apis, secure_api_index;
>  
>  /*
>   * Static helper functions.
> @@ -315,7 +315,7 @@ static void irq_sar_clear(void)
>  static void irq_save_secure_context(void)
>  {
>  	u32 ret;
> -	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
> +	ret = omap_secure_dispatcher(secure_api_index,
>  				FLAG_START_CRITICAL,
>  				0, 0, 0, 0, 0);
>  	if (ret != API_HAL_RET_VALUE_OK)
> @@ -377,9 +377,7 @@ static struct notifier_block irq_notifier_block = {
>  
>  static void __init irq_pm_init(void)
>  {
> -	/* FIXME: Remove this when MPU OSWR support is added */
> -	if (!soc_is_omap54xx())
> -		cpu_pm_register_notifier(&irq_notifier_block);
> +	cpu_pm_register_notifier(&irq_notifier_block);
>  }
>  #else
>  static void __init irq_pm_init(void)
> @@ -420,6 +418,9 @@ int __init omap_wakeupgen_init(void)
>  		irq_banks = OMAP4_NR_BANKS;
>  		max_irqs = OMAP4_NR_IRQS;
>  		omap_secure_apis = 1;
> +		secure_api_index = OMAP4_HAL_SAVEGIC_INDEX;
> +	} else if (soc_is_omap54xx()) {
> +		secure_api_index = OMAP5_HAL_SAVEGIC_INDEX;
>  	}
>  
>  	/* Clear all IRQ bitmasks at wakeupGen level */
> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> index 3322fc8..f4874e5 100644
> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> @@ -406,6 +406,29 @@ do_wfi:
>  	dsb
>  	ldmfd	sp!, {r4-r12, pc}
>  ENDPROC(omap5_finish_suspend)
> +
> +ENTRY(omap5_cpu_resume)
> +#ifdef CONFIG_ARM_ERRATA_761171
> +	/*
> +	 * Work around for errata for 761171. Streaming write that will not
> +	 * allocate in L2 could lead to data corruption.
> +	 */
> +	mrc	p15, 0, r0, c0, c0, 0		@ read main ID register
> +	and	r5, r0, #0x00f00000		@ variant
> +	and	r6, r0, #0x0000000f		@ revision
> +	orr	r6, r6, r5, lsr #20-4		@ combine variant and revision
> +	cmp	r6, #0x03			@ Present before r0p3
> +	bgt	1f
> +	mrc	p15, 0, r0, c1, c0, 1		@ Read Auxctrl
> +	orr	r0, r0, #0x3 << 27		@ bits[28:27]-L1_mode3_threshold
> +	ldr	r12, =OMAP5_MON_AUX_CTRL_INDEX
> +	dsb
> +	smc	#0
> +	dsb
> +1:
> +#endif
> +	b	cpu_resume			@ Jump to generic resume
> +ENDPROC(omap5_cpu_resume)
>  #endif
>  
Other than the previously raised concern,
Acked-by: Nishanth Menon <nm@ti.com>

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 10/15] ARM: OMAP5: PM: Add MPU Open Switch Retention support
@ 2013-03-01 22:05     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 22:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:40-20130301, Santosh Shilimkar wrote:
> In MPUSS OSWR(Open Switch Retention), entire CPU cluster is powered down
> except L2 cache memory. For MPUSS OSWR state, both CPU's needs to be in
> power off state.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |    2 ++
>  arch/arm/mach-omap2/omap-secure.h         |    5 +++++
>  arch/arm/mach-omap2/omap-wakeupgen.c      |   11 ++++++-----
>  arch/arm/mach-omap2/sleep_omap4plus.S     |   23 +++++++++++++++++++++++
>  4 files changed, 36 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index 275f9a4..c1c6b9d 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -82,6 +82,7 @@ struct cpu_pm_ops {
>  extern int omap4_finish_suspend(unsigned long cpu_state);
>  extern void omap4_cpu_resume(void);
>  extern int omap5_finish_suspend(unsigned long cpu_state);
> +extern void omap5_cpu_resume(void);
>  
>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
> @@ -459,6 +460,7 @@ int __init omap4_mpuss_init(void)
>  	} else if (soc_is_omap54xx()) {
>  		omap_pm_ops.finish_suspend = omap5_finish_suspend;
>  		omap_pm_ops.hotplug_restart = omap5_secondary_startup;
> +		omap_pm_ops.resume = omap5_cpu_resume;
>  		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
>  		enable_mercury_retention_mode();
>  	}
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index 6f4dbee..1739468 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -34,6 +34,10 @@
>  #define OMAP4_HAL_SAVEHW_INDEX		0x1b
>  #define OMAP4_HAL_SAVEALL_INDEX		0x1c
>  #define OMAP4_HAL_SAVEGIC_INDEX		0x1d
> +#define OMAP5_HAL_SAVESECURERAM_INDEX	0x1c
> +#define OMAP5_HAL_SAVEHW_INDEX		0x1d
> +#define OMAP5_HAL_SAVEALL_INDEX		0x1e
> +#define OMAP5_HAL_SAVEGIC_INDEX		0x1f
>  
>  /* Secure Monitor mode APIs */
>  #define OMAP4_MON_SCU_PWR_INDEX		0x108
> @@ -42,6 +46,7 @@
>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>  #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
> +#define OMAP5_MON_AUX_CTRL_INDEX	0x107
>  
>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
>  
> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
> index a7350dd..f57b0b8 100644
> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
> @@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(wakeupgen_lock);
>  static unsigned int irq_target_cpu[MAX_IRQS];
>  static unsigned int irq_banks = MAX_NR_REG_BANKS;
>  static unsigned int max_irqs = MAX_IRQS;
> -static unsigned int omap_secure_apis;
> +static unsigned int omap_secure_apis, secure_api_index;
>  
>  /*
>   * Static helper functions.
> @@ -315,7 +315,7 @@ static void irq_sar_clear(void)
>  static void irq_save_secure_context(void)
>  {
>  	u32 ret;
> -	ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
> +	ret = omap_secure_dispatcher(secure_api_index,
>  				FLAG_START_CRITICAL,
>  				0, 0, 0, 0, 0);
>  	if (ret != API_HAL_RET_VALUE_OK)
> @@ -377,9 +377,7 @@ static struct notifier_block irq_notifier_block = {
>  
>  static void __init irq_pm_init(void)
>  {
> -	/* FIXME: Remove this when MPU OSWR support is added */
> -	if (!soc_is_omap54xx())
> -		cpu_pm_register_notifier(&irq_notifier_block);
> +	cpu_pm_register_notifier(&irq_notifier_block);
>  }
>  #else
>  static void __init irq_pm_init(void)
> @@ -420,6 +418,9 @@ int __init omap_wakeupgen_init(void)
>  		irq_banks = OMAP4_NR_BANKS;
>  		max_irqs = OMAP4_NR_IRQS;
>  		omap_secure_apis = 1;
> +		secure_api_index = OMAP4_HAL_SAVEGIC_INDEX;
> +	} else if (soc_is_omap54xx()) {
> +		secure_api_index = OMAP5_HAL_SAVEGIC_INDEX;
>  	}
>  
>  	/* Clear all IRQ bitmasks at wakeupGen level */
> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> index 3322fc8..f4874e5 100644
> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> @@ -406,6 +406,29 @@ do_wfi:
>  	dsb
>  	ldmfd	sp!, {r4-r12, pc}
>  ENDPROC(omap5_finish_suspend)
> +
> +ENTRY(omap5_cpu_resume)
> +#ifdef CONFIG_ARM_ERRATA_761171
> +	/*
> +	 * Work around for errata for 761171. Streaming write that will not
> +	 * allocate in L2 could lead to data corruption.
> +	 */
> +	mrc	p15, 0, r0, c0, c0, 0		@ read main ID register
> +	and	r5, r0, #0x00f00000		@ variant
> +	and	r6, r0, #0x0000000f		@ revision
> +	orr	r6, r6, r5, lsr #20-4		@ combine variant and revision
> +	cmp	r6, #0x03			@ Present before r0p3
> +	bgt	1f
> +	mrc	p15, 0, r0, c1, c0, 1		@ Read Auxctrl
> +	orr	r0, r0, #0x3 << 27		@ bits[28:27]-L1_mode3_threshold
> +	ldr	r12, =OMAP5_MON_AUX_CTRL_INDEX
> +	dsb
> +	smc	#0
> +	dsb
> +1:
> +#endif
> +	b	cpu_resume			@ Jump to generic resume
> +ENDPROC(omap5_cpu_resume)
>  #endif
>  
Other than the previously raised concern,
Acked-by: Nishanth Menon <nm@ti.com>

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support
  2013-03-01 12:11   ` Santosh Shilimkar
@ 2013-03-01 23:43     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 23:43 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:41-20130301, Santosh Shilimkar wrote:
> When the entire MPUSS cluster is powered down in device off state, L2 cache
> memory looses it's content and hence while targetting such a state,
> l2 cache needs to be flushed to main memory.
> 
> Add the necessary low power code support for the same.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-secure.h     |    1 +
>  arch/arm/mach-omap2/sleep_omap4plus.S |   30 ++++++++++++++++++++++++++++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index 1739468..a171a5a 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -47,6 +47,7 @@
>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>  #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
>  #define OMAP5_MON_AUX_CTRL_INDEX	0x107
> +#define OMAP5_MON_L2AUX_CTRL_INDEX	0x104
>  
>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
>  
> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> index f4874e5..ea318be 100644
> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> @@ -386,6 +386,27 @@ skip_secure_l1_clean_op:
>  	isb
>  	dsb
>  
> +	bl	omap4_get_sar_ram_base
> +	mov	r8, r0
> +	mrc	p15, 0, r5, c0, c0, 5		@ Read MPIDR
> +	ands	r5, r5, #0x0f
> +	ldreq	r0, [r8, #L2X0_SAVE_OFFSET0]	@ Retrieve L2 state
> +	ldrne	r0, [r8, #L2X0_SAVE_OFFSET1]
> +	cmp	r0, #3
umm, we store l2x0_pwrst_prepare(cpu, save_state);
which in turn stores into L2X0_SAVE_OFFSET - I am with you so far
save_state in omap4_enter_lowpower is:
PWRDM_POWER_INACTIVE: 0
PWRDM_POWER_OFF: 1
or 2 in the case of OSWR
what is 3? ref:
https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-mpuss-lowpower.c#L298
> +	bne	do_wfi
> +	bl	omap4_get_sar_ram_base
> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
> +	cmp	r9, #0x1			@ Check for HS device
my 2c:
off topic: somewhere down the line, I think we need to clear up these
into macros so that as in this case, omap4_mpuss_init populated value
should be the same as here with usage of same macro without reviewer
needing to track down where it was set with what.

> +	bne	skip_secure_l2_clean_op
> +	mov	r0, #1				@ Clean secure L2
> +	stmfd   r13!, {r4-r12, r14}
> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
> +	DO_SMC
> +	ldmfd   r13!, {r4-r12, r14}
> +skip_secure_l2_clean_op:
> +	mov	r0, #2				@ Flush L2
v7_flush_dcache_all does not take parameters, right?
> +	bl	v7_flush_dcache_all
> +
>  do_wfi:
>  	bl	omap_do_wfi
>  
> @@ -427,6 +448,15 @@ ENTRY(omap5_cpu_resume)
>  	dsb
>  1:
>  #endif
> +	mrc	p15, 1, r0, c15, c0, 0		@ Read L2 ACTLR
> +	cmp	r0, #0x118			@ Check if it is already set

> 	beq	skip_sec_l2
> +	ldr	r0, =0x118			@ Setup L2 ACTLR = 0x118
> +	ldr	r12, =OMAP5_MON_L2AUX_CTRL_INDEX
I hope I am looking at the right place:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0438g/BABIAICD.html
bit 3: Disable clean/evict push to external
bit 4: Disable WriteUnique and WriteLineUnique transactions from master
bit 8: Disable DVM/CMO message broadcast

Is'nt it better to configure on boot, save it into SAR memory and restore it
from SAR using monitor call? I mean it is possible that we start boot
with L2 ACTLR != 0x118 and then hit off and come out of OFF mode with
0x118.
One generally wants the system to be same before and after OFF/LP mode.
else, one tends to track bug such as
"At boot I see this bug, but after a while I dont see (cpuidle kicked in)"
- harder one to track down
or
"At boot I see this bug, but after a first suspend resume, I dont see (OFF kicked in)"
- easier one to track.
or vice versa and other combinations.. :(

> +	dsb
> +	smc     #0
DO_SMC ?
> +	dsb
> +skip_sec_l2:
>  	b	cpu_resume			@ Jump to generic resume

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support
@ 2013-03-01 23:43     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 23:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:41-20130301, Santosh Shilimkar wrote:
> When the entire MPUSS cluster is powered down in device off state, L2 cache
> memory looses it's content and hence while targetting such a state,
> l2 cache needs to be flushed to main memory.
> 
> Add the necessary low power code support for the same.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/omap-secure.h     |    1 +
>  arch/arm/mach-omap2/sleep_omap4plus.S |   30 ++++++++++++++++++++++++++++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index 1739468..a171a5a 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -47,6 +47,7 @@
>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>  #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
>  #define OMAP5_MON_AUX_CTRL_INDEX	0x107
> +#define OMAP5_MON_L2AUX_CTRL_INDEX	0x104
>  
>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
>  
> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> index f4874e5..ea318be 100644
> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> @@ -386,6 +386,27 @@ skip_secure_l1_clean_op:
>  	isb
>  	dsb
>  
> +	bl	omap4_get_sar_ram_base
> +	mov	r8, r0
> +	mrc	p15, 0, r5, c0, c0, 5		@ Read MPIDR
> +	ands	r5, r5, #0x0f
> +	ldreq	r0, [r8, #L2X0_SAVE_OFFSET0]	@ Retrieve L2 state
> +	ldrne	r0, [r8, #L2X0_SAVE_OFFSET1]
> +	cmp	r0, #3
umm, we store l2x0_pwrst_prepare(cpu, save_state);
which in turn stores into L2X0_SAVE_OFFSET - I am with you so far
save_state in omap4_enter_lowpower is:
PWRDM_POWER_INACTIVE: 0
PWRDM_POWER_OFF: 1
or 2 in the case of OSWR
what is 3? ref:
https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-mpuss-lowpower.c#L298
> +	bne	do_wfi
> +	bl	omap4_get_sar_ram_base
> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
> +	cmp	r9, #0x1			@ Check for HS device
my 2c:
off topic: somewhere down the line, I think we need to clear up these
into macros so that as in this case, omap4_mpuss_init populated value
should be the same as here with usage of same macro without reviewer
needing to track down where it was set with what.

> +	bne	skip_secure_l2_clean_op
> +	mov	r0, #1				@ Clean secure L2
> +	stmfd   r13!, {r4-r12, r14}
> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
> +	DO_SMC
> +	ldmfd   r13!, {r4-r12, r14}
> +skip_secure_l2_clean_op:
> +	mov	r0, #2				@ Flush L2
v7_flush_dcache_all does not take parameters, right?
> +	bl	v7_flush_dcache_all
> +
>  do_wfi:
>  	bl	omap_do_wfi
>  
> @@ -427,6 +448,15 @@ ENTRY(omap5_cpu_resume)
>  	dsb
>  1:
>  #endif
> +	mrc	p15, 1, r0, c15, c0, 0		@ Read L2 ACTLR
> +	cmp	r0, #0x118			@ Check if it is already set

> 	beq	skip_sec_l2
> +	ldr	r0, =0x118			@ Setup L2 ACTLR = 0x118
> +	ldr	r12, =OMAP5_MON_L2AUX_CTRL_INDEX
I hope I am looking at the right place:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0438g/BABIAICD.html
bit 3: Disable clean/evict push to external
bit 4: Disable WriteUnique and WriteLineUnique transactions from master
bit 8: Disable DVM/CMO message broadcast

Is'nt it better to configure on boot, save it into SAR memory and restore it
from SAR using monitor call? I mean it is possible that we start boot
with L2 ACTLR != 0x118 and then hit off and come out of OFF mode with
0x118.
One generally wants the system to be same before and after OFF/LP mode.
else, one tends to track bug such as
"At boot I see this bug, but after a while I dont see (cpuidle kicked in)"
- harder one to track down
or
"At boot I see this bug, but after a first suspend resume, I dont see (OFF kicked in)"
- easier one to track.
or vice versa and other combinations.. :(

> +	dsb
> +	smc     #0
DO_SMC ?
> +	dsb
> +skip_sec_l2:
>  	b	cpu_resume			@ Jump to generic resume

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 12/15] ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support
  2013-03-01 12:11   ` Santosh Shilimkar
@ 2013-03-01 23:56     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 23:56 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:41-20130301, Santosh Shilimkar wrote:
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
> index 9de47a7..df81243 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
[...]
> @@ -234,11 +237,12 @@ int __init omap4_idle_init(void)
>  	on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
>  
>  	for_each_cpu(cpu_id, cpu_online_mask) {
> -		dev = &per_cpu(omap4_idle_dev, cpu_id);
> +		dev = &per_cpu(omap_idle_dev, cpu_id);
>  		dev->cpu = cpu_id;
>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
>  		dev->coupled_cpus = *cpu_online_mask;
>  #endif
> +		state_ptr = &omap4_idle_data[0];
minor:
why initialize it twice (cpu0 and cpu1) to the same pointer in each of
the for_each_cpu loop? you could move it maybe just before the loop?
>  		cpuidle_register_driver(&omap4_idle_driver);
>  
>  		if (cpuidle_register_device(dev)) {
Otherwise,
Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 12/15] ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support
@ 2013-03-01 23:56     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-01 23:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:41-20130301, Santosh Shilimkar wrote:
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
> index 9de47a7..df81243 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
[...]
> @@ -234,11 +237,12 @@ int __init omap4_idle_init(void)
>  	on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
>  
>  	for_each_cpu(cpu_id, cpu_online_mask) {
> -		dev = &per_cpu(omap4_idle_dev, cpu_id);
> +		dev = &per_cpu(omap_idle_dev, cpu_id);
>  		dev->cpu = cpu_id;
>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
>  		dev->coupled_cpus = *cpu_online_mask;
>  #endif
> +		state_ptr = &omap4_idle_data[0];
minor:
why initialize it twice (cpu0 and cpu1) to the same pointer in each of
the for_each_cpu loop? you could move it maybe just before the loop?
>  		cpuidle_register_driver(&omap4_idle_driver);
>  
>  		if (cpuidle_register_device(dev)) {
Otherwise,
Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 13/15] ARM: OMAP4+: CPUidle: Deprecate use of omap4_mpuss_read_prev_context_state()
  2013-03-01 12:11   ` Santosh Shilimkar
@ 2013-03-02  0:03     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-02  0:03 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:41-20130301, Santosh Shilimkar wrote:
> Current OMAP4 CPUIdle driver is using omap4_mpuss_read_prev_context_state()
> function to check whether the MPU cluster lost context or not. Thanks to
> couple CPUIdle, cluster low power entry is almost guaranteed and hence
> the programmed cluster check is enough in idle exit path. The API was
> more of an optimization for corner cases, where if the cluster low power
> entry fails for some reason, the cluster context restore gets skipped.
> 
> Moving forward, OMAP CPUidle drivers needs to be moved to drivers/idle/*
> once the PRM/CM code gets moved to drivers. This patch also reduces one
> dependency with platform code for idle driver movement.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/common.h              |    5 -----
>  arch/arm/mach-omap2/cpuidle44xx.c         |    3 ++-
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   14 --------------
>  3 files changed, 2 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
> index 44fcf65..7f9b217 100644
> --- a/arch/arm/mach-omap2/common.h
> +++ b/arch/arm/mach-omap2/common.h
> @@ -242,7 +242,6 @@ 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)
> @@ -270,10 +269,6 @@ 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
>  
>  struct omap_sdrc_params;
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
> index df81243..23286c1 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
> @@ -147,7 +147,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
>  	 * Call idle CPU cluster PM exit notifier chain
>  	 * to restore GIC and wakeupgen context.
>  	 */
> -	if (omap4_mpuss_read_prev_context_state())
> +	if ((cx->mpu_state == PWRDM_POWER_RET) &&
> +		(cx->mpu_logic_state == PWRDM_POWER_OFF))
>  		cpu_cluster_pm_exit();
>  
>  	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index c1c6b9d..5d32444 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -203,20 +203,6 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
>  	}
>  }
>  
> -/**
> - * omap4_mpuss_read_prev_context_state:
> - * Function returns the MPUSS previous context state
> - */
> -u32 omap4_mpuss_read_prev_context_state(void)
> -{
> -	u32 reg;
> -
> -	reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
> -		OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
> -	reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
> -	return reg;
> -}
> -
>  /*
>   * Store the CPU cluster state for L2X0 low power operations.
>   */

Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 13/15] ARM: OMAP4+: CPUidle: Deprecate use of omap4_mpuss_read_prev_context_state()
@ 2013-03-02  0:03     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-02  0:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:41-20130301, Santosh Shilimkar wrote:
> Current OMAP4 CPUIdle driver is using omap4_mpuss_read_prev_context_state()
> function to check whether the MPU cluster lost context or not. Thanks to
> couple CPUIdle, cluster low power entry is almost guaranteed and hence
> the programmed cluster check is enough in idle exit path. The API was
> more of an optimization for corner cases, where if the cluster low power
> entry fails for some reason, the cluster context restore gets skipped.
> 
> Moving forward, OMAP CPUidle drivers needs to be moved to drivers/idle/*
> once the PRM/CM code gets moved to drivers. This patch also reduces one
> dependency with platform code for idle driver movement.
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/common.h              |    5 -----
>  arch/arm/mach-omap2/cpuidle44xx.c         |    3 ++-
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   14 --------------
>  3 files changed, 2 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
> index 44fcf65..7f9b217 100644
> --- a/arch/arm/mach-omap2/common.h
> +++ b/arch/arm/mach-omap2/common.h
> @@ -242,7 +242,6 @@ 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)
> @@ -270,10 +269,6 @@ 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
>  
>  struct omap_sdrc_params;
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
> index df81243..23286c1 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
> @@ -147,7 +147,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
>  	 * Call idle CPU cluster PM exit notifier chain
>  	 * to restore GIC and wakeupgen context.
>  	 */
> -	if (omap4_mpuss_read_prev_context_state())
> +	if ((cx->mpu_state == PWRDM_POWER_RET) &&
> +		(cx->mpu_logic_state == PWRDM_POWER_OFF))
>  		cpu_cluster_pm_exit();
>  
>  	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index c1c6b9d..5d32444 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -203,20 +203,6 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
>  	}
>  }
>  
> -/**
> - * omap4_mpuss_read_prev_context_state:
> - * Function returns the MPUSS previous context state
> - */
> -u32 omap4_mpuss_read_prev_context_state(void)
> -{
> -	u32 reg;
> -
> -	reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
> -		OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET);
> -	reg &= OMAP4430_LOSTCONTEXT_DFF_MASK;
> -	return reg;
> -}
> -
>  /*
>   * Store the CPU cluster state for L2X0 low power operations.
>   */

Acked-by: Nishanth Menon <nm@ti.com>
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support
  2013-03-01 12:11   ` Santosh Shilimkar
@ 2013-03-02  0:25     ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-02  0:25 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 17:41-20130301, Santosh Shilimkar wrote:
> The OMAP5 idle driver can re-use OMAP4 CPUidle driver implementation thanks
> to compatible MPUSS design.
> 
> Though unlike OMAP4, on OMAP5 devices, MPUSS CSWR (Close Switch Retention)
> power states can be achieved with respective power states on CPU0 and CPU1
> power domain. This mode was broken on OMAP4 devices because of hardware
> limitation. Also there is no CPU low power entry order requirement like
> master CPU etc for CSWR C-state, which is icing on the cake. Code makes
> use of voting scheme for cluster low power state to support MPUSS CSWR
> C-state.
> 
> Supported OMAP5 CPUidle C-states:
>         C1 - CPU0 ON(WFI) + CPU1 ON(WFI) + MPUSS ON
>         C2 - CPU0 CSWR + CPU1 CSWR + MPUSS CSWR
>         C3 - CPU0 OFF + CPU1 Force OFF + MPUSS OSWR
 think you meant CPU1 OFF?
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/Kconfig                        |    1 +
>  arch/arm/mach-omap2/Makefile                       |    4 +-
>  .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  103 +++++++++++++++++++-
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    7 +-
>  arch/arm/mach-omap2/pm_omap4plus.c                 |    2 +-
>  5 files changed, 110 insertions(+), 7 deletions(-)
>  rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (70%)
> 
> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> index 41b581f..2df91dc 100644
> --- a/arch/arm/mach-omap2/Kconfig
> +++ b/arch/arm/mach-omap2/Kconfig
> @@ -82,6 +82,7 @@ config SOC_OMAP5
>  	select CPU_V7
>  	select HAVE_SMP
>  	select COMMON_CLK
> +	select ARCH_NEEDS_CPU_IDLE_COUPLED
>  
>  comment "OMAP Core Type"
>  	depends on ARCH_OMAP2
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 7c3c6b6..f6ff88f 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -97,8 +97,10 @@ endif
>  endif
>  
>  ifeq ($(CONFIG_CPU_IDLE),y)
> +omap4plus-common-idle			= cpuidle_omap4plus.o
>  obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
> -obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
> +obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-idle)
> +obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-idle)
nit pick: simpler to use cpuidle_omap4plus.o or do we expect more objs -
like moving the idle_data to DTS or so?
>  endif
>  
>  # PRCM
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle_omap4plus.c
> similarity index 70%
> rename from arch/arm/mach-omap2/cpuidle44xx.c
> rename to arch/arm/mach-omap2/cpuidle_omap4plus.c
> index 23286c1..8681fa6 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle_omap4plus.c
> @@ -29,6 +29,7 @@ struct idle_statedata {
>  	u32 cpu_state;
>  	u32 mpu_logic_state;
>  	u32 mpu_state;
> +	u32 mpu_state_vote;
>  };
>  
>  static struct idle_statedata omap4_idle_data[] = {
> @@ -49,17 +50,36 @@ static struct idle_statedata omap4_idle_data[] = {
>  	},
>  };
>  
> +static struct idle_statedata omap5_idle_data[] = {
> +	{
> +		.cpu_state = PWRDM_POWER_ON,
> +		.mpu_state = PWRDM_POWER_ON,
> +		.mpu_logic_state = PWRDM_POWER_RET,
> +	},
> +	{
> +		.cpu_state = PWRDM_POWER_RET,
CSWR I assume -> Documenting it helps? or we should introdce
cpu_logic_state to be explicit?
> +		.mpu_state = PWRDM_POWER_RET,
> +		.mpu_logic_state = PWRDM_POWER_RET,
> +	},
> +	{
> +		.cpu_state = PWRDM_POWER_OFF,
CSWR I assume -> Documenting it helps?
> +		.mpu_state = PWRDM_POWER_RET,
> +		.mpu_logic_state = PWRDM_POWER_OFF,
> +	},
> +};
> +
>  static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS];
>  static struct clockdomain *cpu_clkdm[NR_CPUS];
>  
>  static atomic_t abort_barrier;
>  static bool cpu_done[NR_CPUS];
>  static struct idle_statedata *state_ptr;
> +static DEFINE_RAW_SPINLOCK(mpu_lock);
>  
>  /* Private functions */
>  
>  /**
> - * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
> + * omap_enter_idle_[simple/smp/coupled] - OMAP4PLUS cpuidle entry functions
>   * @dev: cpuidle device
>   * @drv: cpuidle driver
>   * @index: the index of state to be entered
> @@ -132,6 +152,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
>  
>  	/* Wakeup CPU1 only if it is not offlined */
>  	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
> +		/* Restore MPU PD state post idle */
> +		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
>  		clkdm_wakeup(cpu_clkdm[1]);
>  		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
>  		clkdm_allow_idle(cpu_clkdm[1]);
> @@ -160,6 +182,37 @@ fail:
>  	return index;
>  }
>  
> +static int omap_enter_idle_smp(struct cpuidle_device *dev,
> +			struct cpuidle_driver *drv,
> +			int index)
> +{
> +	struct idle_statedata *cx = state_ptr + index;
> +	int cpu_id = smp_processor_id();
> +	unsigned long flag;
> +
> +	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
> +
> +	raw_spin_lock_irqsave(&mpu_lock, flag);
> +	cx->mpu_state_vote++;
> +	if (cx->mpu_state_vote == num_online_cpus()) {
> +		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
> +		omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
> +	}
> +	raw_spin_unlock_irqrestore(&mpu_lock, flag);
> +
> +	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
> +
> +	raw_spin_lock_irqsave(&mpu_lock, flag);
> +	if (cx->mpu_state_vote == num_online_cpus())
> +		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
> +	cx->mpu_state_vote--;
> +	raw_spin_unlock_irqrestore(&mpu_lock, flag);
> +
> +	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
> +
> +	return index;
> +}
> +
>  /*
>   * For each cpu, setup the broadcast timer because local timers
>   * stops for the states above C1.
> @@ -209,6 +262,43 @@ static struct cpuidle_driver omap4_idle_driver = {
>  	.safe_state_index = 0,
>  };
>  
> +static struct cpuidle_driver omap5_idle_driver = {
> +	.name				= "omap5_idle",
> +	.owner				= THIS_MODULE,
> +	.en_core_tk_irqen		= 1,
> +	.states = {
> +		{
> +			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
we could move these to .desc
> +			.exit_latency = 2 + 2,
> +			.target_residency = 5,
the obvious question on how these latencies were arrived at..
> +			.flags = CPUIDLE_FLAG_TIME_VALID,
> +			.enter = omap_enter_idle_simple,
> +			.name = "C1",
> +			.desc = "MPUSS ON"
> +		},
> +		{
> +			/* C2 - CPU0 CSWR + CPU1 CSWR + MPU CSWR */
we could move these to .desc
> +			.exit_latency = 16 + 16,
> +			.target_residency = 40,
> +			.flags = CPUIDLE_FLAG_TIME_VALID,
> +			.enter = omap_enter_idle_smp,
> +			.name = "C2",
> +			.desc = "MPUSS CSWR",
> +		},
> +		{
> +			/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
we could move these to .desc
> +			.exit_latency = 460 + 518,
> +			.target_residency = 1100,
> +			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
> +			.enter = omap_enter_idle_coupled,
> +			.name = "C3",
> +			.desc = "MPUSS OSWR",
> +		},
> +	},
> +	.state_count = ARRAY_SIZE(omap5_idle_data),
> +	.safe_state_index = 0,
> +};
> +
>  /* Public functions */
>  
>  /**
> @@ -220,7 +310,7 @@ static struct cpuidle_driver omap4_idle_driver = {
>  int __init omap4_idle_init(void)
>  {
>  	struct cpuidle_device *dev;
> -	unsigned int cpu_id = 0;
> +	unsigned cpu_id = 0;
>  
>  	/* Configure the broadcast timer on each cpu */
>  	mpu_pd = pwrdm_lookup("mpu_pwrdm");
> @@ -243,8 +333,13 @@ int __init omap4_idle_init(void)
>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
>  		dev->coupled_cpus = *cpu_online_mask;
>  #endif
> -		state_ptr = &omap4_idle_data[0];
> -		cpuidle_register_driver(&omap4_idle_driver);
> +		if (cpu_is_omap44xx()) {
> +			state_ptr = &omap4_idle_data[0];
> +			cpuidle_register_driver(&omap4_idle_driver);
> +		} else if (soc_is_omap54xx()) {
> +			state_ptr = &omap5_idle_data[0];
> +			cpuidle_register_driver(&omap5_idle_driver);
> +		}
we'd be doing cpuidle_register_driver twice since it is within the
for_each_cpu loop - we dont want to do that.
>  
>  		if (cpuidle_register_device(dev)) {
>  			pr_err("%s: CPUidle register failed\n", __func__);
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index 5d32444..0ccb76e 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -87,7 +87,7 @@ extern void omap5_cpu_resume(void);
>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
>  static void __iomem *sar_base;
> -static u32 cpu_context_offset;
> +static u32 cpu_context_offset, cpu_cswr_supported;
>  
>  static int default_finish_suspend(unsigned long cpu_state)
>  {
> @@ -265,6 +265,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  		save_state = 1;
>  		break;
>  	case PWRDM_POWER_RET:
> +		if (cpu_cswr_supported) {
> +			save_state = 0;
> +			break;
> +		}
ok, I guess this is the best we can do under the current circumstance
where PWRDM_POWER_RET means either CSWR or OSWR!
>  	default:
>  		/*
>  		 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
> @@ -449,6 +453,7 @@ int __init omap4_mpuss_init(void)
>  		omap_pm_ops.resume = omap5_cpu_resume;
>  		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
>  		enable_mercury_retention_mode();
> +		cpu_cswr_supported = 1;
>  	}
>  
>  	if (cpu_is_omap446x())
> diff --git a/arch/arm/mach-omap2/pm_omap4plus.c b/arch/arm/mach-omap2/pm_omap4plus.c
> index 4c37c47..d62edf5 100644
> --- a/arch/arm/mach-omap2/pm_omap4plus.c
> +++ b/arch/arm/mach-omap2/pm_omap4plus.c
> @@ -241,7 +241,7 @@ int __init omap4_pm_init(void)
>  	/* Overwrite the default arch_idle() */
>  	arm_pm_idle = omap_default_idle;
>  
> -	if (cpu_is_omap44xx())
> +	if (cpu_is_omap44xx() || soc_is_omap54xx())
>  		omap4_idle_init();
>  
>  err2:
otherwise, OK.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support
@ 2013-03-02  0:25     ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-02  0:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 17:41-20130301, Santosh Shilimkar wrote:
> The OMAP5 idle driver can re-use OMAP4 CPUidle driver implementation thanks
> to compatible MPUSS design.
> 
> Though unlike OMAP4, on OMAP5 devices, MPUSS CSWR (Close Switch Retention)
> power states can be achieved with respective power states on CPU0 and CPU1
> power domain. This mode was broken on OMAP4 devices because of hardware
> limitation. Also there is no CPU low power entry order requirement like
> master CPU etc for CSWR C-state, which is icing on the cake. Code makes
> use of voting scheme for cluster low power state to support MPUSS CSWR
> C-state.
> 
> Supported OMAP5 CPUidle C-states:
>         C1 - CPU0 ON(WFI) + CPU1 ON(WFI) + MPUSS ON
>         C2 - CPU0 CSWR + CPU1 CSWR + MPUSS CSWR
>         C3 - CPU0 OFF + CPU1 Force OFF + MPUSS OSWR
 think you meant CPU1 OFF?
> 
> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
>  arch/arm/mach-omap2/Kconfig                        |    1 +
>  arch/arm/mach-omap2/Makefile                       |    4 +-
>  .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  103 +++++++++++++++++++-
>  arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    7 +-
>  arch/arm/mach-omap2/pm_omap4plus.c                 |    2 +-
>  5 files changed, 110 insertions(+), 7 deletions(-)
>  rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (70%)
> 
> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> index 41b581f..2df91dc 100644
> --- a/arch/arm/mach-omap2/Kconfig
> +++ b/arch/arm/mach-omap2/Kconfig
> @@ -82,6 +82,7 @@ config SOC_OMAP5
>  	select CPU_V7
>  	select HAVE_SMP
>  	select COMMON_CLK
> +	select ARCH_NEEDS_CPU_IDLE_COUPLED
>  
>  comment "OMAP Core Type"
>  	depends on ARCH_OMAP2
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 7c3c6b6..f6ff88f 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -97,8 +97,10 @@ endif
>  endif
>  
>  ifeq ($(CONFIG_CPU_IDLE),y)
> +omap4plus-common-idle			= cpuidle_omap4plus.o
>  obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
> -obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
> +obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-idle)
> +obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-idle)
nit pick: simpler to use cpuidle_omap4plus.o or do we expect more objs -
like moving the idle_data to DTS or so?
>  endif
>  
>  # PRCM
> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle_omap4plus.c
> similarity index 70%
> rename from arch/arm/mach-omap2/cpuidle44xx.c
> rename to arch/arm/mach-omap2/cpuidle_omap4plus.c
> index 23286c1..8681fa6 100644
> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> +++ b/arch/arm/mach-omap2/cpuidle_omap4plus.c
> @@ -29,6 +29,7 @@ struct idle_statedata {
>  	u32 cpu_state;
>  	u32 mpu_logic_state;
>  	u32 mpu_state;
> +	u32 mpu_state_vote;
>  };
>  
>  static struct idle_statedata omap4_idle_data[] = {
> @@ -49,17 +50,36 @@ static struct idle_statedata omap4_idle_data[] = {
>  	},
>  };
>  
> +static struct idle_statedata omap5_idle_data[] = {
> +	{
> +		.cpu_state = PWRDM_POWER_ON,
> +		.mpu_state = PWRDM_POWER_ON,
> +		.mpu_logic_state = PWRDM_POWER_RET,
> +	},
> +	{
> +		.cpu_state = PWRDM_POWER_RET,
CSWR I assume -> Documenting it helps? or we should introdce
cpu_logic_state to be explicit?
> +		.mpu_state = PWRDM_POWER_RET,
> +		.mpu_logic_state = PWRDM_POWER_RET,
> +	},
> +	{
> +		.cpu_state = PWRDM_POWER_OFF,
CSWR I assume -> Documenting it helps?
> +		.mpu_state = PWRDM_POWER_RET,
> +		.mpu_logic_state = PWRDM_POWER_OFF,
> +	},
> +};
> +
>  static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS];
>  static struct clockdomain *cpu_clkdm[NR_CPUS];
>  
>  static atomic_t abort_barrier;
>  static bool cpu_done[NR_CPUS];
>  static struct idle_statedata *state_ptr;
> +static DEFINE_RAW_SPINLOCK(mpu_lock);
>  
>  /* Private functions */
>  
>  /**
> - * omap_enter_idle_[simple/coupled] - OMAP4PLUS cpuidle entry functions
> + * omap_enter_idle_[simple/smp/coupled] - OMAP4PLUS cpuidle entry functions
>   * @dev: cpuidle device
>   * @drv: cpuidle driver
>   * @index: the index of state to be entered
> @@ -132,6 +152,8 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
>  
>  	/* Wakeup CPU1 only if it is not offlined */
>  	if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) {
> +		/* Restore MPU PD state post idle */
> +		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
>  		clkdm_wakeup(cpu_clkdm[1]);
>  		omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
>  		clkdm_allow_idle(cpu_clkdm[1]);
> @@ -160,6 +182,37 @@ fail:
>  	return index;
>  }
>  
> +static int omap_enter_idle_smp(struct cpuidle_device *dev,
> +			struct cpuidle_driver *drv,
> +			int index)
> +{
> +	struct idle_statedata *cx = state_ptr + index;
> +	int cpu_id = smp_processor_id();
> +	unsigned long flag;
> +
> +	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id);
> +
> +	raw_spin_lock_irqsave(&mpu_lock, flag);
> +	cx->mpu_state_vote++;
> +	if (cx->mpu_state_vote == num_online_cpus()) {
> +		pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state);
> +		omap_set_pwrdm_state(mpu_pd, cx->mpu_state);
> +	}
> +	raw_spin_unlock_irqrestore(&mpu_lock, flag);
> +
> +	omap4_enter_lowpower(dev->cpu, cx->cpu_state);
> +
> +	raw_spin_lock_irqsave(&mpu_lock, flag);
> +	if (cx->mpu_state_vote == num_online_cpus())
> +		omap_set_pwrdm_state(mpu_pd, PWRDM_POWER_ON);
> +	cx->mpu_state_vote--;
> +	raw_spin_unlock_irqrestore(&mpu_lock, flag);
> +
> +	clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id);
> +
> +	return index;
> +}
> +
>  /*
>   * For each cpu, setup the broadcast timer because local timers
>   * stops for the states above C1.
> @@ -209,6 +262,43 @@ static struct cpuidle_driver omap4_idle_driver = {
>  	.safe_state_index = 0,
>  };
>  
> +static struct cpuidle_driver omap5_idle_driver = {
> +	.name				= "omap5_idle",
> +	.owner				= THIS_MODULE,
> +	.en_core_tk_irqen		= 1,
> +	.states = {
> +		{
> +			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
we could move these to .desc
> +			.exit_latency = 2 + 2,
> +			.target_residency = 5,
the obvious question on how these latencies were arrived at..
> +			.flags = CPUIDLE_FLAG_TIME_VALID,
> +			.enter = omap_enter_idle_simple,
> +			.name = "C1",
> +			.desc = "MPUSS ON"
> +		},
> +		{
> +			/* C2 - CPU0 CSWR + CPU1 CSWR + MPU CSWR */
we could move these to .desc
> +			.exit_latency = 16 + 16,
> +			.target_residency = 40,
> +			.flags = CPUIDLE_FLAG_TIME_VALID,
> +			.enter = omap_enter_idle_smp,
> +			.name = "C2",
> +			.desc = "MPUSS CSWR",
> +		},
> +		{
> +			/* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */
we could move these to .desc
> +			.exit_latency = 460 + 518,
> +			.target_residency = 1100,
> +			.flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED,
> +			.enter = omap_enter_idle_coupled,
> +			.name = "C3",
> +			.desc = "MPUSS OSWR",
> +		},
> +	},
> +	.state_count = ARRAY_SIZE(omap5_idle_data),
> +	.safe_state_index = 0,
> +};
> +
>  /* Public functions */
>  
>  /**
> @@ -220,7 +310,7 @@ static struct cpuidle_driver omap4_idle_driver = {
>  int __init omap4_idle_init(void)
>  {
>  	struct cpuidle_device *dev;
> -	unsigned int cpu_id = 0;
> +	unsigned cpu_id = 0;
>  
>  	/* Configure the broadcast timer on each cpu */
>  	mpu_pd = pwrdm_lookup("mpu_pwrdm");
> @@ -243,8 +333,13 @@ int __init omap4_idle_init(void)
>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
>  		dev->coupled_cpus = *cpu_online_mask;
>  #endif
> -		state_ptr = &omap4_idle_data[0];
> -		cpuidle_register_driver(&omap4_idle_driver);
> +		if (cpu_is_omap44xx()) {
> +			state_ptr = &omap4_idle_data[0];
> +			cpuidle_register_driver(&omap4_idle_driver);
> +		} else if (soc_is_omap54xx()) {
> +			state_ptr = &omap5_idle_data[0];
> +			cpuidle_register_driver(&omap5_idle_driver);
> +		}
we'd be doing cpuidle_register_driver twice since it is within the
for_each_cpu loop - we dont want to do that.
>  
>  		if (cpuidle_register_device(dev)) {
>  			pr_err("%s: CPUidle register failed\n", __func__);
> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> index 5d32444..0ccb76e 100644
> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> @@ -87,7 +87,7 @@ extern void omap5_cpu_resume(void);
>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>  static struct powerdomain *mpuss_pd;
>  static void __iomem *sar_base;
> -static u32 cpu_context_offset;
> +static u32 cpu_context_offset, cpu_cswr_supported;
>  
>  static int default_finish_suspend(unsigned long cpu_state)
>  {
> @@ -265,6 +265,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>  		save_state = 1;
>  		break;
>  	case PWRDM_POWER_RET:
> +		if (cpu_cswr_supported) {
> +			save_state = 0;
> +			break;
> +		}
ok, I guess this is the best we can do under the current circumstance
where PWRDM_POWER_RET means either CSWR or OSWR!
>  	default:
>  		/*
>  		 * CPUx CSWR is invalid hardware state. Also CPUx OSWR
> @@ -449,6 +453,7 @@ int __init omap4_mpuss_init(void)
>  		omap_pm_ops.resume = omap5_cpu_resume;
>  		cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
>  		enable_mercury_retention_mode();
> +		cpu_cswr_supported = 1;
>  	}
>  
>  	if (cpu_is_omap446x())
> diff --git a/arch/arm/mach-omap2/pm_omap4plus.c b/arch/arm/mach-omap2/pm_omap4plus.c
> index 4c37c47..d62edf5 100644
> --- a/arch/arm/mach-omap2/pm_omap4plus.c
> +++ b/arch/arm/mach-omap2/pm_omap4plus.c
> @@ -241,7 +241,7 @@ int __init omap4_pm_init(void)
>  	/* Overwrite the default arch_idle() */
>  	arm_pm_idle = omap_default_idle;
>  
> -	if (cpu_is_omap44xx())
> +	if (cpu_is_omap44xx() || soc_is_omap54xx())
>  		omap4_idle_init();
>  
>  err2:
otherwise, OK.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
  2013-03-01 17:43     ` Nishanth Menon
@ 2013-03-02  5:43       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  5:43 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Friday 01 March 2013 11:13 PM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm_omap4plus.c
>> similarity index 74%
>> rename from arch/arm/mach-omap2/pm44xx.c
>> rename to arch/arm/mach-omap2/pm_omap4plus.c
>> index 1d03110..95d2712 100644
>> --- a/arch/arm/mach-omap2/pm44xx.c
>> +++ b/arch/arm/mach-omap2/pm_omap4plus.c
>> @@ -1,7 +1,7 @@
>>  /*
>> - * OMAP4 Power Management Routines
>> + * OMAP4PLUS Power Management Routines
>>   *
>> - * Copyright (C) 2010-2011 Texas Instruments, Inc.
>> + * Copyright (C) 2010-2013 Texas Instruments, Inc.
>>   * Rajendra Nayak <rnayak@ti.com>
>>   * Santosh Shilimkar <santosh.shilimkar@ti.com>
>>   *
>> @@ -125,55 +125,77 @@ static void omap_default_idle(void)
>>  }
>>  
>>  /**
>> - * omap4_pm_init - Init routine for OMAP4 PM
>> + * omap4_init_static_deps - Init static clkdm dependencies on OMAP4
>>   *
>> - * Initializes all powerdomain and clockdomain target states
>> - * and all PRCM settings.
>> + * 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.
>> + * The L4 wakeup depedency is added to workaround the OCP sync hardware
>> + * BUG with 32K synctimer which lead to incorrect timer value read
>> + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
>> + * are part of L4 wakeup clockdomain.
>>   */
>> -int __init omap4_pm_init(void)
>> +static inline int omap4_init_static_deps(void)
>>  {
>>  	int ret;
>> -	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
>> -	struct clockdomain *ducati_clkdm, *l3_2_clkdm;
>> +	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
>> +	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
>>  
>> -	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);
>> -	if (ret) {
>> -		pr_err("Failed to setup powerdomains\n");
>> -		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");
>> +	l4wkup = clkdm_lookup("l4_wkup_clkdm");
> These static dependencies now seems added for OMAP4?
> Sounds like a separate patch as it is not exactly what $subject claims.
>>  	ducati_clkdm = clkdm_lookup("ducati_clkdm");
These are accidently added. I have removed these two in another series.
Will remove this one from the patch.

>> -	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
>> -		(!l3_2_clkdm) || (!ducati_clkdm))
>> -		goto err2;
>> +	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
>> +		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
>> +		return -EINVAL;
>>  
>>  	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(mpuss_clkdm, l4wkup);
>>  	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");
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +/**
>> + * omap4_pm_init - Init routine for OMAP4+ devices
>> + *
>> + * Initializes all powerdomain and clockdomain target states
>> + * and all PRCM settings.
>> + */
>> +int __init omap4_pm_init(void)
> could we rename it as omap4plus_pm_init while we are at it?
> This will help differentiate at least functions which are omap4 only and
> ones which we reuse for omap4plus?
Not needed. That way we have to rename all our omap2_* varients to
omap2plus. omap4_* is assumed to be omap4 and onwards just like
omap2_*

>> +{
>> +	int ret;
>> +
>> +	if (omap_rev() == OMAP4430_REV_ES1_0) {
> we have ID detection for OMAP5430_REV_ES1_0 in arch/arm/mach-omap2/id.c
> However, we do not support PM, so might as well use it to skip init?
Well the plan is to remove OMAP5 ES1.0 completely so no need to add
more checks. As already mentioned ES1.0 is not going to be supported
in mainline kernel.

Regerds,
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
@ 2013-03-02  5:43       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  5:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 01 March 2013 11:13 PM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm_omap4plus.c
>> similarity index 74%
>> rename from arch/arm/mach-omap2/pm44xx.c
>> rename to arch/arm/mach-omap2/pm_omap4plus.c
>> index 1d03110..95d2712 100644
>> --- a/arch/arm/mach-omap2/pm44xx.c
>> +++ b/arch/arm/mach-omap2/pm_omap4plus.c
>> @@ -1,7 +1,7 @@
>>  /*
>> - * OMAP4 Power Management Routines
>> + * OMAP4PLUS Power Management Routines
>>   *
>> - * Copyright (C) 2010-2011 Texas Instruments, Inc.
>> + * Copyright (C) 2010-2013 Texas Instruments, Inc.
>>   * Rajendra Nayak <rnayak@ti.com>
>>   * Santosh Shilimkar <santosh.shilimkar@ti.com>
>>   *
>> @@ -125,55 +125,77 @@ static void omap_default_idle(void)
>>  }
>>  
>>  /**
>> - * omap4_pm_init - Init routine for OMAP4 PM
>> + * omap4_init_static_deps - Init static clkdm dependencies on OMAP4
>>   *
>> - * Initializes all powerdomain and clockdomain target states
>> - * and all PRCM settings.
>> + * 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.
>> + * The L4 wakeup depedency is added to workaround the OCP sync hardware
>> + * BUG with 32K synctimer which lead to incorrect timer value read
>> + * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which
>> + * are part of L4 wakeup clockdomain.
>>   */
>> -int __init omap4_pm_init(void)
>> +static inline int omap4_init_static_deps(void)
>>  {
>>  	int ret;
>> -	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm;
>> -	struct clockdomain *ducati_clkdm, *l3_2_clkdm;
>> +	struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;
>> +	struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm;
>>  
>> -	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);
>> -	if (ret) {
>> -		pr_err("Failed to setup powerdomains\n");
>> -		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");
>> +	l4wkup = clkdm_lookup("l4_wkup_clkdm");
> These static dependencies now seems added for OMAP4?
> Sounds like a separate patch as it is not exactly what $subject claims.
>>  	ducati_clkdm = clkdm_lookup("ducati_clkdm");
These are accidently added. I have removed these two in another series.
Will remove this one from the patch.

>> -	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
>> -		(!l3_2_clkdm) || (!ducati_clkdm))
>> -		goto err2;
>> +	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
>> +		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
>> +		return -EINVAL;
>>  
>>  	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(mpuss_clkdm, l4wkup);
>>  	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");
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +/**
>> + * omap4_pm_init - Init routine for OMAP4+ devices
>> + *
>> + * Initializes all powerdomain and clockdomain target states
>> + * and all PRCM settings.
>> + */
>> +int __init omap4_pm_init(void)
> could we rename it as omap4plus_pm_init while we are at it?
> This will help differentiate at least functions which are omap4 only and
> ones which we reuse for omap4plus?
Not needed. That way we have to rename all our omap2_* varients to
omap2plus. omap4_* is assumed to be omap4 and onwards just like
omap2_*

>> +{
>> +	int ret;
>> +
>> +	if (omap_rev() == OMAP4430_REV_ES1_0) {
> we have ID detection for OMAP5430_REV_ES1_0 in arch/arm/mach-omap2/id.c
> However, we do not support PM, so might as well use it to skip init?
Well the plan is to remove OMAP5 ES1.0 completely so no need to add
more checks. As already mentioned ES1.0 is not going to be supported
in mainline kernel.

Regerds,
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
  2013-03-01 19:37     ` Nishanth Menon
@ 2013-03-02  5:47       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  5:47 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Saturday 02 March 2013 01:07 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> Enables MPUSS ES2 power management mode using ES2_PM_MODE in
>> AMBA_IF_MODE register.
>>
>> 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. Broken
>> 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode independently.
>>
>> This is one time settings thanks to always ON domain.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap-secure.h    |    2 ++
>>  arch/arm/mach-omap2/omap-wakeupgen.c |   14 ++++++++++++++
>>  arch/arm/mach-omap2/omap-wakeupgen.h |    1 +
>>  3 files changed, 17 insertions(+)
>>
>> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
>> index 0e72917..82b3c4c 100644
>> --- a/arch/arm/mach-omap2/omap-secure.h
>> +++ b/arch/arm/mach-omap2/omap-secure.h
>> @@ -42,6 +42,8 @@
>>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
>>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>>  
>> +#define OMAP5_MON_AMBA_IF_INDEX		0x108
>> +
>>  /* Secure PPA(Primary Protected Application) APIs */
>>  #define OMAP4_PPA_L2_POR_INDEX		0x23
>>  #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
>> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
>> index 5d3b4f4..a7350dd 100644
>> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
>> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
>> @@ -403,6 +403,7 @@ int __init omap_wakeupgen_init(void)
>>  {
>>  	int i;
>>  	unsigned int boot_cpu = smp_processor_id();
>> +	u32 val;
>>  
>>  	/* Not supported on OMAP4 ES1.0 silicon */
>>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
>> @@ -444,6 +445,19 @@ int __init omap_wakeupgen_init(void)
>>  	for (i = 0; i < max_irqs; i++)
>>  		irq_target_cpu[i] = boot_cpu;
>>  
>> +	/*
>> +	 * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
>> +	 * 0x0:	ES1 behavior, CPU cores would enter and exit OFF mode together.
>> +	 * 0x1:	ES2 behavior, CPU cores are allowed to enter/exit OFF mode
>> +	 * independently.
>> +	 * This needs to be set one time thanks to always ON domain.
>> +	 */
>> +	if (soc_is_omap54xx()) {
>> +		val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
>> +		val |= BIT(5);
> BIT(5) is ES2_PM_MODE for es2.0 only - we dont have a OMAP5 revision check atm.
> maybe 
>> +		omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
>> +	}
>> +
>>  	irq_hotplug_init();
>>  	irq_pm_init();
>>  
>> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
>> index b0fd16f..b3c8ecc 100644
>> --- a/arch/arm/mach-omap2/omap-wakeupgen.h
>> +++ b/arch/arm/mach-omap2/omap-wakeupgen.h
>> @@ -27,6 +27,7 @@
>>  #define OMAP_WKG_ENB_E_1			0x420
>>  #define OMAP_AUX_CORE_BOOT_0			0x800
>>  #define OMAP_AUX_CORE_BOOT_1			0x804
>> +#define OMAP_AMBA_IF_MODE			0x80c
>>  #define OMAP_PTMSYNCREQ_MASK			0xc00
>>  #define OMAP_PTMSYNCREQ_EN			0xc04
>>  #define OMAP_TIMESTAMPCYCLELO			0xc08
> 
> Curious, I see OMAP5_AMBA_IF_MODE_OFFSET in
> arch/arm/mach-omap2/omap4-sar-layout.h
> if we dont save new modified contents there, Wont restore logic just
> reset it back to 0?
> 
It is already restored in the wakeup-gen restore code.

Regards
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
@ 2013-03-02  5:47       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  5:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 March 2013 01:07 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> Enables MPUSS ES2 power management mode using ES2_PM_MODE in
>> AMBA_IF_MODE register.
>>
>> 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. Broken
>> 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode independently.
>>
>> This is one time settings thanks to always ON domain.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap-secure.h    |    2 ++
>>  arch/arm/mach-omap2/omap-wakeupgen.c |   14 ++++++++++++++
>>  arch/arm/mach-omap2/omap-wakeupgen.h |    1 +
>>  3 files changed, 17 insertions(+)
>>
>> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
>> index 0e72917..82b3c4c 100644
>> --- a/arch/arm/mach-omap2/omap-secure.h
>> +++ b/arch/arm/mach-omap2/omap-secure.h
>> @@ -42,6 +42,8 @@
>>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
>>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>>  
>> +#define OMAP5_MON_AMBA_IF_INDEX		0x108
>> +
>>  /* Secure PPA(Primary Protected Application) APIs */
>>  #define OMAP4_PPA_L2_POR_INDEX		0x23
>>  #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
>> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
>> index 5d3b4f4..a7350dd 100644
>> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
>> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
>> @@ -403,6 +403,7 @@ int __init omap_wakeupgen_init(void)
>>  {
>>  	int i;
>>  	unsigned int boot_cpu = smp_processor_id();
>> +	u32 val;
>>  
>>  	/* Not supported on OMAP4 ES1.0 silicon */
>>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
>> @@ -444,6 +445,19 @@ int __init omap_wakeupgen_init(void)
>>  	for (i = 0; i < max_irqs; i++)
>>  		irq_target_cpu[i] = boot_cpu;
>>  
>> +	/*
>> +	 * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
>> +	 * 0x0:	ES1 behavior, CPU cores would enter and exit OFF mode together.
>> +	 * 0x1:	ES2 behavior, CPU cores are allowed to enter/exit OFF mode
>> +	 * independently.
>> +	 * This needs to be set one time thanks to always ON domain.
>> +	 */
>> +	if (soc_is_omap54xx()) {
>> +		val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
>> +		val |= BIT(5);
> BIT(5) is ES2_PM_MODE for es2.0 only - we dont have a OMAP5 revision check atm.
> maybe 
>> +		omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
>> +	}
>> +
>>  	irq_hotplug_init();
>>  	irq_pm_init();
>>  
>> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
>> index b0fd16f..b3c8ecc 100644
>> --- a/arch/arm/mach-omap2/omap-wakeupgen.h
>> +++ b/arch/arm/mach-omap2/omap-wakeupgen.h
>> @@ -27,6 +27,7 @@
>>  #define OMAP_WKG_ENB_E_1			0x420
>>  #define OMAP_AUX_CORE_BOOT_0			0x800
>>  #define OMAP_AUX_CORE_BOOT_1			0x804
>> +#define OMAP_AMBA_IF_MODE			0x80c
>>  #define OMAP_PTMSYNCREQ_MASK			0xc00
>>  #define OMAP_PTMSYNCREQ_EN			0xc04
>>  #define OMAP_TIMESTAMPCYCLELO			0xc08
> 
> Curious, I see OMAP5_AMBA_IF_MODE_OFFSET in
> arch/arm/mach-omap2/omap4-sar-layout.h
> if we dont save new modified contents there, Wont restore logic just
> reset it back to 0?
> 
It is already restored in the wakeup-gen restore code.

Regards
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
  2013-03-01 19:42     ` Nishanth Menon
@ 2013-03-02  5:52       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  5:52 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Saturday 02 March 2013 01:12 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> In addition to the standard power-management technique, the OMAP5
>> MPU subsystem also employs an SR3-APG (mercury) power management
>> technology to reduce leakage.
> Mercury fast is employed here - might be good to note that.
Slow is completly descoped from validation and only supported mode
is mercury fast which was the intention. So lets not add any confusion
since other state isn't supported. 
>>
>> It allows for full logic and memories retention on MPU_C0 and MPU_C1 and
>> is controlled by the PRCM_MPU.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   17 +++++++++++++++++
>>  1 file changed, 17 insertions(+)
>>
>> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> index bcd2efb..9fda96b 100644
>> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> @@ -360,6 +360,20 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>>  
>>  
>>  /*
>> + * Enable Mercury Fast HG retention mode by default.
>> + */
>> +static void enable_mercury_retention_mode(void)
>> +{
>> +	u32 reg;
>> +
>> +	reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
>> +			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
>> +	reg |= BIT(24) | BIT(25);
> Can we please use macros here?
> we are setting BIT(25) - fast ramp-up (Mercury fast) Vs 0 (which would
> have been mercury slow)
> BIT(24) is mercury enable basically. OMAP4 prm-regbits-44xx.h did not
> have these ofcourse, so might be a different bit file or so?
As already commented above, only mode supported is mercury fast and
hence to avoid any further confusion, i have used bit fields.
In short, to enable the mercury on O5, both bits needs to be set.
And to avoid any fast/slow confusion, I haven't used macro's.

Regards
Santosh


^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
@ 2013-03-02  5:52       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  5:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 March 2013 01:12 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> In addition to the standard power-management technique, the OMAP5
>> MPU subsystem also employs an SR3-APG (mercury) power management
>> technology to reduce leakage.
> Mercury fast is employed here - might be good to note that.
Slow is completly descoped from validation and only supported mode
is mercury fast which was the intention. So lets not add any confusion
since other state isn't supported. 
>>
>> It allows for full logic and memories retention on MPU_C0 and MPU_C1 and
>> is controlled by the PRCM_MPU.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   17 +++++++++++++++++
>>  1 file changed, 17 insertions(+)
>>
>> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> index bcd2efb..9fda96b 100644
>> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> @@ -360,6 +360,20 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>>  
>>  
>>  /*
>> + * Enable Mercury Fast HG retention mode by default.
>> + */
>> +static void enable_mercury_retention_mode(void)
>> +{
>> +	u32 reg;
>> +
>> +	reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
>> +			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
>> +	reg |= BIT(24) | BIT(25);
> Can we please use macros here?
> we are setting BIT(25) - fast ramp-up (Mercury fast) Vs 0 (which would
> have been mercury slow)
> BIT(24) is mercury enable basically. OMAP4 prm-regbits-44xx.h did not
> have these ofcourse, so might be a different bit file or so?
As already commented above, only mode supported is mercury fast and
hence to avoid any further confusion, i have used bit fields.
In short, to enable the mercury on O5, both bits needs to be set.
And to avoid any fast/slow confusion, I haven't used macro's.

Regards
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization
  2013-03-01 20:12     ` Nishanth Menon
@ 2013-03-02  6:00       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:00 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Saturday 02 March 2013 01:42 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> With consolidated code, now we can add the .init_late hook for
>> OMAP5 to enable power management and mux initialization.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/board-generic.c |    1 +
>>  arch/arm/mach-omap2/common.h        |    3 ++-
>>  arch/arm/mach-omap2/io.c            |    8 ++++++++
>>  3 files changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
>> index 53cb380b..eac4ec5 100644
>> --- a/arch/arm/mach-omap2/board-generic.c
>> +++ b/arch/arm/mach-omap2/board-generic.c
>> @@ -179,6 +179,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
>>  	.init_irq	= omap_gic_of_init,
>>  	.handle_irq	= gic_handle_irq,
>>  	.init_machine	= omap_generic_init,
>> +	.init_late	= omap5_init_late,
>>  	.timer		= &omap5_timer,
>>  	.dt_compat	= omap5_boards_compat,
>>  	.restart	= omap44xx_restart,
>> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
>> index e0f9ea7..44fcf65 100644
>> --- a/arch/arm/mach-omap2/common.h
>> +++ b/arch/arm/mach-omap2/common.h
>> @@ -59,7 +59,7 @@ static inline int omap3_pm_init(void)
>>  }
>>  #endif
>>  
>> -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
>> +#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5))
>>  int omap4_pm_init(void);
>>  #else
>>  static inline int omap4_pm_init(void)
>> @@ -108,6 +108,7 @@ void omap35xx_init_late(void);
>>  void omap3630_init_late(void);
>>  void am35xx_init_late(void);
>>  void ti81xx_init_late(void);
>> +void omap5_init_late(void);
>>  int omap2_common_pm_late_init(void);
>>  
>>  #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
>> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
>> index 2c3fdd6..e6ba596 100644
>> --- a/arch/arm/mach-omap2/io.c
>> +++ b/arch/arm/mach-omap2/io.c
>> @@ -620,6 +620,14 @@ void __init omap5_init_early(void)
>>  	omap_cm_base_init();
>>  	omap5xxx_check_revision();
>>  }
>> +
>> +void __init omap5_init_late(void)
>> +{
>> +	omap_mux_late_init();
>> +	omap2_common_pm_late_init();
>> +	omap4_pm_init();
> as part of init sequence, we'd late_initcall *after* module_inits,
> implying probes of drivers will be called (for built-in drivers) prior
> to PM getting ready.
> 
> This basically makes key features like dvfs not available for drivers until
> late_init is complete.
> 
> We have faced tons of problems in the past with this approach, cant we
> improve this? One solution(we used in Android kernel fork) might be to
> ensure all core framework initialized before module_init either in
> arch_init or subsys_init. I am aware that machine_desc does not provide us
> that flexibility - should'nt we rather extend it for the same instead of
> having to go through the same pain all over again?
> 
I have seen those tons of internal patches as well :)
The point is, there is nothing at the moment in mainline code breaks
with this init sequence so it just fine.

You might have valid point but it is more of generic init sequence
for all PM code. Since you are aware of all the needs, I suggest
you to address that in another series so that all devices gets
addressed. Looking at current mainline supported code and the scope
of PM, I suspect there is any issue.

Regards
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization
@ 2013-03-02  6:00       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 March 2013 01:42 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> With consolidated code, now we can add the .init_late hook for
>> OMAP5 to enable power management and mux initialization.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/board-generic.c |    1 +
>>  arch/arm/mach-omap2/common.h        |    3 ++-
>>  arch/arm/mach-omap2/io.c            |    8 ++++++++
>>  3 files changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
>> index 53cb380b..eac4ec5 100644
>> --- a/arch/arm/mach-omap2/board-generic.c
>> +++ b/arch/arm/mach-omap2/board-generic.c
>> @@ -179,6 +179,7 @@ DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
>>  	.init_irq	= omap_gic_of_init,
>>  	.handle_irq	= gic_handle_irq,
>>  	.init_machine	= omap_generic_init,
>> +	.init_late	= omap5_init_late,
>>  	.timer		= &omap5_timer,
>>  	.dt_compat	= omap5_boards_compat,
>>  	.restart	= omap44xx_restart,
>> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
>> index e0f9ea7..44fcf65 100644
>> --- a/arch/arm/mach-omap2/common.h
>> +++ b/arch/arm/mach-omap2/common.h
>> @@ -59,7 +59,7 @@ static inline int omap3_pm_init(void)
>>  }
>>  #endif
>>  
>> -#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
>> +#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5))
>>  int omap4_pm_init(void);
>>  #else
>>  static inline int omap4_pm_init(void)
>> @@ -108,6 +108,7 @@ void omap35xx_init_late(void);
>>  void omap3630_init_late(void);
>>  void am35xx_init_late(void);
>>  void ti81xx_init_late(void);
>> +void omap5_init_late(void);
>>  int omap2_common_pm_late_init(void);
>>  
>>  #if defined(CONFIG_SOC_OMAP2420) || defined(CONFIG_SOC_OMAP2430)
>> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
>> index 2c3fdd6..e6ba596 100644
>> --- a/arch/arm/mach-omap2/io.c
>> +++ b/arch/arm/mach-omap2/io.c
>> @@ -620,6 +620,14 @@ void __init omap5_init_early(void)
>>  	omap_cm_base_init();
>>  	omap5xxx_check_revision();
>>  }
>> +
>> +void __init omap5_init_late(void)
>> +{
>> +	omap_mux_late_init();
>> +	omap2_common_pm_late_init();
>> +	omap4_pm_init();
> as part of init sequence, we'd late_initcall *after* module_inits,
> implying probes of drivers will be called (for built-in drivers) prior
> to PM getting ready.
> 
> This basically makes key features like dvfs not available for drivers until
> late_init is complete.
> 
> We have faced tons of problems in the past with this approach, cant we
> improve this? One solution(we used in Android kernel fork) might be to
> ensure all core framework initialized before module_init either in
> arch_init or subsys_init. I am aware that machine_desc does not provide us
> that flexibility - should'nt we rather extend it for the same instead of
> having to go through the same pain all over again?
> 
I have seen those tons of internal patches as well :)
The point is, there is nothing at the moment in mainline code breaks
with this init sequence so it just fine.

You might have valid point but it is more of generic init sequence
for all PM code. Since you are aware of all the needs, I suggest
you to address that in another series so that all devices gets
addressed. Looking at current mainline supported code and the scope
of PM, I suspect there is any issue.

Regards
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support
  2013-03-01 21:36     ` Nishanth Menon
@ 2013-03-02  6:14       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:14 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Saturday 02 March 2013 03:06 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> Add power management code to handle the CPU off mode. Separate
>> suspend finisher is used for OMAP5(Cortex-A15) because it doesn't
>> use SCU power status register and external PL310 L2 cache which makes
>> code flow bit different.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   31 +++++++----
>>  arch/arm/mach-omap2/omap-secure.h         |    1 +
>>  arch/arm/mach-omap2/omap4-sar-layout.h    |    2 +
>>  arch/arm/mach-omap2/sleep_omap4plus.S     |   80 +++++++++++++++++++++++++++++
>>  4 files changed, 104 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> index 9fda96b..275f9a4 100644
>> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> @@ -76,10 +76,12 @@ struct cpu_pm_ops {
>>  	int (*finish_suspend)(unsigned long cpu_state);
>>  	void (*resume)(void);
>>  	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
>> +	void (*hotplug_restart)(void);
>>  };
>>  
>>  extern int omap4_finish_suspend(unsigned long cpu_state);
>>  extern void omap4_cpu_resume(void);
>> +extern int omap5_finish_suspend(unsigned long cpu_state);
>>  
>>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>>  static struct powerdomain *mpuss_pd;
>> @@ -102,6 +104,7 @@ struct cpu_pm_ops omap_pm_ops = {
>>  	.finish_suspend		= default_finish_suspend,
>>  	.resume			= dummy_cpu_resume,
>>  	.scu_prepare		= dummy_scu_prepare,
>> +	.hotplug_restart	= dummy_cpu_resume,
>>  };
>>  
>>  /*
>> @@ -334,7 +337,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>>  int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>>  {
>>  	unsigned int cpu_state = 0;
>> -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
>>  
>>  	if (omap_rev() == OMAP4430_REV_ES1_0)
>>  		return -ENXIO;
>> @@ -344,7 +346,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>>  
>>  	clear_cpu_prev_pwrst(cpu);
>>  	set_cpu_next_pwrst(cpu, power_state);
>> -	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
>> +	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
>>  	omap_pm_ops.scu_prepare(cpu, power_state);
>>  
>>  	/*
>> @@ -379,6 +381,7 @@ static void enable_mercury_retention_mode(void)
>>  int __init omap4_mpuss_init(void)
>>  {
>>  	struct omap4_cpu_pm_info *pm_info;
>> +	u32 cpu_wakeup_addr = 0;
>>  
>>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
>>  		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
>> @@ -388,9 +391,13 @@ int __init omap4_mpuss_init(void)
>>  	sar_base = omap4_get_sar_ram_base();
>>  
>>  	/* Initilaise per CPU PM information */
>> +	if (cpu_is_omap44xx())
>> +		cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
>> +	else if (soc_is_omap54xx())
>> +		cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
>>  	pm_info = &per_cpu(omap4_pm_info, 0x0);
>>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
>> -	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
>> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
>>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
>>  	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
>>  	if (!pm_info->pwrdm) {
>> @@ -405,14 +412,14 @@ int __init omap4_mpuss_init(void)
>>  	/* Initialise CPU0 power domain state to ON */
>>  	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
>>  
>> +	if (cpu_is_omap44xx())
>> +		cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
>> +	else if (soc_is_omap54xx())
>> +		cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
>>  	pm_info = &per_cpu(omap4_pm_info, 0x1);
>>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
>> -	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
>> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
>>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
>> -	if (cpu_is_omap446x())
>> -		pm_info->secondary_startup = omap_secondary_startup_4460;
>> -	else
>> -		pm_info->secondary_startup = omap_secondary_startup;
>>  
>>  	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
>>  	if (!pm_info->pwrdm) {
>> @@ -445,15 +452,19 @@ int __init omap4_mpuss_init(void)
>>  
>>  	if (cpu_is_omap44xx()) {
>>  		omap_pm_ops.finish_suspend = omap4_finish_suspend;
>> +		omap_pm_ops.hotplug_restart = omap_secondary_startup;
> could we handle omap_pm_ops.hotplug_restart = omap_secondary_startup_4460
> here as well with the interest of keeping all function inits
> in consecutive source location?
I don't wanted to have multiple indentation and  4460 bug is just
too annoying that it is better to keep it seperate.


>> diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
>> index 6822d0a..ee8215b 100644
>> --- a/arch/arm/mach-omap2/omap4-sar-layout.h
>> +++ b/arch/arm/mach-omap2/omap4-sar-layout.h
>> @@ -31,6 +31,8 @@
>>  /* 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
>> +#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
>> +#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
>>  
>>  #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
>>  #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
>> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
>> index 88ff83a..3322fc8 100644
>> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
>> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
>> @@ -326,6 +326,86 @@ skip_l2en:
>>  
>>  	b	cpu_resume			@ Jump to generic resume
>>  ENDPROC(omap4_cpu_resume)
>> +
>> +/*
>> + * ================================
>> + * == OMAP5 CPU suspend finisher ==
>> + * ================================
>> + *
>> + * OMAP5 MPUSS states for the context save:
>> + * save_state =
>> + *	0 - Nothing lost and no need to save: MPUSS INA/CSWR
>> + *	1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR
>> + *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
>> + *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
>> + */
>> +ENTRY(omap5_finish_suspend)
>> +	stmfd	sp!, {r4-r12, lr}
>> +	cmp	r0, #0x0
>> +	beq	do_wfi				@ No lowpower state, jump to WFI
>> +
>> +	/*
>> +	 * Flush all data from the L1 data cache before disabling
>> +	 * SCTLR.C bit.
>> +	 */
>> +	bl	omap4_get_sar_ram_base
>> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
>> +	cmp	r9, #0x1			@ Check for HS device
>> +	bne	skip_secure_l1_clean_op
>> +	mov	r0, #0				@ Clean secure L1
>> +	stmfd   r13!, {r4-r12, r14}
>> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
>> +	DO_SMC
>> +	ldmfd   r13!, {r4-r12, r14}
>> +skip_secure_l1_clean_op:
>> +	bl	v7_flush_dcache_louis
>> +
>> +	/*
>> +	 * Clear the SCTLR.C bit to prevent further data cache
>> +	 * allocation. Clearing SCTLR.C would make all the data accesses
>> +	 * strongly ordered and would not hit the cache.
>> +	 */
>> +	mrc	p15, 0, r0, c1, c0, 0
>> +	bic	r0, r0, #(1 << 2)		@ Disable the C bit
>> +	mcr	p15, 0, r0, c1, c0, 0
>> +	isb
>> +
>> +	/* Clean and Invalidate L1 data cache. */
>> +	bl	v7_flush_dcache_louis
> Curious question - once we have flushed and invalidated L1 on
> skip_secure_l1_clean_op:, we disable SCTLR.C to make all accesses SO,
> what is the need to go through clean and invalidate again? is'nt it an
> un-necessary cycle consuming NOP? What kind of data are we cleaning out
> here?
Obviously you haven't read all the old emails internally as well as
externally on this topic. Its needed.

>> +
>> +	/*
>> +	 * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus
>> +	 * preventing the CPU from receiving cache, TLB, or BTB
>> +	 * maintenance operations broadcast by other CPUs in the cluster.
>> +	 */
>> +	mrc	p15, 0, r0, c1, c1, 2		@ Read NSACR data
>> +	tst	r0, #(1 << 18)
>> +	mrcne	p15, 0, r0, c1, c0, 1
>> +	bicne	r0, r0, #(1 << 6)		@ Disable SMP bit
>> +	mcrne	p15, 0, r0, c1, c0, 1
>> +	isb
>> +	dsb
>> +
> when save_state=3, as per the function comment:
>  3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> But we dont flush L2 nonsecure OR secure at this point. results wont be
> pretty.
Subject adds CPU off support only. I have added the comments section in
this patch. I can move that for next patch.

> If we dont want to deal with "3", then should'nt we add an adequate
> handler on entry and remove the code comment claiming we support
> it?
> is'nt it better to squash in "[PATCH 11/15] ARM: OMAP5: PM: Add L2
> memory power down support" here?
Why. You don't need L2 support for CPU OFF. As I said I will move the
comment in further patch which seems to confused you. And sure, I will
remove that device OFF reference but still support mode where L2
can be destroyed. It can be done in MPU OSWR as well with a setting
to loose L2.

>> +do_wfi:
>> +	bl	omap_do_wfi
>> +
>> +	/*
>> +	 * CPU is here when it failed to enter OFF/DORMANT or
>> +	 * no low power state was attempted.
> This might need a bit more clarity IMHO. successful WFI (which is
> arguably an power state if we consider ARM internal clock gating takes
> place), will reach here as well. So would OMAP CPU INA state. The
> comment is probably valid for the defined save_states in code comments
> for CPU OFF which is un-successful.
>> +	 */
>> +	mrc	p15, 0, r0, c1, c0, 0
>> +	tst	r0, #(1 << 2)			@ Check C bit enabled?
>> +	orreq	r0, r0, #(1 << 2)		@ Enable the C bit
>> +	mcreq	p15, 0, r0, c1, c0, 0
>> +	isb
>> +	mrc	p15, 0, r0, c1, c0, 1
>> +	tst	r0, #(1 << 6)			@ Check SMP bit enabled?
>> +	orreq	r0, r0, #(1 << 6)
>> +	mcreq	p15, 0, r0, c1, c0, 1
>> +	isb
>> +	dsb
>> +	ldmfd	sp!, {r4-r12, pc}
>> +ENDPROC(omap5_finish_suspend)
>>  #endif
>>  
>>  #ifndef CONFIG_OMAP4_ERRATA_I688
> 
> I was curious at this point -> given that we added documentation that
> we will be able to go to CPU OFF here, but I did not see an resume
> handler registered. Untill I looked down in the series to see:
>
I should have mentioned abou CPU OFF in hotplug path which doesn't
need resume entry. Will update commit message accordingly. Thanks
for comments.

regards
Santosh


^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support
@ 2013-03-02  6:14       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 March 2013 03:06 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> Add power management code to handle the CPU off mode. Separate
>> suspend finisher is used for OMAP5(Cortex-A15) because it doesn't
>> use SCU power status register and external PL310 L2 cache which makes
>> code flow bit different.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   31 +++++++----
>>  arch/arm/mach-omap2/omap-secure.h         |    1 +
>>  arch/arm/mach-omap2/omap4-sar-layout.h    |    2 +
>>  arch/arm/mach-omap2/sleep_omap4plus.S     |   80 +++++++++++++++++++++++++++++
>>  4 files changed, 104 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> index 9fda96b..275f9a4 100644
>> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> @@ -76,10 +76,12 @@ struct cpu_pm_ops {
>>  	int (*finish_suspend)(unsigned long cpu_state);
>>  	void (*resume)(void);
>>  	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
>> +	void (*hotplug_restart)(void);
>>  };
>>  
>>  extern int omap4_finish_suspend(unsigned long cpu_state);
>>  extern void omap4_cpu_resume(void);
>> +extern int omap5_finish_suspend(unsigned long cpu_state);
>>  
>>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>>  static struct powerdomain *mpuss_pd;
>> @@ -102,6 +104,7 @@ struct cpu_pm_ops omap_pm_ops = {
>>  	.finish_suspend		= default_finish_suspend,
>>  	.resume			= dummy_cpu_resume,
>>  	.scu_prepare		= dummy_scu_prepare,
>> +	.hotplug_restart	= dummy_cpu_resume,
>>  };
>>  
>>  /*
>> @@ -334,7 +337,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>>  int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>>  {
>>  	unsigned int cpu_state = 0;
>> -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
>>  
>>  	if (omap_rev() == OMAP4430_REV_ES1_0)
>>  		return -ENXIO;
>> @@ -344,7 +346,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
>>  
>>  	clear_cpu_prev_pwrst(cpu);
>>  	set_cpu_next_pwrst(cpu, power_state);
>> -	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
>> +	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
>>  	omap_pm_ops.scu_prepare(cpu, power_state);
>>  
>>  	/*
>> @@ -379,6 +381,7 @@ static void enable_mercury_retention_mode(void)
>>  int __init omap4_mpuss_init(void)
>>  {
>>  	struct omap4_cpu_pm_info *pm_info;
>> +	u32 cpu_wakeup_addr = 0;
>>  
>>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
>>  		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
>> @@ -388,9 +391,13 @@ int __init omap4_mpuss_init(void)
>>  	sar_base = omap4_get_sar_ram_base();
>>  
>>  	/* Initilaise per CPU PM information */
>> +	if (cpu_is_omap44xx())
>> +		cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
>> +	else if (soc_is_omap54xx())
>> +		cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
>>  	pm_info = &per_cpu(omap4_pm_info, 0x0);
>>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
>> -	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
>> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
>>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
>>  	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
>>  	if (!pm_info->pwrdm) {
>> @@ -405,14 +412,14 @@ int __init omap4_mpuss_init(void)
>>  	/* Initialise CPU0 power domain state to ON */
>>  	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
>>  
>> +	if (cpu_is_omap44xx())
>> +		cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
>> +	else if (soc_is_omap54xx())
>> +		cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
>>  	pm_info = &per_cpu(omap4_pm_info, 0x1);
>>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
>> -	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
>> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
>>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
>> -	if (cpu_is_omap446x())
>> -		pm_info->secondary_startup = omap_secondary_startup_4460;
>> -	else
>> -		pm_info->secondary_startup = omap_secondary_startup;
>>  
>>  	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
>>  	if (!pm_info->pwrdm) {
>> @@ -445,15 +452,19 @@ int __init omap4_mpuss_init(void)
>>  
>>  	if (cpu_is_omap44xx()) {
>>  		omap_pm_ops.finish_suspend = omap4_finish_suspend;
>> +		omap_pm_ops.hotplug_restart = omap_secondary_startup;
> could we handle omap_pm_ops.hotplug_restart = omap_secondary_startup_4460
> here as well with the interest of keeping all function inits
> in consecutive source location?
I don't wanted to have multiple indentation and  4460 bug is just
too annoying that it is better to keep it seperate.


>> diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
>> index 6822d0a..ee8215b 100644
>> --- a/arch/arm/mach-omap2/omap4-sar-layout.h
>> +++ b/arch/arm/mach-omap2/omap4-sar-layout.h
>> @@ -31,6 +31,8 @@
>>  /* 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
>> +#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
>> +#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
>>  
>>  #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
>>  #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
>> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
>> index 88ff83a..3322fc8 100644
>> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
>> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
>> @@ -326,6 +326,86 @@ skip_l2en:
>>  
>>  	b	cpu_resume			@ Jump to generic resume
>>  ENDPROC(omap4_cpu_resume)
>> +
>> +/*
>> + * ================================
>> + * == OMAP5 CPU suspend finisher ==
>> + * ================================
>> + *
>> + * OMAP5 MPUSS states for the context save:
>> + * save_state =
>> + *	0 - Nothing lost and no need to save: MPUSS INA/CSWR
>> + *	1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR
>> + *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
>> + *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
>> + */
>> +ENTRY(omap5_finish_suspend)
>> +	stmfd	sp!, {r4-r12, lr}
>> +	cmp	r0, #0x0
>> +	beq	do_wfi				@ No lowpower state, jump to WFI
>> +
>> +	/*
>> +	 * Flush all data from the L1 data cache before disabling
>> +	 * SCTLR.C bit.
>> +	 */
>> +	bl	omap4_get_sar_ram_base
>> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
>> +	cmp	r9, #0x1			@ Check for HS device
>> +	bne	skip_secure_l1_clean_op
>> +	mov	r0, #0				@ Clean secure L1
>> +	stmfd   r13!, {r4-r12, r14}
>> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
>> +	DO_SMC
>> +	ldmfd   r13!, {r4-r12, r14}
>> +skip_secure_l1_clean_op:
>> +	bl	v7_flush_dcache_louis
>> +
>> +	/*
>> +	 * Clear the SCTLR.C bit to prevent further data cache
>> +	 * allocation. Clearing SCTLR.C would make all the data accesses
>> +	 * strongly ordered and would not hit the cache.
>> +	 */
>> +	mrc	p15, 0, r0, c1, c0, 0
>> +	bic	r0, r0, #(1 << 2)		@ Disable the C bit
>> +	mcr	p15, 0, r0, c1, c0, 0
>> +	isb
>> +
>> +	/* Clean and Invalidate L1 data cache. */
>> +	bl	v7_flush_dcache_louis
> Curious question - once we have flushed and invalidated L1 on
> skip_secure_l1_clean_op:, we disable SCTLR.C to make all accesses SO,
> what is the need to go through clean and invalidate again? is'nt it an
> un-necessary cycle consuming NOP? What kind of data are we cleaning out
> here?
Obviously you haven't read all the old emails internally as well as
externally on this topic. Its needed.

>> +
>> +	/*
>> +	 * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus
>> +	 * preventing the CPU from receiving cache, TLB, or BTB
>> +	 * maintenance operations broadcast by other CPUs in the cluster.
>> +	 */
>> +	mrc	p15, 0, r0, c1, c1, 2		@ Read NSACR data
>> +	tst	r0, #(1 << 18)
>> +	mrcne	p15, 0, r0, c1, c0, 1
>> +	bicne	r0, r0, #(1 << 6)		@ Disable SMP bit
>> +	mcrne	p15, 0, r0, c1, c0, 1
>> +	isb
>> +	dsb
>> +
> when save_state=3, as per the function comment:
>  3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> But we dont flush L2 nonsecure OR secure at this point. results wont be
> pretty.
Subject adds CPU off support only. I have added the comments section in
this patch. I can move that for next patch.

> If we dont want to deal with "3", then should'nt we add an adequate
> handler on entry and remove the code comment claiming we support
> it?
> is'nt it better to squash in "[PATCH 11/15] ARM: OMAP5: PM: Add L2
> memory power down support" here?
Why. You don't need L2 support for CPU OFF. As I said I will move the
comment in further patch which seems to confused you. And sure, I will
remove that device OFF reference but still support mode where L2
can be destroyed. It can be done in MPU OSWR as well with a setting
to loose L2.

>> +do_wfi:
>> +	bl	omap_do_wfi
>> +
>> +	/*
>> +	 * CPU is here when it failed to enter OFF/DORMANT or
>> +	 * no low power state was attempted.
> This might need a bit more clarity IMHO. successful WFI (which is
> arguably an power state if we consider ARM internal clock gating takes
> place), will reach here as well. So would OMAP CPU INA state. The
> comment is probably valid for the defined save_states in code comments
> for CPU OFF which is un-successful.
>> +	 */
>> +	mrc	p15, 0, r0, c1, c0, 0
>> +	tst	r0, #(1 << 2)			@ Check C bit enabled?
>> +	orreq	r0, r0, #(1 << 2)		@ Enable the C bit
>> +	mcreq	p15, 0, r0, c1, c0, 0
>> +	isb
>> +	mrc	p15, 0, r0, c1, c0, 1
>> +	tst	r0, #(1 << 6)			@ Check SMP bit enabled?
>> +	orreq	r0, r0, #(1 << 6)
>> +	mcreq	p15, 0, r0, c1, c0, 1
>> +	isb
>> +	dsb
>> +	ldmfd	sp!, {r4-r12, pc}
>> +ENDPROC(omap5_finish_suspend)
>>  #endif
>>  
>>  #ifndef CONFIG_OMAP4_ERRATA_I688
> 
> I was curious at this point -> given that we added documentation that
> we will be able to go to CPU OFF here, but I did not see an resume
> handler registered. Untill I looked down in the series to see:
>
I should have mentioned abou CPU OFF in hotplug path which doesn't
need resume entry. Will update commit message accordingly. Thanks
for comments.

regards
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 09/15] ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method
  2013-03-01 21:53     ` Nishanth Menon
@ 2013-03-02  6:16       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:16 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Saturday 02 March 2013 03:23 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> While waking up CPU from off state using clock domain force wakeup, restore
>> the CPU power state to ON state before putting CPU clock domain under
>> hardware control. Otherwise CPU wakeup might fail. The change is recommended\
> the trailing \ was unintentional I suppose.
Yes.. 
>> for all OMAP4+ devices though the PRCM weakness was observed on OMAP5
>> devices first.
>>
>> So update the code accordingly.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
[..]
> Otherwise:
> Acked-by: Nishanth Menon <nm@ti.com>
> 
Thanks

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 09/15] ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method
@ 2013-03-02  6:16       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 March 2013 03:23 AM, Nishanth Menon wrote:
> On 17:40-20130301, Santosh Shilimkar wrote:
>> While waking up CPU from off state using clock domain force wakeup, restore
>> the CPU power state to ON state before putting CPU clock domain under
>> hardware control. Otherwise CPU wakeup might fail. The change is recommended\
> the trailing \ was unintentional I suppose.
Yes.. 
>> for all OMAP4+ devices though the PRCM weakness was observed on OMAP5
>> devices first.
>>
>> So update the code accordingly.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
[..]
> Otherwise:
> Acked-by: Nishanth Menon <nm@ti.com>
> 
Thanks

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support
  2013-03-01 23:43     ` Nishanth Menon
@ 2013-03-02  6:24       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:24 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Saturday 02 March 2013 05:13 AM, Nishanth Menon wrote:
> On 17:41-20130301, Santosh Shilimkar wrote:
>> When the entire MPUSS cluster is powered down in device off state, L2 cache
>> memory looses it's content and hence while targetting such a state,
>> l2 cache needs to be flushed to main memory.
>>
>> Add the necessary low power code support for the same.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap-secure.h     |    1 +
>>  arch/arm/mach-omap2/sleep_omap4plus.S |   30 ++++++++++++++++++++++++++++++
>>  2 files changed, 31 insertions(+)
>>
>> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
>> index 1739468..a171a5a 100644
>> --- a/arch/arm/mach-omap2/omap-secure.h
>> +++ b/arch/arm/mach-omap2/omap-secure.h
>> @@ -47,6 +47,7 @@
>>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>>  #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
>>  #define OMAP5_MON_AUX_CTRL_INDEX	0x107
>> +#define OMAP5_MON_L2AUX_CTRL_INDEX	0x104
>>  
>>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
>>  
>> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
>> index f4874e5..ea318be 100644
>> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
>> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
>> @@ -386,6 +386,27 @@ skip_secure_l1_clean_op:
>>  	isb
>>  	dsb
>>  
>> +	bl	omap4_get_sar_ram_base
>> +	mov	r8, r0
>> +	mrc	p15, 0, r5, c0, c0, 5		@ Read MPIDR
>> +	ands	r5, r5, #0x0f
>> +	ldreq	r0, [r8, #L2X0_SAVE_OFFSET0]	@ Retrieve L2 state
>> +	ldrne	r0, [r8, #L2X0_SAVE_OFFSET1]
>> +	cmp	r0, #3
> umm, we store l2x0_pwrst_prepare(cpu, save_state);
> which in turn stores into L2X0_SAVE_OFFSET - I am with you so far
> save_state in omap4_enter_lowpower is:
> PWRDM_POWER_INACTIVE: 0
> PWRDM_POWER_OFF: 1
> or 2 in the case of OSWR
> what is 3? ref:
> https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-mpuss-lowpower.c#L298
This was obviosly for the case where L2 can be destroyed. As I said it can happen
with MPU OSWR + L2 OFF setting or device OFF. 

>> +	bne	do_wfi
>> +	bl	omap4_get_sar_ram_base
>> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
>> +	cmp	r9, #0x1			@ Check for HS device
> my 2c:
> off topic: somewhere down the line, I think we need to clear up these
> into macros so that as in this case, omap4_mpuss_init populated value
> should be the same as here with usage of same macro without reviewer
> needing to track down where it was set with what.
>
Patches welcome :)

 
>> +	bne	skip_secure_l2_clean_op
>> +	mov	r0, #1				@ Clean secure L2
>> +	stmfd   r13!, {r4-r12, r14}
>> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
>> +	DO_SMC
>> +	ldmfd   r13!, {r4-r12, r14}
>> +skip_secure_l2_clean_op:
>> +	mov	r0, #2				@ Flush L2
> v7_flush_dcache_all does not take parameters, right?
>> +	bl	v7_flush_dcache_all
>> +
>>  do_wfi:
>>  	bl	omap_do_wfi
>>  
>> @@ -427,6 +448,15 @@ ENTRY(omap5_cpu_resume)
>>  	dsb
>>  1:
>>  #endif
>> +	mrc	p15, 1, r0, c15, c0, 0		@ Read L2 ACTLR
>> +	cmp	r0, #0x118			@ Check if it is already set
> 
>> 	beq	skip_sec_l2
>> +	ldr	r0, =0x118			@ Setup L2 ACTLR = 0x118
>> +	ldr	r12, =OMAP5_MON_L2AUX_CTRL_INDEX
> I hope I am looking at the right place:
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0438g/BABIAICD.html
It is correct.

> 
> Is'nt it better to configure on boot, save it into SAR memory and restore it
> from SAR using monitor call? I mean it is possible that we start boot
> with L2 ACTLR != 0x118 and then hit off and come out of OFF mode with
> 0x118.
No need because it is more of re-initing the value rather than save/restore.
I should have used macro instead of value though.

btw. I might drop this special setting based on some experiments am doing
with benchmarks. Either case, if I keep the L2AUX code, I will use
a macro.

Regards
Santosh



^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support
@ 2013-03-02  6:24       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 March 2013 05:13 AM, Nishanth Menon wrote:
> On 17:41-20130301, Santosh Shilimkar wrote:
>> When the entire MPUSS cluster is powered down in device off state, L2 cache
>> memory looses it's content and hence while targetting such a state,
>> l2 cache needs to be flushed to main memory.
>>
>> Add the necessary low power code support for the same.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/omap-secure.h     |    1 +
>>  arch/arm/mach-omap2/sleep_omap4plus.S |   30 ++++++++++++++++++++++++++++++
>>  2 files changed, 31 insertions(+)
>>
>> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
>> index 1739468..a171a5a 100644
>> --- a/arch/arm/mach-omap2/omap-secure.h
>> +++ b/arch/arm/mach-omap2/omap-secure.h
>> @@ -47,6 +47,7 @@
>>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
>>  #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
>>  #define OMAP5_MON_AUX_CTRL_INDEX	0x107
>> +#define OMAP5_MON_L2AUX_CTRL_INDEX	0x104
>>  
>>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
>>  
>> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
>> index f4874e5..ea318be 100644
>> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
>> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
>> @@ -386,6 +386,27 @@ skip_secure_l1_clean_op:
>>  	isb
>>  	dsb
>>  
>> +	bl	omap4_get_sar_ram_base
>> +	mov	r8, r0
>> +	mrc	p15, 0, r5, c0, c0, 5		@ Read MPIDR
>> +	ands	r5, r5, #0x0f
>> +	ldreq	r0, [r8, #L2X0_SAVE_OFFSET0]	@ Retrieve L2 state
>> +	ldrne	r0, [r8, #L2X0_SAVE_OFFSET1]
>> +	cmp	r0, #3
> umm, we store l2x0_pwrst_prepare(cpu, save_state);
> which in turn stores into L2X0_SAVE_OFFSET - I am with you so far
> save_state in omap4_enter_lowpower is:
> PWRDM_POWER_INACTIVE: 0
> PWRDM_POWER_OFF: 1
> or 2 in the case of OSWR
> what is 3? ref:
> https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-mpuss-lowpower.c#L298
This was obviosly for the case where L2 can be destroyed. As I said it can happen
with MPU OSWR + L2 OFF setting or device OFF. 

>> +	bne	do_wfi
>> +	bl	omap4_get_sar_ram_base
>> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
>> +	cmp	r9, #0x1			@ Check for HS device
> my 2c:
> off topic: somewhere down the line, I think we need to clear up these
> into macros so that as in this case, omap4_mpuss_init populated value
> should be the same as here with usage of same macro without reviewer
> needing to track down where it was set with what.
>
Patches welcome :)

 
>> +	bne	skip_secure_l2_clean_op
>> +	mov	r0, #1				@ Clean secure L2
>> +	stmfd   r13!, {r4-r12, r14}
>> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
>> +	DO_SMC
>> +	ldmfd   r13!, {r4-r12, r14}
>> +skip_secure_l2_clean_op:
>> +	mov	r0, #2				@ Flush L2
> v7_flush_dcache_all does not take parameters, right?
>> +	bl	v7_flush_dcache_all
>> +
>>  do_wfi:
>>  	bl	omap_do_wfi
>>  
>> @@ -427,6 +448,15 @@ ENTRY(omap5_cpu_resume)
>>  	dsb
>>  1:
>>  #endif
>> +	mrc	p15, 1, r0, c15, c0, 0		@ Read L2 ACTLR
>> +	cmp	r0, #0x118			@ Check if it is already set
> 
>> 	beq	skip_sec_l2
>> +	ldr	r0, =0x118			@ Setup L2 ACTLR = 0x118
>> +	ldr	r12, =OMAP5_MON_L2AUX_CTRL_INDEX
> I hope I am looking at the right place:
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0438g/BABIAICD.html
It is correct.

> 
> Is'nt it better to configure on boot, save it into SAR memory and restore it
> from SAR using monitor call? I mean it is possible that we start boot
> with L2 ACTLR != 0x118 and then hit off and come out of OFF mode with
> 0x118.
No need because it is more of re-initing the value rather than save/restore.
I should have used macro instead of value though.

btw. I might drop this special setting based on some experiments am doing
with benchmarks. Either case, if I keep the L2AUX code, I will use
a macro.

Regards
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 12/15] ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support
  2013-03-01 23:56     ` Nishanth Menon
@ 2013-03-02  6:25       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:25 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Saturday 02 March 2013 05:26 AM, Nishanth Menon wrote:
> On 17:41-20130301, Santosh Shilimkar wrote:
>> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
>> index 9de47a7..df81243 100644
>> --- a/arch/arm/mach-omap2/cpuidle44xx.c
>> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
> [...]
>> @@ -234,11 +237,12 @@ int __init omap4_idle_init(void)
>>  	on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
>>  
>>  	for_each_cpu(cpu_id, cpu_online_mask) {
>> -		dev = &per_cpu(omap4_idle_dev, cpu_id);
>> +		dev = &per_cpu(omap_idle_dev, cpu_id);
>>  		dev->cpu = cpu_id;
>>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
>>  		dev->coupled_cpus = *cpu_online_mask;
>>  #endif
>> +		state_ptr = &omap4_idle_data[0];
> minor:
> why initialize it twice (cpu0 and cpu1) to the same pointer in each of
> the for_each_cpu loop? you could move it maybe just before the loop?
Good point 
>>  		cpuidle_register_driver(&omap4_idle_driver);
>>  
>>  		if (cpuidle_register_device(dev)) {
> Otherwise,
> Acked-by: Nishanth Menon <nm@ti.com>
> 
Thanks

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 12/15] ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support
@ 2013-03-02  6:25       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 March 2013 05:26 AM, Nishanth Menon wrote:
> On 17:41-20130301, Santosh Shilimkar wrote:
>> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
>> index 9de47a7..df81243 100644
>> --- a/arch/arm/mach-omap2/cpuidle44xx.c
>> +++ b/arch/arm/mach-omap2/cpuidle44xx.c
> [...]
>> @@ -234,11 +237,12 @@ int __init omap4_idle_init(void)
>>  	on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
>>  
>>  	for_each_cpu(cpu_id, cpu_online_mask) {
>> -		dev = &per_cpu(omap4_idle_dev, cpu_id);
>> +		dev = &per_cpu(omap_idle_dev, cpu_id);
>>  		dev->cpu = cpu_id;
>>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
>>  		dev->coupled_cpus = *cpu_online_mask;
>>  #endif
>> +		state_ptr = &omap4_idle_data[0];
> minor:
> why initialize it twice (cpu0 and cpu1) to the same pointer in each of
> the for_each_cpu loop? you could move it maybe just before the loop?
Good point 
>>  		cpuidle_register_driver(&omap4_idle_driver);
>>  
>>  		if (cpuidle_register_device(dev)) {
> Otherwise,
> Acked-by: Nishanth Menon <nm@ti.com>
> 
Thanks

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support
  2013-03-02  0:25     ` Nishanth Menon
@ 2013-03-02  6:47       ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:47 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Saturday 02 March 2013 05:55 AM, Nishanth Menon wrote:
> On 17:41-20130301, Santosh Shilimkar wrote:
>> The OMAP5 idle driver can re-use OMAP4 CPUidle driver implementation thanks
>> to compatible MPUSS design.
>>
>> Though unlike OMAP4, on OMAP5 devices, MPUSS CSWR (Close Switch Retention)
>> power states can be achieved with respective power states on CPU0 and CPU1
>> power domain. This mode was broken on OMAP4 devices because of hardware
>> limitation. Also there is no CPU low power entry order requirement like
>> master CPU etc for CSWR C-state, which is icing on the cake. Code makes
>> use of voting scheme for cluster low power state to support MPUSS CSWR
>> C-state.
>>
>> Supported OMAP5 CPUidle C-states:
>>         C1 - CPU0 ON(WFI) + CPU1 ON(WFI) + MPUSS ON
>>         C2 - CPU0 CSWR + CPU1 CSWR + MPUSS CSWR
>>         C3 - CPU0 OFF + CPU1 Force OFF + MPUSS OSWR
>  think you meant CPU1 OFF?
Yes.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/Kconfig                        |    1 +
>>  arch/arm/mach-omap2/Makefile                       |    4 +-
>>  .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  103 +++++++++++++++++++-
>>  arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    7 +-
>>  arch/arm/mach-omap2/pm_omap4plus.c                 |    2 +-
>>  5 files changed, 110 insertions(+), 7 deletions(-)
>>  rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (70%)
>>
>> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
>> index 41b581f..2df91dc 100644
>> --- a/arch/arm/mach-omap2/Kconfig
>> +++ b/arch/arm/mach-omap2/Kconfig
>> @@ -82,6 +82,7 @@ config SOC_OMAP5
>>  	select CPU_V7
>>  	select HAVE_SMP
>>  	select COMMON_CLK
>> +	select ARCH_NEEDS_CPU_IDLE_COUPLED
>>  
>>  comment "OMAP Core Type"
>>  	depends on ARCH_OMAP2
>> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
>> index 7c3c6b6..f6ff88f 100644
>> --- a/arch/arm/mach-omap2/Makefile
>> +++ b/arch/arm/mach-omap2/Makefile
>> @@ -97,8 +97,10 @@ endif
>>  endif
>>  
>>  ifeq ($(CONFIG_CPU_IDLE),y)
>> +omap4plus-common-idle			= cpuidle_omap4plus.o
>>  obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
>> -obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
>> +obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-idle)
>> +obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-idle)
> nit pick: simpler to use cpuidle_omap4plus.o or do we expect more objs -
> like moving the idle_data to DTS or so?
No I haven't that on that path. Easy from maintenance point of view. common
object and a label. Thats all.

>>  endif
>>  
>>  # PRCM
>> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle_omap4plus.c
>> similarity index 70%
>> rename from arch/arm/mach-omap2/cpuidle44xx.c
>> rename to arch/arm/mach-omap2/cpuidle_omap4plus.c
>> index 23286c1..8681fa6 100644
>> --- a/arch/arm/mach-omap2/cpuidle44xx.c
>> +++ b/arch/arm/mach-omap2/cpuidle_omap4plus.c
>> @@ -29,6 +29,7 @@ struct idle_statedata {
>>  	u32 cpu_state;
>>  	u32 mpu_logic_state;
>>  	u32 mpu_state;
>> +	u32 mpu_state_vote;
>>  };
>>  
>>  static struct idle_statedata omap4_idle_data[] = {
>> @@ -49,17 +50,36 @@ static struct idle_statedata omap4_idle_data[] = {
>>  	},
>>  };
>>  
>> +static struct idle_statedata omap5_idle_data[] = {
>> +	{
>> +		.cpu_state = PWRDM_POWER_ON,
>> +		.mpu_state = PWRDM_POWER_ON,
>> +		.mpu_logic_state = PWRDM_POWER_RET,
>> +	},
>> +	{
>> +		.cpu_state = PWRDM_POWER_RET,
> CSWR I assume -> Documenting it helps? or we should introdce
> cpu_logic_state to be explicit?
Its is documented just below the table(desc). No need to add useless
cpu_logic_state variable. This is part of the big C-state table.


>
[..]
>>  /*
>>   * For each cpu, setup the broadcast timer because local timers
>>   * stops for the states above C1.
>> @@ -209,6 +262,43 @@ static struct cpuidle_driver omap4_idle_driver = {
>>  	.safe_state_index = 0,
>>  };
>>  
>> +static struct cpuidle_driver omap5_idle_driver = {
>> +	.name				= "omap5_idle",
>> +	.owner				= THIS_MODULE,
>> +	.en_core_tk_irqen		= 1,
>> +	.states = {
>> +		{
>> +			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
> we could move these to .desc
That will be too much ... also above just for refence and understanding
otherwise, CPU state is per CPU so we can't say CPU0 =x, and CPU1 = y in
CPU0 C-state. I like the way .desc is today and would want to keep it that
way.

>> +			.exit_latency = 2 + 2,
>> +			.target_residency = 5,
> the obvious question on how these latencies were arrived at..
Based on the internal measurements done only considering MPUSS
C-state latencies.


>> @@ -243,8 +333,13 @@ int __init omap4_idle_init(void)
>>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
>>  		dev->coupled_cpus = *cpu_online_mask;
>>  #endif
>> -		state_ptr = &omap4_idle_data[0];
>> -		cpuidle_register_driver(&omap4_idle_driver);
>> +		if (cpu_is_omap44xx()) {
>> +			state_ptr = &omap4_idle_data[0];
>> +			cpuidle_register_driver(&omap4_idle_driver);
>> +		} else if (soc_is_omap54xx()) {
>> +			state_ptr = &omap5_idle_data[0];
>> +			cpuidle_register_driver(&omap5_idle_driver);
>> +		}
> we'd be doing cpuidle_register_driver twice since it is within the
> for_each_cpu loop - we dont want to do that.
Yep. I will move that out of the loop though second registration is just
a nop.
>>  
>>  		if (cpuidle_register_device(dev)) {
>>  			pr_err("%s: CPUidle register failed\n", __func__);
>> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> index 5d32444..0ccb76e 100644
>> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> @@ -87,7 +87,7 @@ extern void omap5_cpu_resume(void);
>>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>>  static struct powerdomain *mpuss_pd;
>>  static void __iomem *sar_base;
>> -static u32 cpu_context_offset;
>> +static u32 cpu_context_offset, cpu_cswr_supported;
>>  
>>  static int default_finish_suspend(unsigned long cpu_state)
>>  {
>> @@ -265,6 +265,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>>  		save_state = 1;
>>  		break;
>>  	case PWRDM_POWER_RET:
>> +		if (cpu_cswr_supported) {
>> +			save_state = 0;
>> +			break;
>> +		}
> ok, I guess this is the best we can do under the current circumstance
> where PWRDM_POWER_RET means either CSWR or OSWR!
The switch is for CPUx power states and hence there is no question of
OSWR. CPUx OSWR = CPUx OFF hence CPUx OSWR isn't supported. This has been
known from OMAP4 days. CPU RET isn't supported on OMAP4 and hence
that variable is added.

Regards,
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support
@ 2013-03-02  6:47       ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-02  6:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Saturday 02 March 2013 05:55 AM, Nishanth Menon wrote:
> On 17:41-20130301, Santosh Shilimkar wrote:
>> The OMAP5 idle driver can re-use OMAP4 CPUidle driver implementation thanks
>> to compatible MPUSS design.
>>
>> Though unlike OMAP4, on OMAP5 devices, MPUSS CSWR (Close Switch Retention)
>> power states can be achieved with respective power states on CPU0 and CPU1
>> power domain. This mode was broken on OMAP4 devices because of hardware
>> limitation. Also there is no CPU low power entry order requirement like
>> master CPU etc for CSWR C-state, which is icing on the cake. Code makes
>> use of voting scheme for cluster low power state to support MPUSS CSWR
>> C-state.
>>
>> Supported OMAP5 CPUidle C-states:
>>         C1 - CPU0 ON(WFI) + CPU1 ON(WFI) + MPUSS ON
>>         C2 - CPU0 CSWR + CPU1 CSWR + MPUSS CSWR
>>         C3 - CPU0 OFF + CPU1 Force OFF + MPUSS OSWR
>  think you meant CPU1 OFF?
Yes.
>>
>> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> ---
>>  arch/arm/mach-omap2/Kconfig                        |    1 +
>>  arch/arm/mach-omap2/Makefile                       |    4 +-
>>  .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  103 +++++++++++++++++++-
>>  arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    7 +-
>>  arch/arm/mach-omap2/pm_omap4plus.c                 |    2 +-
>>  5 files changed, 110 insertions(+), 7 deletions(-)
>>  rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (70%)
>>
>> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
>> index 41b581f..2df91dc 100644
>> --- a/arch/arm/mach-omap2/Kconfig
>> +++ b/arch/arm/mach-omap2/Kconfig
>> @@ -82,6 +82,7 @@ config SOC_OMAP5
>>  	select CPU_V7
>>  	select HAVE_SMP
>>  	select COMMON_CLK
>> +	select ARCH_NEEDS_CPU_IDLE_COUPLED
>>  
>>  comment "OMAP Core Type"
>>  	depends on ARCH_OMAP2
>> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
>> index 7c3c6b6..f6ff88f 100644
>> --- a/arch/arm/mach-omap2/Makefile
>> +++ b/arch/arm/mach-omap2/Makefile
>> @@ -97,8 +97,10 @@ endif
>>  endif
>>  
>>  ifeq ($(CONFIG_CPU_IDLE),y)
>> +omap4plus-common-idle			= cpuidle_omap4plus.o
>>  obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
>> -obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
>> +obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-idle)
>> +obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-idle)
> nit pick: simpler to use cpuidle_omap4plus.o or do we expect more objs -
> like moving the idle_data to DTS or so?
No I haven't that on that path. Easy from maintenance point of view. common
object and a label. Thats all.

>>  endif
>>  
>>  # PRCM
>> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle_omap4plus.c
>> similarity index 70%
>> rename from arch/arm/mach-omap2/cpuidle44xx.c
>> rename to arch/arm/mach-omap2/cpuidle_omap4plus.c
>> index 23286c1..8681fa6 100644
>> --- a/arch/arm/mach-omap2/cpuidle44xx.c
>> +++ b/arch/arm/mach-omap2/cpuidle_omap4plus.c
>> @@ -29,6 +29,7 @@ struct idle_statedata {
>>  	u32 cpu_state;
>>  	u32 mpu_logic_state;
>>  	u32 mpu_state;
>> +	u32 mpu_state_vote;
>>  };
>>  
>>  static struct idle_statedata omap4_idle_data[] = {
>> @@ -49,17 +50,36 @@ static struct idle_statedata omap4_idle_data[] = {
>>  	},
>>  };
>>  
>> +static struct idle_statedata omap5_idle_data[] = {
>> +	{
>> +		.cpu_state = PWRDM_POWER_ON,
>> +		.mpu_state = PWRDM_POWER_ON,
>> +		.mpu_logic_state = PWRDM_POWER_RET,
>> +	},
>> +	{
>> +		.cpu_state = PWRDM_POWER_RET,
> CSWR I assume -> Documenting it helps? or we should introdce
> cpu_logic_state to be explicit?
Its is documented just below the table(desc). No need to add useless
cpu_logic_state variable. This is part of the big C-state table.


>
[..]
>>  /*
>>   * For each cpu, setup the broadcast timer because local timers
>>   * stops for the states above C1.
>> @@ -209,6 +262,43 @@ static struct cpuidle_driver omap4_idle_driver = {
>>  	.safe_state_index = 0,
>>  };
>>  
>> +static struct cpuidle_driver omap5_idle_driver = {
>> +	.name				= "omap5_idle",
>> +	.owner				= THIS_MODULE,
>> +	.en_core_tk_irqen		= 1,
>> +	.states = {
>> +		{
>> +			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
> we could move these to .desc
That will be too much ... also above just for refence and understanding
otherwise, CPU state is per CPU so we can't say CPU0 =x, and CPU1 = y in
CPU0 C-state. I like the way .desc is today and would want to keep it that
way.

>> +			.exit_latency = 2 + 2,
>> +			.target_residency = 5,
> the obvious question on how these latencies were arrived at..
Based on the internal measurements done only considering MPUSS
C-state latencies.


>> @@ -243,8 +333,13 @@ int __init omap4_idle_init(void)
>>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
>>  		dev->coupled_cpus = *cpu_online_mask;
>>  #endif
>> -		state_ptr = &omap4_idle_data[0];
>> -		cpuidle_register_driver(&omap4_idle_driver);
>> +		if (cpu_is_omap44xx()) {
>> +			state_ptr = &omap4_idle_data[0];
>> +			cpuidle_register_driver(&omap4_idle_driver);
>> +		} else if (soc_is_omap54xx()) {
>> +			state_ptr = &omap5_idle_data[0];
>> +			cpuidle_register_driver(&omap5_idle_driver);
>> +		}
> we'd be doing cpuidle_register_driver twice since it is within the
> for_each_cpu loop - we dont want to do that.
Yep. I will move that out of the loop though second registration is just
a nop.
>>  
>>  		if (cpuidle_register_device(dev)) {
>>  			pr_err("%s: CPUidle register failed\n", __func__);
>> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> index 5d32444..0ccb76e 100644
>> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
>> @@ -87,7 +87,7 @@ extern void omap5_cpu_resume(void);
>>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
>>  static struct powerdomain *mpuss_pd;
>>  static void __iomem *sar_base;
>> -static u32 cpu_context_offset;
>> +static u32 cpu_context_offset, cpu_cswr_supported;
>>  
>>  static int default_finish_suspend(unsigned long cpu_state)
>>  {
>> @@ -265,6 +265,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
>>  		save_state = 1;
>>  		break;
>>  	case PWRDM_POWER_RET:
>> +		if (cpu_cswr_supported) {
>> +			save_state = 0;
>> +			break;
>> +		}
> ok, I guess this is the best we can do under the current circumstance
> where PWRDM_POWER_RET means either CSWR or OSWR!
The switch is for CPUx power states and hence there is no question of
OSWR. CPUx OSWR = CPUx OFF hence CPUx OSWR isn't supported. This has been
known from OMAP4 days. CPU RET isn't supported on OMAP4 and hence
that variable is added.

Regards,
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
  2013-03-02  5:43       ` Santosh Shilimkar
@ 2013-03-04 18:21         ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:21 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 11:13-20130302, Santosh Shilimkar wrote:
> On Friday 01 March 2013 11:13 PM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm_omap4plus.c
> >> similarity index 74%
[..]
> >>  	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");
> >> +	l4wkup = clkdm_lookup("l4_wkup_clkdm");
> > These static dependencies now seems added for OMAP4?
> > Sounds like a separate patch as it is not exactly what $subject claims.
> >>  	ducati_clkdm = clkdm_lookup("ducati_clkdm");
> These are accidently added. I have removed these two in another series.
> Will remove this one from the patch.
Thanks.
> 
> >> -	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
> >> -		(!l3_2_clkdm) || (!ducati_clkdm))
> >> -		goto err2;
> >> +	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
> >> +		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
> >> +		return -EINVAL;
> >>  
> >>  	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(mpuss_clkdm, l4wkup);
> >>  	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");
> >> +	}
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +/**
> >> + * omap4_pm_init - Init routine for OMAP4+ devices
> >> + *
> >> + * Initializes all powerdomain and clockdomain target states
> >> + * and all PRCM settings.
> >> + */
> >> +int __init omap4_pm_init(void)
> > could we rename it as omap4plus_pm_init while we are at it?
> > This will help differentiate at least functions which are omap4 only and
> > ones which we reuse for omap4plus?
> Not needed. That way we have to rename all our omap2_* varients to
> omap2plus. omap4_* is assumed to be omap4 and onwards just like
> omap2_*
hmm true.. :(
> 
> >> +{
> >> +	int ret;
> >> +
> >> +	if (omap_rev() == OMAP4430_REV_ES1_0) {
> > we have ID detection for OMAP5430_REV_ES1_0 in arch/arm/mach-omap2/id.c
> > However, we do not support PM, so might as well use it to skip init?
> Well the plan is to remove OMAP5 ES1.0 completely so no need to add
> more checks. As already mentioned ES1.0 is not going to be supported
> in mainline kernel.
OK.
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5
@ 2013-03-04 18:21         ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 11:13-20130302, Santosh Shilimkar wrote:
> On Friday 01 March 2013 11:13 PM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm_omap4plus.c
> >> similarity index 74%
[..]
> >>  	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");
> >> +	l4wkup = clkdm_lookup("l4_wkup_clkdm");
> > These static dependencies now seems added for OMAP4?
> > Sounds like a separate patch as it is not exactly what $subject claims.
> >>  	ducati_clkdm = clkdm_lookup("ducati_clkdm");
> These are accidently added. I have removed these two in another series.
> Will remove this one from the patch.
Thanks.
> 
> >> -	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) ||
> >> -		(!l3_2_clkdm) || (!ducati_clkdm))
> >> -		goto err2;
> >> +	if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || (!l4wkup) ||
> >> +		(!l3_2_clkdm) || (!ducati_clkdm) || (!l4_per_clkdm))
> >> +		return -EINVAL;
> >>  
> >>  	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(mpuss_clkdm, l4wkup);
> >>  	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");
> >> +	}
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +/**
> >> + * omap4_pm_init - Init routine for OMAP4+ devices
> >> + *
> >> + * Initializes all powerdomain and clockdomain target states
> >> + * and all PRCM settings.
> >> + */
> >> +int __init omap4_pm_init(void)
> > could we rename it as omap4plus_pm_init while we are at it?
> > This will help differentiate at least functions which are omap4 only and
> > ones which we reuse for omap4plus?
> Not needed. That way we have to rename all our omap2_* varients to
> omap2plus. omap4_* is assumed to be omap4 and onwards just like
> omap2_*
hmm true.. :(
> 
> >> +{
> >> +	int ret;
> >> +
> >> +	if (omap_rev() == OMAP4430_REV_ES1_0) {
> > we have ID detection for OMAP5430_REV_ES1_0 in arch/arm/mach-omap2/id.c
> > However, we do not support PM, so might as well use it to skip init?
> Well the plan is to remove OMAP5 ES1.0 completely so no need to add
> more checks. As already mentioned ES1.0 is not going to be supported
> in mainline kernel.
OK.
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
  2013-03-02  5:47       ` Santosh Shilimkar
@ 2013-03-04 18:29         ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:29 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 11:17-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 01:07 AM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> Enables MPUSS ES2 power management mode using ES2_PM_MODE in
> >> AMBA_IF_MODE register.
> >>
> >> 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. Broken
> >> 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode independently.
> >>
> >> This is one time settings thanks to always ON domain.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap-secure.h    |    2 ++
> >>  arch/arm/mach-omap2/omap-wakeupgen.c |   14 ++++++++++++++
> >>  arch/arm/mach-omap2/omap-wakeupgen.h |    1 +
> >>  3 files changed, 17 insertions(+)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> >> index 0e72917..82b3c4c 100644
> >> --- a/arch/arm/mach-omap2/omap-secure.h
> >> +++ b/arch/arm/mach-omap2/omap-secure.h
> >> @@ -42,6 +42,8 @@
> >>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
> >>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
> >>  
> >> +#define OMAP5_MON_AMBA_IF_INDEX		0x108
> >> +
> >>  /* Secure PPA(Primary Protected Application) APIs */
> >>  #define OMAP4_PPA_L2_POR_INDEX		0x23
> >>  #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
> >> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
> >> index 5d3b4f4..a7350dd 100644
> >> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
> >> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
> >> @@ -403,6 +403,7 @@ int __init omap_wakeupgen_init(void)
> >>  {
> >>  	int i;
> >>  	unsigned int boot_cpu = smp_processor_id();
> >> +	u32 val;
> >>  
> >>  	/* Not supported on OMAP4 ES1.0 silicon */
> >>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
> >> @@ -444,6 +445,19 @@ int __init omap_wakeupgen_init(void)
> >>  	for (i = 0; i < max_irqs; i++)
> >>  		irq_target_cpu[i] = boot_cpu;
> >>  
> >> +	/*
> >> +	 * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
> >> +	 * 0x0:	ES1 behavior, CPU cores would enter and exit OFF mode together.
> >> +	 * 0x1:	ES2 behavior, CPU cores are allowed to enter/exit OFF mode
> >> +	 * independently.
> >> +	 * This needs to be set one time thanks to always ON domain.
> >> +	 */
> >> +	if (soc_is_omap54xx()) {
> >> +		val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
> >> +		val |= BIT(5);
> > BIT(5) is ES2_PM_MODE for es2.0 only - we dont have a OMAP5 revision check atm.
> > maybe 
OK on ES1.0 bit from previous discussion. I still suggest having a macro for
BIT(5) instead of having to review TRM to ensure this is right.
> >> +		omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
> >> +	}
> >> +
> >>  	irq_hotplug_init();
> >>  	irq_pm_init();
> >>  
> >> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
> >> index b0fd16f..b3c8ecc 100644
> >> --- a/arch/arm/mach-omap2/omap-wakeupgen.h
> >> +++ b/arch/arm/mach-omap2/omap-wakeupgen.h
> >> @@ -27,6 +27,7 @@
> >>  #define OMAP_WKG_ENB_E_1			0x420
> >>  #define OMAP_AUX_CORE_BOOT_0			0x800
> >>  #define OMAP_AUX_CORE_BOOT_1			0x804
> >> +#define OMAP_AMBA_IF_MODE			0x80c
> >>  #define OMAP_PTMSYNCREQ_MASK			0xc00
> >>  #define OMAP_PTMSYNCREQ_EN			0xc04
> >>  #define OMAP_TIMESTAMPCYCLELO			0xc08
> > 
> > Curious, I see OMAP5_AMBA_IF_MODE_OFFSET in
> > arch/arm/mach-omap2/omap4-sar-layout.h
> > if we dont save new modified contents there, Wont restore logic just
> > reset it back to 0?
> > 
> It is already restored in the wakeup-gen restore code.
I apologize, I do not see it in:
https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-wakeupgen.c
I might have expected an save of val to sar offset to ensure this is
done, but since you indicate this is in wakeupgen restore logic, which I
presume is done by ROM, we might expect an write to sar_base +
OMAP5_AMBA_IF_MODE_OFFSET with the val for it to function?

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
@ 2013-03-04 18:29         ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 11:17-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 01:07 AM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> Enables MPUSS ES2 power management mode using ES2_PM_MODE in
> >> AMBA_IF_MODE register.
> >>
> >> 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together. Broken
> >> 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode independently.
> >>
> >> This is one time settings thanks to always ON domain.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap-secure.h    |    2 ++
> >>  arch/arm/mach-omap2/omap-wakeupgen.c |   14 ++++++++++++++
> >>  arch/arm/mach-omap2/omap-wakeupgen.h |    1 +
> >>  3 files changed, 17 insertions(+)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> >> index 0e72917..82b3c4c 100644
> >> --- a/arch/arm/mach-omap2/omap-secure.h
> >> +++ b/arch/arm/mach-omap2/omap-secure.h
> >> @@ -42,6 +42,8 @@
> >>  #define OMAP4_MON_L2X0_AUXCTRL_INDEX	0x109
> >>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
> >>  
> >> +#define OMAP5_MON_AMBA_IF_INDEX		0x108
> >> +
> >>  /* Secure PPA(Primary Protected Application) APIs */
> >>  #define OMAP4_PPA_L2_POR_INDEX		0x23
> >>  #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX	0x25
> >> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c
> >> index 5d3b4f4..a7350dd 100644
> >> --- a/arch/arm/mach-omap2/omap-wakeupgen.c
> >> +++ b/arch/arm/mach-omap2/omap-wakeupgen.c
> >> @@ -403,6 +403,7 @@ int __init omap_wakeupgen_init(void)
> >>  {
> >>  	int i;
> >>  	unsigned int boot_cpu = smp_processor_id();
> >> +	u32 val;
> >>  
> >>  	/* Not supported on OMAP4 ES1.0 silicon */
> >>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
> >> @@ -444,6 +445,19 @@ int __init omap_wakeupgen_init(void)
> >>  	for (i = 0; i < max_irqs; i++)
> >>  		irq_target_cpu[i] = boot_cpu;
> >>  
> >> +	/*
> >> +	 * Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
> >> +	 * 0x0:	ES1 behavior, CPU cores would enter and exit OFF mode together.
> >> +	 * 0x1:	ES2 behavior, CPU cores are allowed to enter/exit OFF mode
> >> +	 * independently.
> >> +	 * This needs to be set one time thanks to always ON domain.
> >> +	 */
> >> +	if (soc_is_omap54xx()) {
> >> +		val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
> >> +		val |= BIT(5);
> > BIT(5) is ES2_PM_MODE for es2.0 only - we dont have a OMAP5 revision check atm.
> > maybe 
OK on ES1.0 bit from previous discussion. I still suggest having a macro for
BIT(5) instead of having to review TRM to ensure this is right.
> >> +		omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
> >> +	}
> >> +
> >>  	irq_hotplug_init();
> >>  	irq_pm_init();
> >>  
> >> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
> >> index b0fd16f..b3c8ecc 100644
> >> --- a/arch/arm/mach-omap2/omap-wakeupgen.h
> >> +++ b/arch/arm/mach-omap2/omap-wakeupgen.h
> >> @@ -27,6 +27,7 @@
> >>  #define OMAP_WKG_ENB_E_1			0x420
> >>  #define OMAP_AUX_CORE_BOOT_0			0x800
> >>  #define OMAP_AUX_CORE_BOOT_1			0x804
> >> +#define OMAP_AMBA_IF_MODE			0x80c
> >>  #define OMAP_PTMSYNCREQ_MASK			0xc00
> >>  #define OMAP_PTMSYNCREQ_EN			0xc04
> >>  #define OMAP_TIMESTAMPCYCLELO			0xc08
> > 
> > Curious, I see OMAP5_AMBA_IF_MODE_OFFSET in
> > arch/arm/mach-omap2/omap4-sar-layout.h
> > if we dont save new modified contents there, Wont restore logic just
> > reset it back to 0?
> > 
> It is already restored in the wakeup-gen restore code.
I apologize, I do not see it in:
https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-wakeupgen.c
I might have expected an save of val to sar offset to ensure this is
done, but since you indicate this is in wakeupgen restore logic, which I
presume is done by ROM, we might expect an write to sar_base +
OMAP5_AMBA_IF_MODE_OFFSET with the val for it to function?

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
  2013-03-02  5:52       ` Santosh Shilimkar
@ 2013-03-04 18:33         ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:33 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 11:22-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 01:12 AM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> In addition to the standard power-management technique, the OMAP5
> >> MPU subsystem also employs an SR3-APG (mercury) power management
> >> technology to reduce leakage.
> > Mercury fast is employed here - might be good to note that.
> Slow is completly descoped from validation and only supported mode
> is mercury fast which was the intention. So lets not add any confusion
> since other state isn't supported. 
understood and agreed.

> >>
> >> It allows for full logic and memories retention on MPU_C0 and MPU_C1 and
> >> is controlled by the PRCM_MPU.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   17 +++++++++++++++++
> >>  1 file changed, 17 insertions(+)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> index bcd2efb..9fda96b 100644
> >> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> @@ -360,6 +360,20 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> >>  
> >>  
> >>  /*
> >> + * Enable Mercury Fast HG retention mode by default.
> >> + */
> >> +static void enable_mercury_retention_mode(void)
> >> +{
> >> +	u32 reg;
> >> +
> >> +	reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
> >> +			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
> >> +	reg |= BIT(24) | BIT(25);
> > Can we please use macros here?
> > we are setting BIT(25) - fast ramp-up (Mercury fast) Vs 0 (which would
> > have been mercury slow)
> > BIT(24) is mercury enable basically. OMAP4 prm-regbits-44xx.h did not
> > have these ofcourse, so might be a different bit file or so?
> As already commented above, only mode supported is mercury fast and
> hence to avoid any further confusion, i have used bit fields.
> In short, to enable the mercury on O5, both bits needs to be set.
> And to avoid any fast/slow confusion, I haven't used macro's.
I see the usage as a slightly better version of:
reg |= 0x3000000
shrug.. Register bit define is slightly better from review perspective.
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains
@ 2013-03-04 18:33         ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:33 UTC (permalink / raw)
  To: linux-arm-kernel

On 11:22-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 01:12 AM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> In addition to the standard power-management technique, the OMAP5
> >> MPU subsystem also employs an SR3-APG (mercury) power management
> >> technology to reduce leakage.
> > Mercury fast is employed here - might be good to note that.
> Slow is completly descoped from validation and only supported mode
> is mercury fast which was the intention. So lets not add any confusion
> since other state isn't supported. 
understood and agreed.

> >>
> >> It allows for full logic and memories retention on MPU_C0 and MPU_C1 and
> >> is controlled by the PRCM_MPU.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   17 +++++++++++++++++
> >>  1 file changed, 17 insertions(+)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> index bcd2efb..9fda96b 100644
> >> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> @@ -360,6 +360,20 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> >>  
> >>  
> >>  /*
> >> + * Enable Mercury Fast HG retention mode by default.
> >> + */
> >> +static void enable_mercury_retention_mode(void)
> >> +{
> >> +	u32 reg;
> >> +
> >> +	reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
> >> +			OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
> >> +	reg |= BIT(24) | BIT(25);
> > Can we please use macros here?
> > we are setting BIT(25) - fast ramp-up (Mercury fast) Vs 0 (which would
> > have been mercury slow)
> > BIT(24) is mercury enable basically. OMAP4 prm-regbits-44xx.h did not
> > have these ofcourse, so might be a different bit file or so?
> As already commented above, only mode supported is mercury fast and
> hence to avoid any further confusion, i have used bit fields.
> In short, to enable the mercury on O5, both bits needs to be set.
> And to avoid any fast/slow confusion, I haven't used macro's.
I see the usage as a slightly better version of:
reg |= 0x3000000
shrug.. Register bit define is slightly better from review perspective.
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization
  2013-03-02  6:00       ` Santosh Shilimkar
@ 2013-03-04 18:35         ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:35 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 11:30-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 01:42 AM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
> >> index 2c3fdd6..e6ba596 100644
> >> --- a/arch/arm/mach-omap2/io.c
> >> +++ b/arch/arm/mach-omap2/io.c
> >> @@ -620,6 +620,14 @@ void __init omap5_init_early(void)
> >>  	omap_cm_base_init();
> >>  	omap5xxx_check_revision();
> >>  }
> >> +
> >> +void __init omap5_init_late(void)
> >> +{
> >> +	omap_mux_late_init();
> >> +	omap2_common_pm_late_init();
> >> +	omap4_pm_init();
> > as part of init sequence, we'd late_initcall *after* module_inits,
> > implying probes of drivers will be called (for built-in drivers) prior
> > to PM getting ready.
> > 
> > This basically makes key features like dvfs not available for drivers until
> > late_init is complete.
> > 
> > We have faced tons of problems in the past with this approach, cant we
> > improve this? One solution(we used in Android kernel fork) might be to
> > ensure all core framework initialized before module_init either in
> > arch_init or subsys_init. I am aware that machine_desc does not provide us
> > that flexibility - should'nt we rather extend it for the same instead of
> > having to go through the same pain all over again?
> > 
> I have seen those tons of internal patches as well :)
> The point is, there is nothing at the moment in mainline code breaks
> with this init sequence so it just fine.
> 
> You might have valid point but it is more of generic init sequence
> for all PM code. Since you are aware of all the needs, I suggest
> you to address that in another series so that all devices gets
> addressed. Looking at current mainline supported code and the scope
> of PM, I suspect there is any issue.
:( Sigh.. We will eventually need to fix this up (aka will need tons of
patches eventually). But this patch is inline with the existing usage,
so no complaints on this one.
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization
@ 2013-03-04 18:35         ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 11:30-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 01:42 AM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
> >> index 2c3fdd6..e6ba596 100644
> >> --- a/arch/arm/mach-omap2/io.c
> >> +++ b/arch/arm/mach-omap2/io.c
> >> @@ -620,6 +620,14 @@ void __init omap5_init_early(void)
> >>  	omap_cm_base_init();
> >>  	omap5xxx_check_revision();
> >>  }
> >> +
> >> +void __init omap5_init_late(void)
> >> +{
> >> +	omap_mux_late_init();
> >> +	omap2_common_pm_late_init();
> >> +	omap4_pm_init();
> > as part of init sequence, we'd late_initcall *after* module_inits,
> > implying probes of drivers will be called (for built-in drivers) prior
> > to PM getting ready.
> > 
> > This basically makes key features like dvfs not available for drivers until
> > late_init is complete.
> > 
> > We have faced tons of problems in the past with this approach, cant we
> > improve this? One solution(we used in Android kernel fork) might be to
> > ensure all core framework initialized before module_init either in
> > arch_init or subsys_init. I am aware that machine_desc does not provide us
> > that flexibility - should'nt we rather extend it for the same instead of
> > having to go through the same pain all over again?
> > 
> I have seen those tons of internal patches as well :)
> The point is, there is nothing at the moment in mainline code breaks
> with this init sequence so it just fine.
> 
> You might have valid point but it is more of generic init sequence
> for all PM code. Since you are aware of all the needs, I suggest
> you to address that in another series so that all devices gets
> addressed. Looking at current mainline supported code and the scope
> of PM, I suspect there is any issue.
:( Sigh.. We will eventually need to fix this up (aka will need tons of
patches eventually). But this patch is inline with the existing usage,
so no complaints on this one.
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support
  2013-03-02  6:14       ` Santosh Shilimkar
@ 2013-03-04 18:38         ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:38 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 11:44-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 03:06 AM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> Add power management code to handle the CPU off mode. Separate
> >> suspend finisher is used for OMAP5(Cortex-A15) because it doesn't
> >> use SCU power status register and external PL310 L2 cache which makes
> >> code flow bit different.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   31 +++++++----
> >>  arch/arm/mach-omap2/omap-secure.h         |    1 +
> >>  arch/arm/mach-omap2/omap4-sar-layout.h    |    2 +
> >>  arch/arm/mach-omap2/sleep_omap4plus.S     |   80 +++++++++++++++++++++++++++++
> >>  4 files changed, 104 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> index 9fda96b..275f9a4 100644
> >> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> @@ -76,10 +76,12 @@ struct cpu_pm_ops {
> >>  	int (*finish_suspend)(unsigned long cpu_state);
> >>  	void (*resume)(void);
> >>  	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
> >> +	void (*hotplug_restart)(void);
> >>  };
> >>  
> >>  extern int omap4_finish_suspend(unsigned long cpu_state);
> >>  extern void omap4_cpu_resume(void);
> >> +extern int omap5_finish_suspend(unsigned long cpu_state);
> >>  
> >>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
> >>  static struct powerdomain *mpuss_pd;
> >> @@ -102,6 +104,7 @@ struct cpu_pm_ops omap_pm_ops = {
> >>  	.finish_suspend		= default_finish_suspend,
> >>  	.resume			= dummy_cpu_resume,
> >>  	.scu_prepare		= dummy_scu_prepare,
> >> +	.hotplug_restart	= dummy_cpu_resume,
> >>  };
> >>  
> >>  /*
> >> @@ -334,7 +337,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >>  int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> >>  {
> >>  	unsigned int cpu_state = 0;
> >> -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
> >>  
> >>  	if (omap_rev() == OMAP4430_REV_ES1_0)
> >>  		return -ENXIO;
> >> @@ -344,7 +346,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> >>  
> >>  	clear_cpu_prev_pwrst(cpu);
> >>  	set_cpu_next_pwrst(cpu, power_state);
> >> -	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
> >> +	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
> >>  	omap_pm_ops.scu_prepare(cpu, power_state);
> >>  
> >>  	/*
> >> @@ -379,6 +381,7 @@ static void enable_mercury_retention_mode(void)
> >>  int __init omap4_mpuss_init(void)
> >>  {
> >>  	struct omap4_cpu_pm_info *pm_info;
> >> +	u32 cpu_wakeup_addr = 0;
> >>  
> >>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
> >>  		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
> >> @@ -388,9 +391,13 @@ int __init omap4_mpuss_init(void)
> >>  	sar_base = omap4_get_sar_ram_base();
> >>  
> >>  	/* Initilaise per CPU PM information */
> >> +	if (cpu_is_omap44xx())
> >> +		cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> >> +	else if (soc_is_omap54xx())
> >> +		cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> >>  	pm_info = &per_cpu(omap4_pm_info, 0x0);
> >>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
> >> -	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> >> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
> >>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
> >>  	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
> >>  	if (!pm_info->pwrdm) {
> >> @@ -405,14 +412,14 @@ int __init omap4_mpuss_init(void)
> >>  	/* Initialise CPU0 power domain state to ON */
> >>  	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
> >>  
> >> +	if (cpu_is_omap44xx())
> >> +		cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> >> +	else if (soc_is_omap54xx())
> >> +		cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> >>  	pm_info = &per_cpu(omap4_pm_info, 0x1);
> >>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
> >> -	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> >> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
> >>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
> >> -	if (cpu_is_omap446x())
> >> -		pm_info->secondary_startup = omap_secondary_startup_4460;
> >> -	else
> >> -		pm_info->secondary_startup = omap_secondary_startup;
> >>  
> >>  	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
> >>  	if (!pm_info->pwrdm) {
> >> @@ -445,15 +452,19 @@ int __init omap4_mpuss_init(void)
> >>  
> >>  	if (cpu_is_omap44xx()) {
> >>  		omap_pm_ops.finish_suspend = omap4_finish_suspend;
> >> +		omap_pm_ops.hotplug_restart = omap_secondary_startup;
> > could we handle omap_pm_ops.hotplug_restart = omap_secondary_startup_4460
> > here as well with the interest of keeping all function inits
> > in consecutive source location?
> I don't wanted to have multiple indentation and  4460 bug is just
> too annoying that it is better to keep it seperate.
ok
> 
> 
> >> diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
> >> index 6822d0a..ee8215b 100644
> >> --- a/arch/arm/mach-omap2/omap4-sar-layout.h
> >> +++ b/arch/arm/mach-omap2/omap4-sar-layout.h
> >> @@ -31,6 +31,8 @@
> >>  /* 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
> >> +#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
> >> +#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
> >>  
> >>  #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
> >>  #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
> >> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> >> index 88ff83a..3322fc8 100644
> >> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> >> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> >> @@ -326,6 +326,86 @@ skip_l2en:
> >>  
> >>  	b	cpu_resume			@ Jump to generic resume
> >>  ENDPROC(omap4_cpu_resume)
> >> +
> >> +/*
> >> + * ================================
> >> + * == OMAP5 CPU suspend finisher ==
> >> + * ================================
> >> + *
> >> + * OMAP5 MPUSS states for the context save:
> >> + * save_state =
> >> + *	0 - Nothing lost and no need to save: MPUSS INA/CSWR
> >> + *	1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR
> >> + *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
> >> + *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> >> + */
> >> +ENTRY(omap5_finish_suspend)
> >> +	stmfd	sp!, {r4-r12, lr}
> >> +	cmp	r0, #0x0
> >> +	beq	do_wfi				@ No lowpower state, jump to WFI
> >> +
> >> +	/*
> >> +	 * Flush all data from the L1 data cache before disabling
> >> +	 * SCTLR.C bit.
> >> +	 */
> >> +	bl	omap4_get_sar_ram_base
> >> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
> >> +	cmp	r9, #0x1			@ Check for HS device
> >> +	bne	skip_secure_l1_clean_op
> >> +	mov	r0, #0				@ Clean secure L1
> >> +	stmfd   r13!, {r4-r12, r14}
> >> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
> >> +	DO_SMC
> >> +	ldmfd   r13!, {r4-r12, r14}
> >> +skip_secure_l1_clean_op:
> >> +	bl	v7_flush_dcache_louis
> >> +
> >> +	/*
> >> +	 * Clear the SCTLR.C bit to prevent further data cache
> >> +	 * allocation. Clearing SCTLR.C would make all the data accesses
> >> +	 * strongly ordered and would not hit the cache.
> >> +	 */
> >> +	mrc	p15, 0, r0, c1, c0, 0
> >> +	bic	r0, r0, #(1 << 2)		@ Disable the C bit
> >> +	mcr	p15, 0, r0, c1, c0, 0
> >> +	isb
> >> +
> >> +	/* Clean and Invalidate L1 data cache. */
> >> +	bl	v7_flush_dcache_louis
> > Curious question - once we have flushed and invalidated L1 on
> > skip_secure_l1_clean_op:, we disable SCTLR.C to make all accesses SO,
> > what is the need to go through clean and invalidate again? is'nt it an
> > un-necessary cycle consuming NOP? What kind of data are we cleaning out
> > here?
> Obviously you haven't read all the old emails internally as well as
> externally on this topic. Its needed.
OK. Might be good to briefly document the same in code comments.
> 
> >> +
> >> +	/*
> >> +	 * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus
> >> +	 * preventing the CPU from receiving cache, TLB, or BTB
> >> +	 * maintenance operations broadcast by other CPUs in the cluster.
> >> +	 */
> >> +	mrc	p15, 0, r0, c1, c1, 2		@ Read NSACR data
> >> +	tst	r0, #(1 << 18)
> >> +	mrcne	p15, 0, r0, c1, c0, 1
> >> +	bicne	r0, r0, #(1 << 6)		@ Disable SMP bit
> >> +	mcrne	p15, 0, r0, c1, c0, 1
> >> +	isb
> >> +	dsb
> >> +
> > when save_state=3, as per the function comment:
> >  3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> > But we dont flush L2 nonsecure OR secure at this point. results wont be
> > pretty.
> Subject adds CPU off support only. I have added the comments section in
> this patch. I can move that for next patch.
Thanks - it will be good NOT to have DEVICE OFF mentioned here.
> 
> > If we dont want to deal with "3", then should'nt we add an adequate
> > handler on entry and remove the code comment claiming we support
> > it?
> > is'nt it better to squash in "[PATCH 11/15] ARM: OMAP5: PM: Add L2
> > memory power down support" here?
> Why. You don't need L2 support for CPU OFF. As I said I will move the
> comment in further patch which seems to confused you. And sure, I will
> remove that device OFF reference but still support mode where L2
> can be destroyed. It can be done in MPU OSWR as well with a setting
> to loose L2.
yep - the DEVICE OFF documentation threw me off I suppose.
> 
> >> +do_wfi:
> >> +	bl	omap_do_wfi
> >> +
> >> +	/*
> >> +	 * CPU is here when it failed to enter OFF/DORMANT or
> >> +	 * no low power state was attempted.
> > This might need a bit more clarity IMHO. successful WFI (which is
> > arguably an power state if we consider ARM internal clock gating takes
> > place), will reach here as well. So would OMAP CPU INA state. The
> > comment is probably valid for the defined save_states in code comments
> > for CPU OFF which is un-successful.
> >> +	 */
> >> +	mrc	p15, 0, r0, c1, c0, 0
> >> +	tst	r0, #(1 << 2)			@ Check C bit enabled?
> >> +	orreq	r0, r0, #(1 << 2)		@ Enable the C bit
> >> +	mcreq	p15, 0, r0, c1, c0, 0
> >> +	isb
> >> +	mrc	p15, 0, r0, c1, c0, 1
> >> +	tst	r0, #(1 << 6)			@ Check SMP bit enabled?
> >> +	orreq	r0, r0, #(1 << 6)
> >> +	mcreq	p15, 0, r0, c1, c0, 1
> >> +	isb
> >> +	dsb
> >> +	ldmfd	sp!, {r4-r12, pc}
> >> +ENDPROC(omap5_finish_suspend)
> >>  #endif
> >>  
> >>  #ifndef CONFIG_OMAP4_ERRATA_I688
> > 
> > I was curious at this point -> given that we added documentation that
> > we will be able to go to CPU OFF here, but I did not see an resume
> > handler registered. Untill I looked down in the series to see:
> >
> I should have mentioned abou CPU OFF in hotplug path which doesn't
> need resume entry. Will update commit message accordingly. Thanks
> for comments.
Thanks.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support
@ 2013-03-04 18:38         ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 11:44-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 03:06 AM, Nishanth Menon wrote:
> > On 17:40-20130301, Santosh Shilimkar wrote:
> >> Add power management code to handle the CPU off mode. Separate
> >> suspend finisher is used for OMAP5(Cortex-A15) because it doesn't
> >> use SCU power status register and external PL310 L2 cache which makes
> >> code flow bit different.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap-mpuss-lowpower.c |   31 +++++++----
> >>  arch/arm/mach-omap2/omap-secure.h         |    1 +
> >>  arch/arm/mach-omap2/omap4-sar-layout.h    |    2 +
> >>  arch/arm/mach-omap2/sleep_omap4plus.S     |   80 +++++++++++++++++++++++++++++
> >>  4 files changed, 104 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> index 9fda96b..275f9a4 100644
> >> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> @@ -76,10 +76,12 @@ struct cpu_pm_ops {
> >>  	int (*finish_suspend)(unsigned long cpu_state);
> >>  	void (*resume)(void);
> >>  	void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
> >> +	void (*hotplug_restart)(void);
> >>  };
> >>  
> >>  extern int omap4_finish_suspend(unsigned long cpu_state);
> >>  extern void omap4_cpu_resume(void);
> >> +extern int omap5_finish_suspend(unsigned long cpu_state);
> >>  
> >>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
> >>  static struct powerdomain *mpuss_pd;
> >> @@ -102,6 +104,7 @@ struct cpu_pm_ops omap_pm_ops = {
> >>  	.finish_suspend		= default_finish_suspend,
> >>  	.resume			= dummy_cpu_resume,
> >>  	.scu_prepare		= dummy_scu_prepare,
> >> +	.hotplug_restart	= dummy_cpu_resume,
> >>  };
> >>  
> >>  /*
> >> @@ -334,7 +337,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >>  int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> >>  {
> >>  	unsigned int cpu_state = 0;
> >> -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
> >>  
> >>  	if (omap_rev() == OMAP4430_REV_ES1_0)
> >>  		return -ENXIO;
> >> @@ -344,7 +346,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
> >>  
> >>  	clear_cpu_prev_pwrst(cpu);
> >>  	set_cpu_next_pwrst(cpu, power_state);
> >> -	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
> >> +	set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
> >>  	omap_pm_ops.scu_prepare(cpu, power_state);
> >>  
> >>  	/*
> >> @@ -379,6 +381,7 @@ static void enable_mercury_retention_mode(void)
> >>  int __init omap4_mpuss_init(void)
> >>  {
> >>  	struct omap4_cpu_pm_info *pm_info;
> >> +	u32 cpu_wakeup_addr = 0;
> >>  
> >>  	if (omap_rev() == OMAP4430_REV_ES1_0) {
> >>  		WARN(1, "Power Management not supported on OMAP4430 ES1.0\n");
> >> @@ -388,9 +391,13 @@ int __init omap4_mpuss_init(void)
> >>  	sar_base = omap4_get_sar_ram_base();
> >>  
> >>  	/* Initilaise per CPU PM information */
> >> +	if (cpu_is_omap44xx())
> >> +		cpu_wakeup_addr = CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> >> +	else if (soc_is_omap54xx())
> >> +		cpu_wakeup_addr = OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> >>  	pm_info = &per_cpu(omap4_pm_info, 0x0);
> >>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
> >> -	pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
> >> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
> >>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
> >>  	pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
> >>  	if (!pm_info->pwrdm) {
> >> @@ -405,14 +412,14 @@ int __init omap4_mpuss_init(void)
> >>  	/* Initialise CPU0 power domain state to ON */
> >>  	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
> >>  
> >> +	if (cpu_is_omap44xx())
> >> +		cpu_wakeup_addr = CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> >> +	else if (soc_is_omap54xx())
> >> +		cpu_wakeup_addr = OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> >>  	pm_info = &per_cpu(omap4_pm_info, 0x1);
> >>  	pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
> >> -	pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
> >> +	pm_info->wkup_sar_addr = sar_base + cpu_wakeup_addr;
> >>  	pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
> >> -	if (cpu_is_omap446x())
> >> -		pm_info->secondary_startup = omap_secondary_startup_4460;
> >> -	else
> >> -		pm_info->secondary_startup = omap_secondary_startup;
> >>  
> >>  	pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
> >>  	if (!pm_info->pwrdm) {
> >> @@ -445,15 +452,19 @@ int __init omap4_mpuss_init(void)
> >>  
> >>  	if (cpu_is_omap44xx()) {
> >>  		omap_pm_ops.finish_suspend = omap4_finish_suspend;
> >> +		omap_pm_ops.hotplug_restart = omap_secondary_startup;
> > could we handle omap_pm_ops.hotplug_restart = omap_secondary_startup_4460
> > here as well with the interest of keeping all function inits
> > in consecutive source location?
> I don't wanted to have multiple indentation and  4460 bug is just
> too annoying that it is better to keep it seperate.
ok
> 
> 
> >> diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h
> >> index 6822d0a..ee8215b 100644
> >> --- a/arch/arm/mach-omap2/omap4-sar-layout.h
> >> +++ b/arch/arm/mach-omap2/omap4-sar-layout.h
> >> @@ -31,6 +31,8 @@
> >>  /* 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
> >> +#define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET	0xe00
> >> +#define OMAP5_CPU1_WAKEUP_NS_PA_ADDR_OFFSET	0xe04
> >>  
> >>  #define SAR_BACKUP_STATUS_OFFSET		(SAR_BANK3_OFFSET + 0x500)
> >>  #define SAR_SECURE_RAM_SIZE_OFFSET		(SAR_BANK3_OFFSET + 0x504)
> >> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> >> index 88ff83a..3322fc8 100644
> >> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> >> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> >> @@ -326,6 +326,86 @@ skip_l2en:
> >>  
> >>  	b	cpu_resume			@ Jump to generic resume
> >>  ENDPROC(omap4_cpu_resume)
> >> +
> >> +/*
> >> + * ================================
> >> + * == OMAP5 CPU suspend finisher ==
> >> + * ================================
> >> + *
> >> + * OMAP5 MPUSS states for the context save:
> >> + * save_state =
> >> + *	0 - Nothing lost and no need to save: MPUSS INA/CSWR
> >> + *	1 - CPUx L1 and logic lost: CPU OFF, MPUSS INA/CSWR
> >> + *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR
> >> + *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> >> + */
> >> +ENTRY(omap5_finish_suspend)
> >> +	stmfd	sp!, {r4-r12, lr}
> >> +	cmp	r0, #0x0
> >> +	beq	do_wfi				@ No lowpower state, jump to WFI
> >> +
> >> +	/*
> >> +	 * Flush all data from the L1 data cache before disabling
> >> +	 * SCTLR.C bit.
> >> +	 */
> >> +	bl	omap4_get_sar_ram_base
> >> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
> >> +	cmp	r9, #0x1			@ Check for HS device
> >> +	bne	skip_secure_l1_clean_op
> >> +	mov	r0, #0				@ Clean secure L1
> >> +	stmfd   r13!, {r4-r12, r14}
> >> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
> >> +	DO_SMC
> >> +	ldmfd   r13!, {r4-r12, r14}
> >> +skip_secure_l1_clean_op:
> >> +	bl	v7_flush_dcache_louis
> >> +
> >> +	/*
> >> +	 * Clear the SCTLR.C bit to prevent further data cache
> >> +	 * allocation. Clearing SCTLR.C would make all the data accesses
> >> +	 * strongly ordered and would not hit the cache.
> >> +	 */
> >> +	mrc	p15, 0, r0, c1, c0, 0
> >> +	bic	r0, r0, #(1 << 2)		@ Disable the C bit
> >> +	mcr	p15, 0, r0, c1, c0, 0
> >> +	isb
> >> +
> >> +	/* Clean and Invalidate L1 data cache. */
> >> +	bl	v7_flush_dcache_louis
> > Curious question - once we have flushed and invalidated L1 on
> > skip_secure_l1_clean_op:, we disable SCTLR.C to make all accesses SO,
> > what is the need to go through clean and invalidate again? is'nt it an
> > un-necessary cycle consuming NOP? What kind of data are we cleaning out
> > here?
> Obviously you haven't read all the old emails internally as well as
> externally on this topic. Its needed.
OK. Might be good to briefly document the same in code comments.
> 
> >> +
> >> +	/*
> >> +	 * Take CPU out of Symmetric Multiprocessing (SMP) mode and thus
> >> +	 * preventing the CPU from receiving cache, TLB, or BTB
> >> +	 * maintenance operations broadcast by other CPUs in the cluster.
> >> +	 */
> >> +	mrc	p15, 0, r0, c1, c1, 2		@ Read NSACR data
> >> +	tst	r0, #(1 << 18)
> >> +	mrcne	p15, 0, r0, c1, c0, 1
> >> +	bicne	r0, r0, #(1 << 6)		@ Disable SMP bit
> >> +	mcrne	p15, 0, r0, c1, c0, 1
> >> +	isb
> >> +	dsb
> >> +
> > when save_state=3, as per the function comment:
> >  3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF
> > But we dont flush L2 nonsecure OR secure at this point. results wont be
> > pretty.
> Subject adds CPU off support only. I have added the comments section in
> this patch. I can move that for next patch.
Thanks - it will be good NOT to have DEVICE OFF mentioned here.
> 
> > If we dont want to deal with "3", then should'nt we add an adequate
> > handler on entry and remove the code comment claiming we support
> > it?
> > is'nt it better to squash in "[PATCH 11/15] ARM: OMAP5: PM: Add L2
> > memory power down support" here?
> Why. You don't need L2 support for CPU OFF. As I said I will move the
> comment in further patch which seems to confused you. And sure, I will
> remove that device OFF reference but still support mode where L2
> can be destroyed. It can be done in MPU OSWR as well with a setting
> to loose L2.
yep - the DEVICE OFF documentation threw me off I suppose.
> 
> >> +do_wfi:
> >> +	bl	omap_do_wfi
> >> +
> >> +	/*
> >> +	 * CPU is here when it failed to enter OFF/DORMANT or
> >> +	 * no low power state was attempted.
> > This might need a bit more clarity IMHO. successful WFI (which is
> > arguably an power state if we consider ARM internal clock gating takes
> > place), will reach here as well. So would OMAP CPU INA state. The
> > comment is probably valid for the defined save_states in code comments
> > for CPU OFF which is un-successful.
> >> +	 */
> >> +	mrc	p15, 0, r0, c1, c0, 0
> >> +	tst	r0, #(1 << 2)			@ Check C bit enabled?
> >> +	orreq	r0, r0, #(1 << 2)		@ Enable the C bit
> >> +	mcreq	p15, 0, r0, c1, c0, 0
> >> +	isb
> >> +	mrc	p15, 0, r0, c1, c0, 1
> >> +	tst	r0, #(1 << 6)			@ Check SMP bit enabled?
> >> +	orreq	r0, r0, #(1 << 6)
> >> +	mcreq	p15, 0, r0, c1, c0, 1
> >> +	isb
> >> +	dsb
> >> +	ldmfd	sp!, {r4-r12, pc}
> >> +ENDPROC(omap5_finish_suspend)
> >>  #endif
> >>  
> >>  #ifndef CONFIG_OMAP4_ERRATA_I688
> > 
> > I was curious at this point -> given that we added documentation that
> > we will be able to go to CPU OFF here, but I did not see an resume
> > handler registered. Untill I looked down in the series to see:
> >
> I should have mentioned abou CPU OFF in hotplug path which doesn't
> need resume entry. Will update commit message accordingly. Thanks
> for comments.
Thanks.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support
  2013-03-02  6:24       ` Santosh Shilimkar
@ 2013-03-04 18:41         ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:41 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 11:54-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 05:13 AM, Nishanth Menon wrote:
> > On 17:41-20130301, Santosh Shilimkar wrote:
> >> When the entire MPUSS cluster is powered down in device off state, L2 cache
> >> memory looses it's content and hence while targetting such a state,
> >> l2 cache needs to be flushed to main memory.
> >>
> >> Add the necessary low power code support for the same.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap-secure.h     |    1 +
> >>  arch/arm/mach-omap2/sleep_omap4plus.S |   30 ++++++++++++++++++++++++++++++
> >>  2 files changed, 31 insertions(+)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> >> index 1739468..a171a5a 100644
> >> --- a/arch/arm/mach-omap2/omap-secure.h
> >> +++ b/arch/arm/mach-omap2/omap-secure.h
> >> @@ -47,6 +47,7 @@
> >>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
> >>  #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
> >>  #define OMAP5_MON_AUX_CTRL_INDEX	0x107
> >> +#define OMAP5_MON_L2AUX_CTRL_INDEX	0x104
> >>  
> >>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
> >>  
> >> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> >> index f4874e5..ea318be 100644
> >> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> >> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> >> @@ -386,6 +386,27 @@ skip_secure_l1_clean_op:
> >>  	isb
> >>  	dsb
> >>  
> >> +	bl	omap4_get_sar_ram_base
> >> +	mov	r8, r0
> >> +	mrc	p15, 0, r5, c0, c0, 5		@ Read MPIDR
> >> +	ands	r5, r5, #0x0f
> >> +	ldreq	r0, [r8, #L2X0_SAVE_OFFSET0]	@ Retrieve L2 state
> >> +	ldrne	r0, [r8, #L2X0_SAVE_OFFSET1]
> >> +	cmp	r0, #3
> > umm, we store l2x0_pwrst_prepare(cpu, save_state);
> > which in turn stores into L2X0_SAVE_OFFSET - I am with you so far
> > save_state in omap4_enter_lowpower is:
> > PWRDM_POWER_INACTIVE: 0
> > PWRDM_POWER_OFF: 1
> > or 2 in the case of OSWR
> > what is 3? ref:
> > https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-mpuss-lowpower.c#L298
> This was obviosly for the case where L2 can be destroyed. As I said it can happen
> with MPU OSWR + L2 OFF setting or device OFF. 
Then please use macros for this.
> 
> >> +	bne	do_wfi
> >> +	bl	omap4_get_sar_ram_base
> >> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
> >> +	cmp	r9, #0x1			@ Check for HS device
> > my 2c:
> > off topic: somewhere down the line, I think we need to clear up these
> > into macros so that as in this case, omap4_mpuss_init populated value
> > should be the same as here with usage of same macro without reviewer
> > needing to track down where it was set with what.
> >
> Patches welcome :)
Sure as long as we don't add even more "magic handshakes to the code" it
makes sense to cleanup older code.
> 
>  
> >> +	bne	skip_secure_l2_clean_op
> >> +	mov	r0, #1				@ Clean secure L2
> >> +	stmfd   r13!, {r4-r12, r14}
> >> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
> >> +	DO_SMC
> >> +	ldmfd   r13!, {r4-r12, r14}
> >> +skip_secure_l2_clean_op:
> >> +	mov	r0, #2				@ Flush L2
> > v7_flush_dcache_all does not take parameters, right?
> >> +	bl	v7_flush_dcache_all
> >> +
> >>  do_wfi:
> >>  	bl	omap_do_wfi
> >>  
> >> @@ -427,6 +448,15 @@ ENTRY(omap5_cpu_resume)
> >>  	dsb
> >>  1:
> >>  #endif
> >> +	mrc	p15, 1, r0, c15, c0, 0		@ Read L2 ACTLR
> >> +	cmp	r0, #0x118			@ Check if it is already set
> > 
> >> 	beq	skip_sec_l2
> >> +	ldr	r0, =0x118			@ Setup L2 ACTLR = 0x118
> >> +	ldr	r12, =OMAP5_MON_L2AUX_CTRL_INDEX
> > I hope I am looking at the right place:
> > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0438g/BABIAICD.html
> It is correct.
> 
> > 
> > Is'nt it better to configure on boot, save it into SAR memory and restore it
> > from SAR using monitor call? I mean it is possible that we start boot
> > with L2 ACTLR != 0x118 and then hit off and come out of OFF mode with
> > 0x118.
> No need because it is more of re-initing the value rather than save/restore.
> I should have used macro instead of value though.
> 
> btw. I might drop this special setting based on some experiments am doing
> with benchmarks. Either case, if I keep the L2AUX code, I will use
> a macro.
Thanks. As long as it remains constant at boot and across OFF, it is
fine with me.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support
@ 2013-03-04 18:41         ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:41 UTC (permalink / raw)
  To: linux-arm-kernel

On 11:54-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 05:13 AM, Nishanth Menon wrote:
> > On 17:41-20130301, Santosh Shilimkar wrote:
> >> When the entire MPUSS cluster is powered down in device off state, L2 cache
> >> memory looses it's content and hence while targetting such a state,
> >> l2 cache needs to be flushed to main memory.
> >>
> >> Add the necessary low power code support for the same.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/omap-secure.h     |    1 +
> >>  arch/arm/mach-omap2/sleep_omap4plus.S |   30 ++++++++++++++++++++++++++++++
> >>  2 files changed, 31 insertions(+)
> >>
> >> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> >> index 1739468..a171a5a 100644
> >> --- a/arch/arm/mach-omap2/omap-secure.h
> >> +++ b/arch/arm/mach-omap2/omap-secure.h
> >> @@ -47,6 +47,7 @@
> >>  #define OMAP4_MON_L2X0_PREFETCH_INDEX	0x113
> >>  #define OMAP5_MON_CACHES_CLEAN_INDEX	0x103
> >>  #define OMAP5_MON_AUX_CTRL_INDEX	0x107
> >> +#define OMAP5_MON_L2AUX_CTRL_INDEX	0x104
> >>  
> >>  #define OMAP5_MON_AMBA_IF_INDEX		0x108
> >>  
> >> diff --git a/arch/arm/mach-omap2/sleep_omap4plus.S b/arch/arm/mach-omap2/sleep_omap4plus.S
> >> index f4874e5..ea318be 100644
> >> --- a/arch/arm/mach-omap2/sleep_omap4plus.S
> >> +++ b/arch/arm/mach-omap2/sleep_omap4plus.S
> >> @@ -386,6 +386,27 @@ skip_secure_l1_clean_op:
> >>  	isb
> >>  	dsb
> >>  
> >> +	bl	omap4_get_sar_ram_base
> >> +	mov	r8, r0
> >> +	mrc	p15, 0, r5, c0, c0, 5		@ Read MPIDR
> >> +	ands	r5, r5, #0x0f
> >> +	ldreq	r0, [r8, #L2X0_SAVE_OFFSET0]	@ Retrieve L2 state
> >> +	ldrne	r0, [r8, #L2X0_SAVE_OFFSET1]
> >> +	cmp	r0, #3
> > umm, we store l2x0_pwrst_prepare(cpu, save_state);
> > which in turn stores into L2X0_SAVE_OFFSET - I am with you so far
> > save_state in omap4_enter_lowpower is:
> > PWRDM_POWER_INACTIVE: 0
> > PWRDM_POWER_OFF: 1
> > or 2 in the case of OSWR
> > what is 3? ref:
> > https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-mpuss-lowpower.c#L298
> This was obviosly for the case where L2 can be destroyed. As I said it can happen
> with MPU OSWR + L2 OFF setting or device OFF. 
Then please use macros for this.
> 
> >> +	bne	do_wfi
> >> +	bl	omap4_get_sar_ram_base
> >> +	ldr	r9, [r0, #OMAP_TYPE_OFFSET]
> >> +	cmp	r9, #0x1			@ Check for HS device
> > my 2c:
> > off topic: somewhere down the line, I think we need to clear up these
> > into macros so that as in this case, omap4_mpuss_init populated value
> > should be the same as here with usage of same macro without reviewer
> > needing to track down where it was set with what.
> >
> Patches welcome :)
Sure as long as we don't add even more "magic handshakes to the code" it
makes sense to cleanup older code.
> 
>  
> >> +	bne	skip_secure_l2_clean_op
> >> +	mov	r0, #1				@ Clean secure L2
> >> +	stmfd   r13!, {r4-r12, r14}
> >> +	ldr	r12, =OMAP5_MON_CACHES_CLEAN_INDEX
> >> +	DO_SMC
> >> +	ldmfd   r13!, {r4-r12, r14}
> >> +skip_secure_l2_clean_op:
> >> +	mov	r0, #2				@ Flush L2
> > v7_flush_dcache_all does not take parameters, right?
> >> +	bl	v7_flush_dcache_all
> >> +
> >>  do_wfi:
> >>  	bl	omap_do_wfi
> >>  
> >> @@ -427,6 +448,15 @@ ENTRY(omap5_cpu_resume)
> >>  	dsb
> >>  1:
> >>  #endif
> >> +	mrc	p15, 1, r0, c15, c0, 0		@ Read L2 ACTLR
> >> +	cmp	r0, #0x118			@ Check if it is already set
> > 
> >> 	beq	skip_sec_l2
> >> +	ldr	r0, =0x118			@ Setup L2 ACTLR = 0x118
> >> +	ldr	r12, =OMAP5_MON_L2AUX_CTRL_INDEX
> > I hope I am looking at the right place:
> > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0438g/BABIAICD.html
> It is correct.
> 
> > 
> > Is'nt it better to configure on boot, save it into SAR memory and restore it
> > from SAR using monitor call? I mean it is possible that we start boot
> > with L2 ACTLR != 0x118 and then hit off and come out of OFF mode with
> > 0x118.
> No need because it is more of re-initing the value rather than save/restore.
> I should have used macro instead of value though.
> 
> btw. I might drop this special setting based on some experiments am doing
> with benchmarks. Either case, if I keep the L2AUX code, I will use
> a macro.
Thanks. As long as it remains constant at boot and across OFF, it is
fine with me.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support
  2013-03-02  6:47       ` Santosh Shilimkar
@ 2013-03-04 18:48         ` Nishanth Menon
  -1 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:48 UTC (permalink / raw)
  To: Santosh Shilimkar; +Cc: linux-omap, khilman, linux-arm-kernel

On 12:17-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 05:55 AM, Nishanth Menon wrote:
> > On 17:41-20130301, Santosh Shilimkar wrote:
> >> The OMAP5 idle driver can re-use OMAP4 CPUidle driver implementation thanks
> >> to compatible MPUSS design.
> >>
> >> Though unlike OMAP4, on OMAP5 devices, MPUSS CSWR (Close Switch Retention)
> >> power states can be achieved with respective power states on CPU0 and CPU1
> >> power domain. This mode was broken on OMAP4 devices because of hardware
> >> limitation. Also there is no CPU low power entry order requirement like
> >> master CPU etc for CSWR C-state, which is icing on the cake. Code makes
> >> use of voting scheme for cluster low power state to support MPUSS CSWR
> >> C-state.
> >>
> >> Supported OMAP5 CPUidle C-states:
> >>         C1 - CPU0 ON(WFI) + CPU1 ON(WFI) + MPUSS ON
> >>         C2 - CPU0 CSWR + CPU1 CSWR + MPUSS CSWR
> >>         C3 - CPU0 OFF + CPU1 Force OFF + MPUSS OSWR
> >  think you meant CPU1 OFF?
> Yes.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/Kconfig                        |    1 +
> >>  arch/arm/mach-omap2/Makefile                       |    4 +-
> >>  .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  103 +++++++++++++++++++-
> >>  arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    7 +-
> >>  arch/arm/mach-omap2/pm_omap4plus.c                 |    2 +-
> >>  5 files changed, 110 insertions(+), 7 deletions(-)
> >>  rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (70%)
> >>
> >> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> >> index 41b581f..2df91dc 100644
> >> --- a/arch/arm/mach-omap2/Kconfig
> >> +++ b/arch/arm/mach-omap2/Kconfig
> >> @@ -82,6 +82,7 @@ config SOC_OMAP5
> >>  	select CPU_V7
> >>  	select HAVE_SMP
> >>  	select COMMON_CLK
> >> +	select ARCH_NEEDS_CPU_IDLE_COUPLED
> >>  
> >>  comment "OMAP Core Type"
> >>  	depends on ARCH_OMAP2
> >> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> >> index 7c3c6b6..f6ff88f 100644
> >> --- a/arch/arm/mach-omap2/Makefile
> >> +++ b/arch/arm/mach-omap2/Makefile
> >> @@ -97,8 +97,10 @@ endif
> >>  endif
> >>  
> >>  ifeq ($(CONFIG_CPU_IDLE),y)
> >> +omap4plus-common-idle			= cpuidle_omap4plus.o
> >>  obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
> >> -obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
> >> +obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-idle)
> >> +obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-idle)
> > nit pick: simpler to use cpuidle_omap4plus.o or do we expect more objs -
> > like moving the idle_data to DTS or so?
> No I haven't that on that path. Easy from maintenance point of view. common
> object and a label. Thats all.
> 
> >>  endif
> >>  
> >>  # PRCM
> >> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle_omap4plus.c
> >> similarity index 70%
> >> rename from arch/arm/mach-omap2/cpuidle44xx.c
> >> rename to arch/arm/mach-omap2/cpuidle_omap4plus.c
> >> index 23286c1..8681fa6 100644
> >> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> >> +++ b/arch/arm/mach-omap2/cpuidle_omap4plus.c
> >> @@ -29,6 +29,7 @@ struct idle_statedata {
> >>  	u32 cpu_state;
> >>  	u32 mpu_logic_state;
> >>  	u32 mpu_state;
> >> +	u32 mpu_state_vote;
> >>  };
> >>  
> >>  static struct idle_statedata omap4_idle_data[] = {
> >> @@ -49,17 +50,36 @@ static struct idle_statedata omap4_idle_data[] = {
> >>  	},
> >>  };
> >>  
> >> +static struct idle_statedata omap5_idle_data[] = {
> >> +	{
> >> +		.cpu_state = PWRDM_POWER_ON,
> >> +		.mpu_state = PWRDM_POWER_ON,
> >> +		.mpu_logic_state = PWRDM_POWER_RET,
> >> +	},
> >> +	{
> >> +		.cpu_state = PWRDM_POWER_RET,
> > CSWR I assume -> Documenting it helps? or we should introdce
> > cpu_logic_state to be explicit?
> Its is documented just below the table(desc). No need to add useless
> cpu_logic_state variable. This is part of the big C-state table.
> 
> 
> >
> [..]
> >>  /*
> >>   * For each cpu, setup the broadcast timer because local timers
> >>   * stops for the states above C1.
> >> @@ -209,6 +262,43 @@ static struct cpuidle_driver omap4_idle_driver = {
> >>  	.safe_state_index = 0,
> >>  };
> >>  
> >> +static struct cpuidle_driver omap5_idle_driver = {
> >> +	.name				= "omap5_idle",
> >> +	.owner				= THIS_MODULE,
> >> +	.en_core_tk_irqen		= 1,
> >> +	.states = {
> >> +		{
> >> +			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
> > we could move these to .desc
> That will be too much ... also above just for refence and understanding
> otherwise, CPU state is per CPU so we can't say CPU0 =x, and CPU1 = y in
> CPU0 C-state. I like the way .desc is today and would want to keep it that
> way.
imagine having kernel definitions change on a wide variety of customer
platforms - it is easy for us in customer support team to dump the
descriptions off the sysfs entries to know precisely what they would
probably be using. IMHO, making desc as an generated string is nice,
failing which either documenting it OR expanding idle_statedata to mean
the exact h/w state configured is the best option.
> 
> >> +			.exit_latency = 2 + 2,
> >> +			.target_residency = 5,
> > the obvious question on how these latencies were arrived at..
> Based on the internal measurements done only considering MPUSS
> C-state latencies.
OK.
> 
> 
> >> @@ -243,8 +333,13 @@ int __init omap4_idle_init(void)
> >>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
> >>  		dev->coupled_cpus = *cpu_online_mask;
> >>  #endif
> >> -		state_ptr = &omap4_idle_data[0];
> >> -		cpuidle_register_driver(&omap4_idle_driver);
> >> +		if (cpu_is_omap44xx()) {
> >> +			state_ptr = &omap4_idle_data[0];
> >> +			cpuidle_register_driver(&omap4_idle_driver);
> >> +		} else if (soc_is_omap54xx()) {
> >> +			state_ptr = &omap5_idle_data[0];
> >> +			cpuidle_register_driver(&omap5_idle_driver);
> >> +		}
> > we'd be doing cpuidle_register_driver twice since it is within the
> > for_each_cpu loop - we dont want to do that.
> Yep. I will move that out of the loop though second registration is just
> a nop.
Thanks. that said, I think it is best to register the driver *after* we
have done the state population (we do not want cpuidle driver to manage
CPU0 while we are getting CPU1 state vars ready)
> >>  
> >>  		if (cpuidle_register_device(dev)) {
> >>  			pr_err("%s: CPUidle register failed\n", __func__);
> >> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> index 5d32444..0ccb76e 100644
> >> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> @@ -87,7 +87,7 @@ extern void omap5_cpu_resume(void);
> >>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
> >>  static struct powerdomain *mpuss_pd;
> >>  static void __iomem *sar_base;
> >> -static u32 cpu_context_offset;
> >> +static u32 cpu_context_offset, cpu_cswr_supported;
> >>  
> >>  static int default_finish_suspend(unsigned long cpu_state)
> >>  {
> >> @@ -265,6 +265,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >>  		save_state = 1;
> >>  		break;
> >>  	case PWRDM_POWER_RET:
> >> +		if (cpu_cswr_supported) {
> >> +			save_state = 0;
> >> +			break;
> >> +		}
> > ok, I guess this is the best we can do under the current circumstance
> > where PWRDM_POWER_RET means either CSWR or OSWR!
> The switch is for CPUx power states and hence there is no question of
> OSWR. CPUx OSWR = CPUx OFF hence CPUx OSWR isn't supported. This has been
> known from OMAP4 days. CPU RET isn't supported on OMAP4 and hence
> that variable is added.
OK.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support
@ 2013-03-04 18:48         ` Nishanth Menon
  0 siblings, 0 replies; 100+ messages in thread
From: Nishanth Menon @ 2013-03-04 18:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 12:17-20130302, Santosh Shilimkar wrote:
> On Saturday 02 March 2013 05:55 AM, Nishanth Menon wrote:
> > On 17:41-20130301, Santosh Shilimkar wrote:
> >> The OMAP5 idle driver can re-use OMAP4 CPUidle driver implementation thanks
> >> to compatible MPUSS design.
> >>
> >> Though unlike OMAP4, on OMAP5 devices, MPUSS CSWR (Close Switch Retention)
> >> power states can be achieved with respective power states on CPU0 and CPU1
> >> power domain. This mode was broken on OMAP4 devices because of hardware
> >> limitation. Also there is no CPU low power entry order requirement like
> >> master CPU etc for CSWR C-state, which is icing on the cake. Code makes
> >> use of voting scheme for cluster low power state to support MPUSS CSWR
> >> C-state.
> >>
> >> Supported OMAP5 CPUidle C-states:
> >>         C1 - CPU0 ON(WFI) + CPU1 ON(WFI) + MPUSS ON
> >>         C2 - CPU0 CSWR + CPU1 CSWR + MPUSS CSWR
> >>         C3 - CPU0 OFF + CPU1 Force OFF + MPUSS OSWR
> >  think you meant CPU1 OFF?
> Yes.
> >>
> >> Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >> ---
> >>  arch/arm/mach-omap2/Kconfig                        |    1 +
> >>  arch/arm/mach-omap2/Makefile                       |    4 +-
> >>  .../{cpuidle44xx.c => cpuidle_omap4plus.c}         |  103 +++++++++++++++++++-
> >>  arch/arm/mach-omap2/omap-mpuss-lowpower.c          |    7 +-
> >>  arch/arm/mach-omap2/pm_omap4plus.c                 |    2 +-
> >>  5 files changed, 110 insertions(+), 7 deletions(-)
> >>  rename arch/arm/mach-omap2/{cpuidle44xx.c => cpuidle_omap4plus.c} (70%)
> >>
> >> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> >> index 41b581f..2df91dc 100644
> >> --- a/arch/arm/mach-omap2/Kconfig
> >> +++ b/arch/arm/mach-omap2/Kconfig
> >> @@ -82,6 +82,7 @@ config SOC_OMAP5
> >>  	select CPU_V7
> >>  	select HAVE_SMP
> >>  	select COMMON_CLK
> >> +	select ARCH_NEEDS_CPU_IDLE_COUPLED
> >>  
> >>  comment "OMAP Core Type"
> >>  	depends on ARCH_OMAP2
> >> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> >> index 7c3c6b6..f6ff88f 100644
> >> --- a/arch/arm/mach-omap2/Makefile
> >> +++ b/arch/arm/mach-omap2/Makefile
> >> @@ -97,8 +97,10 @@ endif
> >>  endif
> >>  
> >>  ifeq ($(CONFIG_CPU_IDLE),y)
> >> +omap4plus-common-idle			= cpuidle_omap4plus.o
> >>  obj-$(CONFIG_ARCH_OMAP3)                += cpuidle34xx.o
> >> -obj-$(CONFIG_ARCH_OMAP4)                += cpuidle44xx.o
> >> +obj-$(CONFIG_ARCH_OMAP4)		+= $(omap4plus-common-idle)
> >> +obj-$(CONFIG_SOC_OMAP5)			+= $(omap4plus-common-idle)
> > nit pick: simpler to use cpuidle_omap4plus.o or do we expect more objs -
> > like moving the idle_data to DTS or so?
> No I haven't that on that path. Easy from maintenance point of view. common
> object and a label. Thats all.
> 
> >>  endif
> >>  
> >>  # PRCM
> >> diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle_omap4plus.c
> >> similarity index 70%
> >> rename from arch/arm/mach-omap2/cpuidle44xx.c
> >> rename to arch/arm/mach-omap2/cpuidle_omap4plus.c
> >> index 23286c1..8681fa6 100644
> >> --- a/arch/arm/mach-omap2/cpuidle44xx.c
> >> +++ b/arch/arm/mach-omap2/cpuidle_omap4plus.c
> >> @@ -29,6 +29,7 @@ struct idle_statedata {
> >>  	u32 cpu_state;
> >>  	u32 mpu_logic_state;
> >>  	u32 mpu_state;
> >> +	u32 mpu_state_vote;
> >>  };
> >>  
> >>  static struct idle_statedata omap4_idle_data[] = {
> >> @@ -49,17 +50,36 @@ static struct idle_statedata omap4_idle_data[] = {
> >>  	},
> >>  };
> >>  
> >> +static struct idle_statedata omap5_idle_data[] = {
> >> +	{
> >> +		.cpu_state = PWRDM_POWER_ON,
> >> +		.mpu_state = PWRDM_POWER_ON,
> >> +		.mpu_logic_state = PWRDM_POWER_RET,
> >> +	},
> >> +	{
> >> +		.cpu_state = PWRDM_POWER_RET,
> > CSWR I assume -> Documenting it helps? or we should introdce
> > cpu_logic_state to be explicit?
> Its is documented just below the table(desc). No need to add useless
> cpu_logic_state variable. This is part of the big C-state table.
> 
> 
> >
> [..]
> >>  /*
> >>   * For each cpu, setup the broadcast timer because local timers
> >>   * stops for the states above C1.
> >> @@ -209,6 +262,43 @@ static struct cpuidle_driver omap4_idle_driver = {
> >>  	.safe_state_index = 0,
> >>  };
> >>  
> >> +static struct cpuidle_driver omap5_idle_driver = {
> >> +	.name				= "omap5_idle",
> >> +	.owner				= THIS_MODULE,
> >> +	.en_core_tk_irqen		= 1,
> >> +	.states = {
> >> +		{
> >> +			/* C1 - CPU0 ON + CPU1 ON + MPU ON */
> > we could move these to .desc
> That will be too much ... also above just for refence and understanding
> otherwise, CPU state is per CPU so we can't say CPU0 =x, and CPU1 = y in
> CPU0 C-state. I like the way .desc is today and would want to keep it that
> way.
imagine having kernel definitions change on a wide variety of customer
platforms - it is easy for us in customer support team to dump the
descriptions off the sysfs entries to know precisely what they would
probably be using. IMHO, making desc as an generated string is nice,
failing which either documenting it OR expanding idle_statedata to mean
the exact h/w state configured is the best option.
> 
> >> +			.exit_latency = 2 + 2,
> >> +			.target_residency = 5,
> > the obvious question on how these latencies were arrived at..
> Based on the internal measurements done only considering MPUSS
> C-state latencies.
OK.
> 
> 
> >> @@ -243,8 +333,13 @@ int __init omap4_idle_init(void)
> >>  #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
> >>  		dev->coupled_cpus = *cpu_online_mask;
> >>  #endif
> >> -		state_ptr = &omap4_idle_data[0];
> >> -		cpuidle_register_driver(&omap4_idle_driver);
> >> +		if (cpu_is_omap44xx()) {
> >> +			state_ptr = &omap4_idle_data[0];
> >> +			cpuidle_register_driver(&omap4_idle_driver);
> >> +		} else if (soc_is_omap54xx()) {
> >> +			state_ptr = &omap5_idle_data[0];
> >> +			cpuidle_register_driver(&omap5_idle_driver);
> >> +		}
> > we'd be doing cpuidle_register_driver twice since it is within the
> > for_each_cpu loop - we dont want to do that.
> Yep. I will move that out of the loop though second registration is just
> a nop.
Thanks. that said, I think it is best to register the driver *after* we
have done the state population (we do not want cpuidle driver to manage
CPU0 while we are getting CPU1 state vars ready)
> >>  
> >>  		if (cpuidle_register_device(dev)) {
> >>  			pr_err("%s: CPUidle register failed\n", __func__);
> >> diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> index 5d32444..0ccb76e 100644
> >> --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c
> >> @@ -87,7 +87,7 @@ extern void omap5_cpu_resume(void);
> >>  static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
> >>  static struct powerdomain *mpuss_pd;
> >>  static void __iomem *sar_base;
> >> -static u32 cpu_context_offset;
> >> +static u32 cpu_context_offset, cpu_cswr_supported;
> >>  
> >>  static int default_finish_suspend(unsigned long cpu_state)
> >>  {
> >> @@ -265,6 +265,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
> >>  		save_state = 1;
> >>  		break;
> >>  	case PWRDM_POWER_RET:
> >> +		if (cpu_cswr_supported) {
> >> +			save_state = 0;
> >> +			break;
> >> +		}
> > ok, I guess this is the best we can do under the current circumstance
> > where PWRDM_POWER_RET means either CSWR or OSWR!
> The switch is for CPUx power states and hence there is no question of
> OSWR. CPUx OSWR = CPUx OFF hence CPUx OSWR isn't supported. This has been
> known from OMAP4 days. CPU RET isn't supported on OMAP4 and hence
> that variable is added.
OK.

-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 100+ messages in thread

* Re: [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
  2013-03-04 18:29         ` Nishanth Menon
@ 2013-03-10 18:07           ` Santosh Shilimkar
  -1 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-10 18:07 UTC (permalink / raw)
  To: Nishanth Menon; +Cc: linux-omap, khilman, linux-arm-kernel

On Monday 04 March 2013 11:59 PM, Nishanth Menon wrote:
> On 11:17-20130302, Santosh Shilimkar wrote:
>> On Saturday 02 March 2013 01:07 AM, Nishanth Menon wrote:
>>> On 17:40-20130301, Santosh Shilimkar wrote:
>>>> Enables MPUSS ES2 power management mode using ES2_PM_MODE in
>>>> AMBA_IF_MODE register.
>>>>

[..]

>>>> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
>>>> index b0fd16f..b3c8ecc 100644
>>>> --- a/arch/arm/mach-omap2/omap-wakeupgen.h
>>>> +++ b/arch/arm/mach-omap2/omap-wakeupgen.h
>>>> @@ -27,6 +27,7 @@
>>>>  #define OMAP_WKG_ENB_E_1			0x420
>>>>  #define OMAP_AUX_CORE_BOOT_0			0x800
>>>>  #define OMAP_AUX_CORE_BOOT_1			0x804
>>>> +#define OMAP_AMBA_IF_MODE			0x80c
>>>>  #define OMAP_PTMSYNCREQ_MASK			0xc00
>>>>  #define OMAP_PTMSYNCREQ_EN			0xc04
>>>>  #define OMAP_TIMESTAMPCYCLELO			0xc08
>>>
>>> Curious, I see OMAP5_AMBA_IF_MODE_OFFSET in
>>> arch/arm/mach-omap2/omap4-sar-layout.h
>>> if we dont save new modified contents there, Wont restore logic just
>>> reset it back to 0?
>>>
>> It is already restored in the wakeup-gen restore code.
> I apologize, I do not see it in:
> https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-wakeupgen.c
> I might have expected an save of val to sar offset to ensure this is
> done, but since you indicate this is in wakeupgen restore logic, which I
> presume is done by ROM, we might expect an write to sar_base +
> OMAP5_AMBA_IF_MODE_OFFSET with the val for it to function?
> 
Arr.. Looks like I missed the hunk while updating the patches. Will
fix the appropriate patch which updates the wakeupgen SAR offsets.

Regards,
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

* [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default
@ 2013-03-10 18:07           ` Santosh Shilimkar
  0 siblings, 0 replies; 100+ messages in thread
From: Santosh Shilimkar @ 2013-03-10 18:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 04 March 2013 11:59 PM, Nishanth Menon wrote:
> On 11:17-20130302, Santosh Shilimkar wrote:
>> On Saturday 02 March 2013 01:07 AM, Nishanth Menon wrote:
>>> On 17:40-20130301, Santosh Shilimkar wrote:
>>>> Enables MPUSS ES2 power management mode using ES2_PM_MODE in
>>>> AMBA_IF_MODE register.
>>>>

[..]

>>>> diff --git a/arch/arm/mach-omap2/omap-wakeupgen.h b/arch/arm/mach-omap2/omap-wakeupgen.h
>>>> index b0fd16f..b3c8ecc 100644
>>>> --- a/arch/arm/mach-omap2/omap-wakeupgen.h
>>>> +++ b/arch/arm/mach-omap2/omap-wakeupgen.h
>>>> @@ -27,6 +27,7 @@
>>>>  #define OMAP_WKG_ENB_E_1			0x420
>>>>  #define OMAP_AUX_CORE_BOOT_0			0x800
>>>>  #define OMAP_AUX_CORE_BOOT_1			0x804
>>>> +#define OMAP_AMBA_IF_MODE			0x80c
>>>>  #define OMAP_PTMSYNCREQ_MASK			0xc00
>>>>  #define OMAP_PTMSYNCREQ_EN			0xc04
>>>>  #define OMAP_TIMESTAMPCYCLELO			0xc08
>>>
>>> Curious, I see OMAP5_AMBA_IF_MODE_OFFSET in
>>> arch/arm/mach-omap2/omap4-sar-layout.h
>>> if we dont save new modified contents there, Wont restore logic just
>>> reset it back to 0?
>>>
>> It is already restored in the wakeup-gen restore code.
> I apologize, I do not see it in:
> https://github.com/SantoshShilimkar/linux/blob/testing/3.10/omap5-int-rebuild/arch/arm/mach-omap2/omap-wakeupgen.c
> I might have expected an save of val to sar offset to ensure this is
> done, but since you indicate this is in wakeupgen restore logic, which I
> presume is done by ROM, we might expect an write to sar_base +
> OMAP5_AMBA_IF_MODE_OFFSET with the val for it to function?
> 
Arr.. Looks like I missed the hunk while updating the patches. Will
fix the appropriate patch which updates the wakeupgen SAR offsets.

Regards,
Santosh

^ permalink raw reply	[flat|nested] 100+ messages in thread

end of thread, other threads:[~2013-03-10 18:07 UTC | newest]

Thread overview: 100+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-01 12:10 [PATCH 00/15] ARM: OMAP5: PM: Add MPUSS suspend and CPUidle support Santosh Shilimkar
2013-03-01 12:10 ` Santosh Shilimkar
2013-03-01 12:10 ` [PATCH 01/15] ARM: OMAP4+: PM: Consolidate MPU subsystem PM code for re-use Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 13:50   ` Nishanth Menon
2013-03-01 13:50     ` Nishanth Menon
2013-03-01 12:10 ` [PATCH 02/15] ARM: OMAP5: PM: Update CPU context register offset Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 17:34   ` Nishanth Menon
2013-03-01 17:34     ` Nishanth Menon
2013-03-01 12:10 ` [PATCH 03/15] ARM: OMAP4+: PM: Consolidate and use OMAP4 PM code for OMAP5 Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 17:43   ` Nishanth Menon
2013-03-01 17:43     ` Nishanth Menon
2013-03-02  5:43     ` Santosh Shilimkar
2013-03-02  5:43       ` Santosh Shilimkar
2013-03-04 18:21       ` Nishanth Menon
2013-03-04 18:21         ` Nishanth Menon
2013-03-01 12:10 ` [PATCH 04/15] ARM: OMAP5: PM: Set MPUSS-EMIF clock-domain static dependency Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 12:10 ` [PATCH 05/15] ARM: OMAP5: PM: Enables ES2 PM mode by default Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 19:37   ` Nishanth Menon
2013-03-01 19:37     ` Nishanth Menon
2013-03-02  5:47     ` Santosh Shilimkar
2013-03-02  5:47       ` Santosh Shilimkar
2013-03-04 18:29       ` Nishanth Menon
2013-03-04 18:29         ` Nishanth Menon
2013-03-10 18:07         ` Santosh Shilimkar
2013-03-10 18:07           ` Santosh Shilimkar
2013-03-01 12:10 ` [PATCH 06/15] ARM: OMAP5: PM: Enable Mercury retention mode on CPUx powerdomains Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 19:42   ` Nishanth Menon
2013-03-01 19:42     ` Nishanth Menon
2013-03-02  5:52     ` Santosh Shilimkar
2013-03-02  5:52       ` Santosh Shilimkar
2013-03-04 18:33       ` Nishanth Menon
2013-03-04 18:33         ` Nishanth Menon
2013-03-01 12:10 ` [PATCH 07/15] ARM: OMAP5: Add init_late() hook to enable pm initialization Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 20:12   ` Nishanth Menon
2013-03-01 20:12     ` Nishanth Menon
2013-03-02  6:00     ` Santosh Shilimkar
2013-03-02  6:00       ` Santosh Shilimkar
2013-03-04 18:35       ` Nishanth Menon
2013-03-04 18:35         ` Nishanth Menon
2013-03-01 12:10 ` [PATCH 08/15] ARM: OMAP5: PM: Add CPU power off mode support Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 21:36   ` Nishanth Menon
2013-03-01 21:36     ` Nishanth Menon
2013-03-02  6:14     ` Santosh Shilimkar
2013-03-02  6:14       ` Santosh Shilimkar
2013-03-04 18:38       ` Nishanth Menon
2013-03-04 18:38         ` Nishanth Menon
2013-03-01 12:10 ` [PATCH 09/15] ARM: OMAP4+: PM: Restore CPU power state to ON with clockdomain force wakeup method Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 21:53   ` Nishanth Menon
2013-03-01 21:53     ` Nishanth Menon
2013-03-02  6:16     ` Santosh Shilimkar
2013-03-02  6:16       ` Santosh Shilimkar
2013-03-01 12:10 ` [PATCH 10/15] ARM: OMAP5: PM: Add MPU Open Switch Retention support Santosh Shilimkar
2013-03-01 12:10   ` Santosh Shilimkar
2013-03-01 22:05   ` Nishanth Menon
2013-03-01 22:05     ` Nishanth Menon
2013-03-01 12:11 ` [PATCH 11/15] ARM: OMAP5: PM: Add L2 memory power down support Santosh Shilimkar
2013-03-01 12:11   ` Santosh Shilimkar
2013-03-01 23:43   ` Nishanth Menon
2013-03-01 23:43     ` Nishanth Menon
2013-03-02  6:24     ` Santosh Shilimkar
2013-03-02  6:24       ` Santosh Shilimkar
2013-03-04 18:41       ` Nishanth Menon
2013-03-04 18:41         ` Nishanth Menon
2013-03-01 12:11 ` [PATCH 12/15] ARM: OMAP4+: CPUidle: Cleanup idle driver for OMAP5 support Santosh Shilimkar
2013-03-01 12:11   ` Santosh Shilimkar
2013-03-01 23:56   ` Nishanth Menon
2013-03-01 23:56     ` Nishanth Menon
2013-03-02  6:25     ` Santosh Shilimkar
2013-03-02  6:25       ` Santosh Shilimkar
2013-03-01 12:11 ` [PATCH 13/15] ARM: OMAP4+: CPUidle: Deprecate use of omap4_mpuss_read_prev_context_state() Santosh Shilimkar
2013-03-01 12:11   ` Santosh Shilimkar
2013-03-02  0:03   ` Nishanth Menon
2013-03-02  0:03     ` Nishanth Menon
2013-03-01 12:11 ` [PATCH 14/15] ARM: OMAP4+: CPUidle: Add OMAP5 idle driver support Santosh Shilimkar
2013-03-01 12:11   ` Santosh Shilimkar
2013-03-02  0:25   ` Nishanth Menon
2013-03-02  0:25     ` Nishanth Menon
2013-03-02  6:47     ` Santosh Shilimkar
2013-03-02  6:47       ` Santosh Shilimkar
2013-03-04 18:48       ` Nishanth Menon
2013-03-04 18:48         ` Nishanth Menon
2013-03-01 12:11 ` [PATCH 15/15] ARM: OMAP5: PM: handle device instance for for coldreset Santosh Shilimkar
2013-03-01 12:11   ` Santosh Shilimkar
2013-03-01 13:04   ` Nishanth Menon
2013-03-01 13:04     ` Nishanth Menon
2013-03-01 13:09     ` Santosh Shilimkar
2013-03-01 13:09       ` Santosh Shilimkar
2013-03-01 13:13       ` Nishanth Menon
2013-03-01 13:13         ` Nishanth Menon
2013-03-01 13:16         ` Santosh Shilimkar
2013-03-01 13:16           ` Santosh Shilimkar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.