Skip to contentSkip to conversation

OMAP3: run the ASM sleep code from DDR

PATCH In review jean.pihet at newoldbits.com 6 participants 11 messages Jun 29, 2011 – Jul 13, 2011

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

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

From: Jean Pihet <[email protected]>

Most of the ASM sleep code (in arch/arm/mach-omap2/sleep34xx.S) is copied to internal SRAM at boot and after wake-up from CORE OFF mode. However only a small part of the code really needs to run from internal SRAM.

This fix lets most of the ASM idle code run from the DDR
in order to minimize the SRAM usage and the overhead in the code copy.

The only pieces of code that are mandatory in SRAM are:
- the i443 erratum WA,
- the i581 erratum WA,
- the security extension code.

SRAM usage:
- original code:
. 560 bytes for omap3_sram_configure_core_dpll (used by DVFS), . 852 bytes for omap_sram_idle (used by suspend/resume in RETention), . 124 bytes for es3_sdrc_fix (used by suspend/resume in OFF mode on ES3.x), . 108 bytes for save_secure_ram_context (used on HS parts only).

With this fix the usage for suspend/resume in RETention goes down 288 bytes, so the gain in SRAM usage for suspend/resume is 564 bytes.

Also fixed the SRAM initialization sequence to avoid an unnecessary copy to SRAM at boot time and for readability.

Tested on Beagleboard (ES2.x) in idle with full RET and OFF modes.

---
 arch/arm/mach-omap2/pm.h        |   20 ++-
 arch/arm/mach-omap2/pm34xx.c    |   20 ++--
 arch/arm/mach-omap2/sleep34xx.S |  303 ++++++++++++++++++++++----------------
 arch/arm/plat-omap/sram.c       |   15 +--
 4 files changed, 206 insertions(+), 152 deletions(-)

Rebased on the suspend branch of rmk's tree

arch/arm/mach-omap2/pm.h +15 -5
index 45bcfce..a4ec213 100644
@@ -88,18 +88,28 @@ extern int pm_dbg_regset_init(int reg_set);
 #define pm_dbg_regset_init(reg_set) do {} while (0);
 #endif /* CONFIG_PM_DEBUG */
 
+/* 24xx */
 extern void omap24xx_idle_loop_suspend(void);
+extern unsigned int omap24xx_idle_loop_suspend_sz;
 
 extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 					void __iomem *sdrc_power);
+extern unsigned int omap24xx_cpu_suspend_sz;
+
+/* 3xxx */
 extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern int save_secure_ram_context(u32 *addr);
-extern void omap3_save_scratchpad_contents(void);
 
-extern unsigned int omap24xx_idle_loop_suspend_sz;
+/* omap3_do_wfi function pointer and size, for copy to SRAM */
+extern void omap3_do_wfi(void);
+extern unsigned int omap3_do_wfi_sz;
+/* ... and its pointer from SRAM after copy */
+extern void (*omap3_do_wfi_sram)(void);
+
+/* save_secure_ram_context function pointer and size, for copy to SRAM */
+extern int save_secure_ram_context(u32 *addr);
 extern unsigned int save_secure_ram_context_sz;
-extern unsigned int omap24xx_cpu_suspend_sz;
-extern unsigned int omap34xx_cpu_suspend_sz;
+
+extern void omap3_save_scratchpad_contents(void);
 
 #define PM_RTA_ERRATUM_i608		(1 << 0)
 #define PM_SDRC_WAKEUP_ERRATUM_i583	(1 << 1)
arch/arm/mach-omap2/pm34xx.c +11 -9
index 3e9a13e..e1c79ba 100644
@@ -78,9 +78,8 @@ struct power_state {
 
 static LIST_HEAD(pwrst_list);
 
-static void (*_omap_sram_idle)(u32 *addr, int save_state);
-
 static int (*_omap_save_secure_sram)(u32 *addr);
+void (*omap3_do_wfi_sram)(void);
 
 static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
 static struct powerdomain *core_pwrdm, *per_pwrdm;
@@ -309,7 +308,7 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 
 static void omap34xx_do_sram_idle(unsigned long save_state)
 {
-	_omap_sram_idle(omap3_arm_context, save_state);
+	omap34xx_cpu_suspend(omap3_arm_context, save_state);
 }
 
 void omap_sram_idle(void)
@@ -328,9 +327,6 @@ void omap_sram_idle(void)
 	int core_prev_state, per_prev_state;
 	u32 sdrc_pwr = 0;
 
-	if (!_omap_sram_idle)
-		return;
-
 	pwrdm_clear_all_prev_pwrst(mpu_pwrdm);
 	pwrdm_clear_all_prev_pwrst(neon_pwrdm);
 	pwrdm_clear_all_prev_pwrst(core_pwrdm);
@@ -826,10 +822,17 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
 	return 0;
 }
 
+/*
+ * Push functions to SRAM
+ *
+ * The minimum set of functions is pushed to SRAM for execution:
+ * - omap3_do_wfi for erratum i581 WA,
+ * - save_secure_ram_context for security extensions.
+ */
 void omap_push_sram_idle(void)
 {
-	_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
-					omap34xx_cpu_suspend_sz);
+	omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz);
+
 	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
 		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
 				save_secure_ram_context_sz);
@@ -894,7 +897,6 @@ static int __init omap3_pm_init(void)
 	per_clkdm = clkdm_lookup("per_clkdm");
 	core_clkdm = clkdm_lookup("core_clkdm");
 
-	omap_push_sram_idle();
 #ifdef CONFIG_SUSPEND
 	suspend_set_ops(&omap_pm_ops);
 #endif /* CONFIG_SUSPEND */
arch/arm/mach-omap2/sleep34xx.S +175 -128

376 lines not on this page · raw message

arch/arm/plat-omap/sram.c +5 -10
index 6af3d0b..363c91e 100644
@@ -394,20 +394,15 @@ void omap3_sram_restore_context(void)
 }
 #endif /* CONFIG_PM */
 
-static int __init omap34xx_sram_init(void)
-{
-	_omap3_sram_configure_core_dpll =
-		omap_sram_push(omap3_sram_configure_core_dpll,
-			       omap3_sram_configure_core_dpll_sz);
-	omap_push_sram_idle();
-	return 0;
-}
-#else
+#endif /* CONFIG_ARCH_OMAP3 */
+
 static inline int omap34xx_sram_init(void)
 {
+#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
+	omap3_sram_restore_context();
+#endif
 	return 0;
 }
-#endif
 
 int __init omap_sram_init(void)
 {
Signature · 1 line
1.7.4.1
#1 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

Quoted 24 lines · jean.pihet at newoldbits.com

From: Jean Pihet <[email protected]>

Most of the ASM sleep code (in arch/arm/mach-omap2/sleep34xx.S) is copied to internal SRAM at boot and after wake-up from CORE OFF mode. However only a small part of the code really needs to run from internal SRAM.

This fix lets most of the ASM idle code run from the DDR
in order to minimize the SRAM usage and the overhead in the code copy.

The only pieces of code that are mandatory in SRAM are:
- the i443 erratum WA,
- the i581 erratum WA,
- the security extension code.

SRAM usage:
- original code:
. 560 bytes for omap3_sram_configure_core_dpll (used by DVFS), . 852 bytes for omap_sram_idle (used by suspend/resume in RETention), . 124 bytes for es3_sdrc_fix (used by suspend/resume in OFF mode on ES3.x), . 108 bytes for save_secure_ram_context (used on HS parts only).

With this fix the usage for suspend/resume in RETention goes down 288 bytes, so the gain in SRAM usage for suspend/resume is 564 bytes.

Quoted 6 lines

Also fixed the SRAM initialization sequence to avoid an unnecessary copy to SRAM at boot time and for readability.

Tested on Beagleboard (ES2.x) in idle with full RET and OFF modes.

Also tested retention and off on 3430/n900, 3530/Overo and 3630/Zoom3

Russell, if you're OK with it, can you add it to your suspend branch for the upcoming merge window?

Kevin

author
#2 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

Quoted 31 lines · Kevin Hilman
Quoted 29 lines · jean.pihet at newoldbits.com

From: Jean Pihet <[email protected]>

Most of the ASM sleep code (in arch/arm/mach-omap2/sleep34xx.S) is copied to internal SRAM at boot and after wake-up from CORE OFF mode. However only a small part of the code really needs to run from internal SRAM.

This fix lets most of the ASM idle code run from the DDR
in order to minimize the SRAM usage and the overhead in the code copy.

The only pieces of code that are mandatory in SRAM are:
- the i443 erratum WA,
- the i581 erratum WA,
- the security extension code.

SRAM usage:
- original code:
? . 560 bytes for omap3_sram_configure_core_dpll (used by DVFS), ? . 852 bytes for omap_sram_idle (used by suspend/resume in RETention), ? . 124 bytes for es3_sdrc_fix (used by suspend/resume in OFF mode on ES3.x), ? . 108 bytes for save_secure_ram_context (used on HS parts only).

With this fix the usage for suspend/resume in RETention goes down 288 bytes, so the gain in SRAM usage for suspend/resume is 564 bytes.

Also fixed the SRAM initialization sequence to avoid an unnecessary copy to SRAM at boot time and for readability.

Tested on Beagleboard (ES2.x) in idle with full RET and OFF modes.

Quoted 7 lines
Quoted 1 line

Also tested retention and off on 3430/n900, 3530/Overo and 3630/Zoom3

Thanks for the extensive testing!

Regards,
Jean

Quoted 6 lines

Russell, if you're OK with it, can you add it to your suspend branch for the upcoming merge window?

Kevin

#3 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

In reply to Kevin Hilman
Quoted 2 lines · Kevin Hilman

Russell, if you're OK with it, can you add it to your suspend branch for the upcoming merge window?

Yes - though I think we can go a little bit further - this patch is on top of my code so far, and is untested. There isn't a need for the saving of these registers to be in assembly because we can read them just as easily from C code.

Comments?

 arch/arm/mach-omap2/pm.h        |    2 +-
 arch/arm/mach-omap2/pm34xx.c    |   19 +++++++++++++++++--
 arch/arm/mach-omap2/sleep34xx.S |   12 ++----------
 3 files changed, 20 insertions(+), 13 deletions(-)
arch/arm/mach-omap2/pm.h +1 -1
index 45bcfce..4984cca 100644
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 
 extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 					void __iomem *sdrc_power);
-extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
+extern void omap34xx_cpu_suspend(int save_state);
 extern int save_secure_ram_context(u32 *addr);
 extern void omap3_save_scratchpad_contents(void);
 
arch/arm/mach-omap2/pm34xx.c +17 -2
index 3e9a13e..6366352 100644
@@ -78,7 +78,7 @@ struct power_state {
 
 static LIST_HEAD(pwrst_list);
 
-static void (*_omap_sram_idle)(u32 *addr, int save_state);
+static void (*_omap_sram_idle)(int save_state);
 
 static int (*_omap_save_secure_sram)(u32 *addr);
 
@@ -307,9 +307,22 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static void omap34xx_save_context(u32 *save)
+{
+	u32 val;
+
+	asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (val));
+	*save++ = 1;
+	*save++ = val;
+
+	asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
+	*save++ = 1;
+	*save++ = val;
+}
+
 static void omap34xx_do_sram_idle(unsigned long save_state)
 {
-	_omap_sram_idle(omap3_arm_context, save_state);
+	_omap_sram_idle(save_state);
 }
 
 void omap_sram_idle(void)
@@ -412,6 +425,8 @@ void omap_sram_idle(void)
 	 * get saved. The rest is placed on the stack, and restored
 	 * from there before resuming.
 	 */
+	if (save_state)
+		omap34xx_save_context(omap3_arm_context);
 	if (save_state == 1 || save_state == 3)
 		cpu_suspend(save_state, omap34xx_do_sram_idle);
 	else
arch/arm/mach-omap2/sleep34xx.S +2 -10
index d18f52e..3335753 100644
@@ -150,8 +150,7 @@ ENTRY(omap34xx_cpu_suspend)
 	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
 
 	/*
-	 * r0 contains CPU context save/restore pointer in sdram
-	 * r1 contains information about saving context:
+	 * r0 contains information about saving context:
 	 *   0 - No context lost
 	 *   1 - Only L1 and logic lost
 	 *   2 - Only L2 lost (Even L1 is retained we clean it along with L2)
@@ -159,18 +158,11 @@ ENTRY(omap34xx_cpu_suspend)
 	 */
 
 	/* Directly jump to WFI is the context save is not required */
-	cmp	r1, #0x0
+	cmp	r0, #0x0
 	beq	omap3_do_wfi
 
 	/* Otherwise fall through to the save context code */
 save_context_wfi:
-	mov	r8, r0			@ Store SDRAM address in r8
-	mrc	p15, 0, r5, c1, c0, 1	@ Read Auxiliary Control Register
-	mov	r4, #0x1		@ Number of parameters for restore call
-	stmia	r8!, {r4-r5}		@ Push parameters for restore call
-	mrc	p15, 1, r5, c9, c0, 2	@ Read L2 AUX ctrl register
-	stmia	r8!, {r4-r5}		@ Push parameters for restore call
-
 	/*
 	 * jump out to kernel flush routine
 	 *  - reuse that code is better
#4 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

Quoted 8 lines · Russell King - ARM Linux
Quoted 2 lines · Kevin Hilman

Russell, if you're OK with it, can you add it to your suspend branch for the upcoming merge window?

Yes - though I think we can go a little bit further - this patch is on top of my code so far, and is untested. There isn't a need for the saving of these registers to be in assembly because we can read them just as easily from C code.

Indeed

Quoted 1 line

Comments?

Looks good to me (although untested) care to respin on top of $SUBJECT patch?

Minor comments below...

Quoted 32 lines
 arch/arm/mach-omap2/pm.h        |    2 +-
 arch/arm/mach-omap2/pm34xx.c    |   19 +++++++++++++++++--
 arch/arm/mach-omap2/sleep34xx.S |   12 ++----------
 3 files changed, 20 insertions(+), 13 deletions(-)
arch/arm/mach-omap2/pm.h +1 -1
index 45bcfce..4984cca 100644
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
 
 extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 					void __iomem *sdrc_power);
-extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
+extern void omap34xx_cpu_suspend(int save_state);
 extern int save_secure_ram_context(u32 *addr);
 extern void omap3_save_scratchpad_contents(void);
 
arch/arm/mach-omap2/pm34xx.c +1 -1
index 3e9a13e..6366352 100644
@@ -78,7 +78,7 @@ struct power_state {
 
 static LIST_HEAD(pwrst_list);
 
-static void (*_omap_sram_idle)(u32 *addr, int save_state);
+static void (*_omap_sram_idle)(int save_state);
 
 static int (*_omap_save_secure_sram)(u32 *addr);
 

arch/arm/mach-omap2/pm34xx.c static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) · line 314

Quoted 8 lines
arch/arm/mach-omap2/pm34xx.c +5 -0
@@ -307,9 +307,22 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static void omap34xx_save_context(u32 *save)
+{
+	u32 val;
+
+	asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (val));

Minor: for those of us who don't have all these registers memorized when looking at the assembly, maybe keeping the original comments (e.g. "Read AUX

Quoted 58 lines
arch/arm/mach-omap2/pm34xx.c +11 -1
+	*save++ = 1;
+	*save++ = val;
+
+	asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
+	*save++ = 1;
+	*save++ = val;
+}
+
 static void omap34xx_do_sram_idle(unsigned long save_state)
 {
-	_omap_sram_idle(omap3_arm_context, save_state);
+	_omap_sram_idle(save_state);
 }
 
 void omap_sram_idle(void)
@@ -412,6 +425,8 @@ void omap_sram_idle(void)
 	 * get saved. The rest is placed on the stack, and restored
 	 * from there before resuming.
 	 */
+	if (save_state)
+		omap34xx_save_context(omap3_arm_context);
 	if (save_state == 1 || save_state == 3)
 		cpu_suspend(save_state, omap34xx_do_sram_idle);
 	else
arch/arm/mach-omap2/sleep34xx.S +2 -10
index d18f52e..3335753 100644
@@ -150,8 +150,7 @@ ENTRY(omap34xx_cpu_suspend)
 	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
 
 	/*
-	 * r0 contains CPU context save/restore pointer in sdram
-	 * r1 contains information about saving context:
+	 * r0 contains information about saving context:
 	 *   0 - No context lost
 	 *   1 - Only L1 and logic lost
 	 *   2 - Only L2 lost (Even L1 is retained we clean it along with L2)
@@ -159,18 +158,11 @@ ENTRY(omap34xx_cpu_suspend)
 	 */
 
 	/* Directly jump to WFI is the context save is not required */
-	cmp	r1, #0x0
+	cmp	r0, #0x0
 	beq	omap3_do_wfi
 
 	/* Otherwise fall through to the save context code */
 save_context_wfi:
-	mov	r8, r0			@ Store SDRAM address in r8
-	mrc	p15, 0, r5, c1, c0, 1	@ Read Auxiliary Control Register
-	mov	r4, #0x1		@ Number of parameters for restore call
-	stmia	r8!, {r4-r5}		@ Push parameters for restore call
-	mrc	p15, 1, r5, c9, c0, 2	@ Read L2 AUX ctrl register
-	stmia	r8!, {r4-r5}		@ Push parameters for restore call
-
 	/*
 	 * jump out to kernel flush routine
 	 *  - reuse that code is better
#5 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

Quoted 11 lines · Kevin Hilman
Quoted 8 lines · Russell King - ARM Linux
Quoted 2 lines · Kevin Hilman

Russell, if you're OK with it, can you add it to your suspend branch for the upcoming merge window?

Yes - though I think we can go a little bit further - this patch is on top of my code so far, and is untested. There isn't a need for the saving of these registers to be in assembly because we can read them just as easily from C code.

Quoted 8 lines

Indeed

Quoted 1 line

Comments?

Looks good to me (although untested) care to respin on top of $SUBJECT patch?

Minor comments below...

Done.

 arch/arm/mach-omap2/pm.h        |    2 +-
 arch/arm/mach-omap2/pm34xx.c    |   19 ++++++++++++++++++-
 arch/arm/mach-omap2/sleep34xx.S |   12 ++----------
 3 files changed, 21 insertions(+), 12 deletions(-)
arch/arm/mach-omap2/pm.h +1 -1
index a4ec213..04ee566 100644
@@ -97,7 +97,7 @@ extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
 extern unsigned int omap24xx_cpu_suspend_sz;
 
 /* 3xxx */
-extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
+extern void omap34xx_cpu_suspend(int save_state);
 
 /* omap3_do_wfi function pointer and size, for copy to SRAM */
 extern void omap3_do_wfi(void);
arch/arm/mach-omap2/pm34xx.c +18 -1
index e1c79ba..7238a63 100644
@@ -306,9 +306,24 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static void omap34xx_save_context(u32 *save)
+{
+	u32 val;
+
+	/* Read Auxiliary Control Register */
+	asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (val));
+	*save++ = 1;
+	*save++ = val;
+
+	/* Read L2 AUX ctrl register */
+	asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
+	*save++ = 1;
+	*save++ = val;
+}
+
 static void omap34xx_do_sram_idle(unsigned long save_state)
 {
-	omap34xx_cpu_suspend(omap3_arm_context, save_state);
+	omap34xx_cpu_suspend(save_state);
 }
 
 void omap_sram_idle(void)
@@ -408,6 +423,8 @@ void omap_sram_idle(void)
 	 * get saved. The rest is placed on the stack, and restored
 	 * from there before resuming.
 	 */
+	if (save_state)
+		omap34xx_save_context(omap3_arm_context);
 	if (save_state == 1 || save_state == 3)
 		cpu_suspend(save_state, omap34xx_do_sram_idle);
 	else
arch/arm/mach-omap2/sleep34xx.S +2 -10
index 17dbc5a..f2ea1bd 100644
@@ -152,8 +152,7 @@ ENTRY(omap34xx_cpu_suspend)
 	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
 
 	/*
-	 * r0 contains CPU context save/restore pointer in sdram
-	 * r1 contains information about saving context:
+	 * r0 contains information about saving context:
 	 *   0 - No context lost
 	 *   1 - Only L1 and logic lost
 	 *   2 - Only L2 lost (Even L1 is retained we clean it along with L2)
@@ -166,19 +165,12 @@ ENTRY(omap34xx_cpu_suspend)
 	 */
 	ldr	r4, omap3_do_wfi_sram_addr
 	ldr	r5, [r4]
-	cmp	r1, #0x0		@ If no context save required,
+	cmp	r0, #0x0		@ If no context save required,
 	bxeq	r5			@  jump to the WFI code in SRAM
 
 
 	/* Otherwise fall through to the save context code */
 save_context_wfi:
-	mov	r8, r0			@ Store SDRAM address in r8
-	mrc	p15, 0, r5, c1, c0, 1	@ Read Auxiliary Control Register
-	mov	r4, #0x1		@ Number of parameters for restore call
-	stmia	r8!, {r4-r5}		@ Push parameters for restore call
-	mrc	p15, 1, r5, c9, c0, 2	@ Read L2 AUX ctrl register
-	stmia	r8!, {r4-r5}		@ Push parameters for restore call
-
 	/*
 	 * jump out to kernel flush routine
 	 *  - reuse that code is better
#6 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

Quoted 14 lines · Russell King - ARM Linux
Quoted 13 lines · Kevin Hilman
Quoted 8 lines · Russell King - ARM Linux
Quoted 2 lines · Kevin Hilman

Russell, if you're OK with it, can you add it to your suspend branch for the upcoming merge window?

Yes - though I think we can go a little bit further - this patch is on top of my code so far, and is untested. There isn't a need for the saving of these registers to be in assembly because we can read them just as easily from C code.

Indeed

Quoted 8 lines
Quoted 6 lines
Quoted 1 line

Comments?

Looks good to me (although untested) care to respin on top of $SUBJECT patch?

Minor comments below...

Done.

Tested full-chip retention and off on 3430/n900, 3530/Overo and 3630/Zoom3.

Kevin

#7 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

In reply to jean.pihet at newoldbits.com

arch/arm/mach-omap2/pm34xx.c static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) · line 311

Quoted 6 lines · jean.pihet at newoldbits.com
arch/arm/mach-omap2/pm34xx.c +1 -1
@@ -309,7 +308,7 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
 
 static void omap34xx_do_sram_idle(unsigned long save_state)
 {
-	_omap_sram_idle(omap3_arm_context, save_state);
+	omap34xx_cpu_suspend(omap3_arm_context, save_state);

Actually, this should be called omap34xx_soc_suspend() or omap34xx_finish_suspend() - finish_suspend() reflects the naming of other such functions elsewhere.

#8 lore raw
In reply to jean.pihet at newoldbits.com
Quoted 42 lines
arch/arm/mach-omap2/sleep34xx.S +42 -0
+/*
+ * This function implements the erratum ID i581 WA:
+ *  SDRC state restore before accessing the SDRAM
+ *
+ * Only used at return from non-OFF mode. For OFF
+ * mode the ROM code configures the SDRC and
+ * the DPLL before calling the restore code directly
+ * from DDR.
+ */
+
+/* Make sure SDRC accesses are ok */
+wait_sdrc_ok:
+
+/* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */
+       ldr     r4, cm_idlest_ckgen
+wait_dpll3_lock:
+       ldr     r5, [r4]
+       tst     r5, #1
+       beq     wait_dpll3_lock
+
+       ldr     r4, cm_idlest1_core
+wait_sdrc_ready:
+       ldr     r5, [r4]
+       tst     r5, #0x2
+       bne     wait_sdrc_ready
+       /* allow DLL powerdown upon hw idle req */
+       ldr     r4, sdrc_power
+       ldr     r5, [r4]
+       bic     r5, r5, #0x40
+       str     r5, [r4]
+
+/*
+ * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
+ * base instead.
+ * Be careful not to clobber r7 when maintaing this code.
+ */
+
+is_dll_in_lock_mode:
+       /* Is dll in lock mode? */
+       ldr     r4, sdrc_dlla_ctrl
+       ldr     r5, [r4]
+       tst     r5, #0x4

arch/arm/mach-omap2/sleep34xx.S omap3_do_wfi: · line 333

Quoted 10 lines
arch/arm/mach-omap2/sleep34xx.S +10 -0
+       bne     exit_nonoff_modes       @ Return if locked
+       /* wait till dll locks */
+       adr     r7, kick_counter
+wait_dll_lock_timed:
+       ldr     r4, wait_dll_lock_counter
+       add     r4, r4, #1
+       str     r4, [r7, #wait_dll_lock_counter - kick_counter]
+       ldr     r4, sdrc_dlla_status
+       /* Wait 20uS for lock */
+       mov     r6, #8

This was once calibrated using a scope on 3430 running from uncached SRAM, maybe this needs to verified for 3630 or other newer OMAP3 variants.

Cheers,

Peter.

#9 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

In reply to jean.pihet at newoldbits.com
Quoted 8 lines · jean.pihet at newoldbits.com

From: Jean Pihet <[email protected]>

Most of the ASM sleep code (in arch/arm/mach-omap2/sleep34xx.S) is copied to internal SRAM at boot and after wake-up from CORE OFF mode. However only a small part of the code really needs to run from internal SRAM.

This fix lets most of the ASM idle code run from the DDR
in order to minimize the SRAM usage and the overhead in the code copy.

So... what do you plan to use sram for? Because I don't think the speedup is worth the complexity...

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#10 lore raw

PATCH 1/1 OMAP3: run the ASM sleep code from DDR

Quoted 7 lines · Pavel Machek
Quoted 6 lines · jean.pihet at newoldbits.com

From: Jean Pihet <[email protected]>

Most of the ASM sleep code (in arch/arm/mach-omap2/sleep34xx.S) is copied to internal SRAM at boot and after wake-up from CORE OFF mode. However only a small part of the code really needs to run from internal SRAM.

Quoted 5 lines
Quoted 2 lines

This fix lets most of the ASM idle code run from the DDR
in order to minimize the SRAM usage and the overhead in the code copy.

So... what do you plan to use sram for? Because I don't think the speedup is worth the complexity...

The SDRAM may not be accessible yet when the chip isn't waking up from off-mode, so SRAM is the only option. The comments & code in the patch surrounding the "wait_sdrc_ok" label refer to this issue - albeit, perhaps telegraphically.

- Paul