From: Vishwanath Sripathy <vishwanath.bs@ti.com>
To: Jean Pihet <jean.pihet@newoldbits.com>, linux-omap@vger.kernel.org
Cc: Jean Pihet-XID <j-pihet@ti.com>
Subject: RE: [RFC/PATCH] OMAP3: run the ASM sleep code from DDR
Date: Thu, 27 Jan 2011 15:43:15 +0530 [thread overview]
Message-ID: <e5e976880879f22d944bb8cf98cc3aa9@mail.gmail.com> (raw)
In-Reply-To: <AANLkTiniZuR9LFmJpo8WfmQN2D3zcB=jbfd-Nhv=Fbsr@mail.gmail.com>
Jean,
> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-
> owner@vger.kernel.org] On Behalf Of Jean Pihet
> Sent: Monday, January 24, 2011 7:59 PM
> To: linux-omap@vger.kernel.org
> Cc: Jean Pihet
> Subject: Re: [RFC/PATCH] OMAP3: run the ASM sleep code from DDR
>
> On Thu, Jan 13, 2011 at 5:19 PM, <jean.pihet@newoldbits.com> wrote:
> > From: Jean Pihet <j-pihet@ti.com>
> >
> > Most of the ASM sleep code (in arch/arm/mach-omap2/sleep34xx.S)
> > is copied to internal SRAM and run from there.
> > 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. No performance
> > loss or gain can be measured with a 32KHz clock period.
> >
> > 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),
> > . 1368 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).
> >
> > With this fix the usage for suspend/resume in RETention goes down
> 312 bytes, so the
> > gain in SRAM usage for suspend/resume is > 1KB.
> >
> > Tested on OMAP3EVM, Beagleboard (ES2.x) and N900 (ES3.1)
> > in idle with full RET and OFF modes.
> >
> > Signed-off-by: Jean Pihet <j-pihet@ti.com>
>
> Is there any feedback on this code?
> This change would need some more testing on all OMAP3 platforms,
> especially on the 36xx platforms that I do not have at hand.
I tested this patch on ZOOM3 (OMAP3630) using kevin's PM branch for both
retention and off in CPUIdle and suspend path and it seems to work fine.
You can add
Tested-by: Vishwanath BS <Vishwanath.bs@ti.com>
Vishwa
>
> Comments are welcome!
>
> Regards,
> Jean
>
> > ---
> > arch/arm/mach-omap2/pm.h | 19 ++-
> > arch/arm/mach-omap2/pm34xx.c | 19 ++-
> > arch/arm/mach-omap2/sleep34xx.S | 299
> +++++++++++++++++++++++----------------
> > 3 files changed, 200 insertions(+), 137 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-
> omap2/pm.h
> > index 1c1b0ab..ae9dec0 100644
> > --- a/arch/arm/mach-omap2/pm.h
> > +++ b/arch/arm/mach-omap2/pm.h
> > @@ -87,18 +87,29 @@ 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);
> > +
> > +/* 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 void save_secure_ram_context(u32 *addr);
> > -extern void omap3_save_scratchpad_contents(void);
> >
> > -extern unsigned int omap24xx_idle_loop_suspend_sz;
> > 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)
> > diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-
> omap2/pm34xx.c
> > index 5b323f2..56ca3cb 100644
> > --- a/arch/arm/mach-omap2/pm34xx.c
> > +++ b/arch/arm/mach-omap2/pm34xx.c
> > @@ -82,9 +82,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;
> > @@ -355,9 +354,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);
> > @@ -439,7 +435,7 @@ void omap_sram_idle(void)
> > * get saved. The restore path then reads from this
> > * location and restores them back.
> > */
> > - _omap_sram_idle(omap3_arm_context, save_state);
> > + omap34xx_cpu_suspend(omap3_arm_context, save_state);
> > cpu_init();
> >
> > /* Restore normal SDRC POWER settings */
> > @@ -996,10 +992,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);
> > diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-
> omap2/sleep34xx.S
> > index 98d8232..ced85b5 100644
> > --- a/arch/arm/mach-omap2/sleep34xx.S
> > +++ b/arch/arm/mach-omap2/sleep34xx.S
> > @@ -163,8 +163,10 @@ ENTRY(save_secure_ram_context_sz)
> > *
> > *
> > * Notes:
> > - * - this code gets copied to internal SRAM at boot and after wake-up
> > - * from OFF mode. The execution pointer in SRAM is
> _omap_sram_idle.
> > + * - only the minimum set of functions gets copied to internal SRAM
> at boot
> > + * and after wake-up from OFF mode, cf. omap_push_sram_idle.
> The function
> > + * pointers in SDRAM or SRAM are called depending on the desired
> low power
> > + * target state.
> > * - when the OMAP wakes up it continues at different execution points
> > * depending on the low power mode (non-OFF vs OFF modes),
> > * cf. 'Resume path for xxx mode' comments.
> > @@ -181,9 +183,15 @@ ENTRY(omap34xx_cpu_suspend)
> > * 3 - Both L1 and L2 lost
> > */
> >
> > - /* Directly jump to WFI is the context save is not required */
> > - cmp r1, #0x0
> > - beq omap3_do_wfi
> > + /*
> > + * For OFF mode: save context and jump to WFI in SDRAM
> (omap3_do_wfi)
> > + * For non-OFF modes: jump to the WFI code in SRAM
> (omap3_do_wfi_sram)
> > + */
> > + ldr r4, omap3_do_wfi_sram_addr
> > + ldr r5, [r4]
> > + cmp r1, #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:
> > @@ -282,7 +290,31 @@ clean_l2:
> > mov lr, pc
> > bx r1
> >
> > -omap3_do_wfi:
> > + b omap3_do_wfi
> > +
> > +/*
> > + * Local variables
> > + */
> > +omap3_do_wfi_sram_addr:
> > + .word omap3_do_wfi_sram
> > +kernel_flush:
> > + .word v7_flush_dcache_all
> > +
> > +/* ===================================
> > + * == WFI instruction => Enter idle ==
> > + * ===================================
> > + */
> > +
> > +/*
> > + * Do WFI instruction
> > + * Includes the resume path for non-OFF modes
> > + *
> > + * This code gets copied to internal SRAM and is accessible
> > + * from both SDRAM and SRAM:
> > + * - executed from SRAM for non-off modes (omap3_do_wfi_sram),
> > + * - executed from SDRAM for OFF mode (omap3_do_wfi).
> > + */
> > +ENTRY(omap3_do_wfi)
> > ldr r4, sdrc_power @ read the SDRC_POWER register
> > ldr r5, [r4] @ read the contents of
SDRC_POWER
> > orr r5, r5, #0x40 @ enable self refresh on idle
req
> > @@ -315,15 +347,111 @@ omap3_do_wfi:
> > nop
> > nop
> > nop
> > - bl wait_sdrc_ok
> > +
> > +/*
> > + * wait_sdrc_ok 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 SDRAM.
> > + */
> > +
> > +/* 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]
> > +
> > +is_dll_in_lock_mode:
> > + /* Is dll in lock mode? */
> > + ldr r4, sdrc_dlla_ctrl
> > + ldr r5, [r4]
> > + tst r5, #0x4
> > + bne exit_nonoff_modes @ Return if locked
> > +
> > + /* wait till dll locks */
> > +wait_dll_lock_timed:
> > + ldr r4, wait_dll_lock_counter
> > + add r4, r4, #1
> > + str r4, wait_dll_lock_counter
> > + ldr r4, sdrc_dlla_status
> > + /* Wait 20uS for lock */
> > + mov r6, #8
> > +wait_dll_lock:
> > + subs r6, r6, #0x1
> > + beq kick_dll
> > + ldr r5, [r4]
> > + and r5, r5, #0x4
> > + cmp r5, #0x4
> > + bne wait_dll_lock
> > + b exit_nonoff_modes @ Return when locked
> > +
> > + /* disable/reenable DLL if not locked */
> > +kick_dll:
> > + ldr r4, sdrc_dlla_ctrl
> > + ldr r5, [r4]
> > + mov r6, r5
> > + bic r6, #(1<<3) @ disable dll
> > + str r6, [r4]
> > + dsb
> > + orr r6, r6, #(1<<3) @ enable dll
> > + str r6, [r4]
> > + dsb
> > + ldr r4, kick_counter
> > + add r4, r4, #1
> > + str r4, kick_counter
> > + b wait_dll_lock_timed
> >
> > /*
> > * ===================================
> > * == Exit point from non-OFF modes ==
> > * ===================================
> > */
> > +exit_nonoff_modes:
> > ldmfd sp!, {r0-r12, pc} @ restore regs and return
> >
> > +/*
> > + * Local variables
> > + */
> > +sdrc_power:
> > + .word SDRC_POWER_V
> > +cm_idlest1_core:
> > + .word CM_IDLEST1_CORE_V
> > +cm_idlest_ckgen:
> > + .word CM_IDLEST_CKGEN_V
> > +sdrc_dlla_status:
> > + .word SDRC_DLLA_STATUS_V
> > +sdrc_dlla_ctrl:
> > + .word SDRC_DLLA_CTRL_V
> > + /*
> > + * When exporting to userspace while the counters are in SRAM,
> > + * these 2 words need to be at the end to facilitate retrival!
> > + */
> > +kick_counter:
> > + .word 0
> > +wait_dll_lock_counter:
> > + .word 0
> > +
> > +ENTRY(omap3_do_wfi_sz)
> > + .word . - omap3_do_wfi
> > +
> >
> > /*
> > * ==============================
> > @@ -339,6 +467,10 @@ omap3_do_wfi:
> > * restore_es3: applies to 34xx >= ES3.0
> > * restore_3630: applies to 36xx
> > * restore: common code for 3xxx
> > + *
> > + * Note: when back from CORE and MPU OFF mode we are running
> > + * from SDRAM, without MMU, without the caches and prediction.
> > + * Also the SRAM content has been cleared.
> > */
> > restore_es3:
> > ldr r5, pm_prepwstst_core_p
> > @@ -357,7 +489,8 @@ copy_to_sram:
> > bne copy_to_sram
> > ldr r1, sram_base
> > blx r1
> > - b restore
> > +
> > + b restore @ Fall through to common code
> >
> > restore_3630:
> > ldr r1, pm_prepwstst_core_p
> > @@ -600,12 +733,41 @@ usettbr0:
> > */
> > ldmfd sp!, {r0-r12, pc} @ restore regs and return
> >
> > +/*
> > + * Local variables
> > + */
> > +pm_prepwstst_core_p:
> > + .word PM_PREPWSTST_CORE_P
> > +pm_pwstctrl_mpu:
> > + .word PM_PWSTCTRL_MPU_P
> > +scratchpad_base:
> > + .word SCRATCHPAD_BASE_P
> > +sram_base:
> > + .word SRAM_BASE_P + 0x8000
> > +ttbrbit_mask:
> > + .word 0xFFFFC000
> > +table_index_mask:
> > + .word 0xFFF00000
> > +table_entry:
> > + .word 0x00000C02
> > +cache_pred_disable_mask:
> > + .word 0xFFFFE7FB
> > +control_stat:
> > + .word CONTROL_STAT
> > +control_mem_rta:
> > + .word CONTROL_MEM_RTA_CTRL
> > +l2dis_3630:
> > + .word 0
> > +
> >
> > /*
> > * Internal functions
> > */
> >
> > -/* This function implements the erratum ID i443 WA, applies to 34xx
> >= ES3.0 */
> > +/* This function implements the erratum ID i443 WA, applies to 34xx
> >= ES3.0
> > + *
> > + * Copied and run from SRAM in order to reconfigure the SDRC
> parameters.
> > + */
> > .text
> > ENTRY(es3_sdrc_fix)
> > ldr r4, sdrc_syscfg @ get config addr
> > @@ -634,6 +796,9 @@ ENTRY(es3_sdrc_fix)
> > str r5, [r4] @ kick off refreshes
> > bx lr
> >
> > +/*
> > + * Local variables
> > + */
> > sdrc_syscfg:
> > .word SDRC_SYSCONFIG_P
> > sdrc_mr_0:
> > @@ -650,119 +815,3 @@ sdrc_manual_1:
> > .word SDRC_MANUAL_1_P
> > ENTRY(es3_sdrc_fix_sz)
> > .word . - es3_sdrc_fix
> > -
> > -/*
> > - * 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]
> > -
> > -is_dll_in_lock_mode:
> > - /* Is dll in lock mode? */
> > - ldr r4, sdrc_dlla_ctrl
> > - ldr r5, [r4]
> > - tst r5, #0x4
> > - bxne lr @ Return if locked
> > - /* wait till dll locks */
> > -wait_dll_lock_timed:
> > - ldr r4, wait_dll_lock_counter
> > - add r4, r4, #1
> > - str r4, wait_dll_lock_counter
> > - ldr r4, sdrc_dlla_status
> > - /* Wait 20uS for lock */
> > - mov r6, #8
> > -wait_dll_lock:
> > - subs r6, r6, #0x1
> > - beq kick_dll
> > - ldr r5, [r4]
> > - and r5, r5, #0x4
> > - cmp r5, #0x4
> > - bne wait_dll_lock
> > - bx lr @ Return when locked
> > -
> > - /* disable/reenable DLL if not locked */
> > -kick_dll:
> > - ldr r4, sdrc_dlla_ctrl
> > - ldr r5, [r4]
> > - mov r6, r5
> > - bic r6, #(1<<3) @ disable dll
> > - str r6, [r4]
> > - dsb
> > - orr r6, r6, #(1<<3) @ enable dll
> > - str r6, [r4]
> > - dsb
> > - ldr r4, kick_counter
> > - add r4, r4, #1
> > - str r4, kick_counter
> > - b wait_dll_lock_timed
> > -
> > -cm_idlest1_core:
> > - .word CM_IDLEST1_CORE_V
> > -cm_idlest_ckgen:
> > - .word CM_IDLEST_CKGEN_V
> > -sdrc_dlla_status:
> > - .word SDRC_DLLA_STATUS_V
> > -sdrc_dlla_ctrl:
> > - .word SDRC_DLLA_CTRL_V
> > -pm_prepwstst_core_p:
> > - .word PM_PREPWSTST_CORE_P
> > -pm_pwstctrl_mpu:
> > - .word PM_PWSTCTRL_MPU_P
> > -scratchpad_base:
> > - .word SCRATCHPAD_BASE_P
> > -sram_base:
> > - .word SRAM_BASE_P + 0x8000
> > -sdrc_power:
> > - .word SDRC_POWER_V
> > -ttbrbit_mask:
> > - .word 0xFFFFC000
> > -table_index_mask:
> > - .word 0xFFF00000
> > -table_entry:
> > - .word 0x00000C02
> > -cache_pred_disable_mask:
> > - .word 0xFFFFE7FB
> > -control_stat:
> > - .word CONTROL_STAT
> > -control_mem_rta:
> > - .word CONTROL_MEM_RTA_CTRL
> > -kernel_flush:
> > - .word v7_flush_dcache_all
> > -l2dis_3630:
> > - .word 0
> > - /*
> > - * When exporting to userspace while the counters are in SRAM,
> > - * these 2 words need to be at the end to facilitate retrival!
> > - */
> > -kick_counter:
> > - .word 0
> > -wait_dll_lock_counter:
> > - .word 0
> > -
> > -ENTRY(omap34xx_cpu_suspend_sz)
> > - .word . - omap34xx_cpu_suspend
> > --
> > 1.7.2.3
> >
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2011-01-27 10:13 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-13 16:19 [RFC/PATCH] OMAP3: run the ASM sleep code from DDR jean.pihet
2011-01-24 14:29 ` Jean Pihet
2011-01-27 10:13 ` Vishwanath Sripathy [this message]
2011-01-27 13:50 ` Jean Pihet
2011-01-29 17:14 ` Santosh Shilimkar
2011-01-30 5:57 ` Santosh Shilimkar
2011-01-31 10:36 ` Jean Pihet
2011-01-31 11:00 ` Santosh Shilimkar
2011-02-01 11:23 ` Jean Pihet
2011-02-01 11:31 ` Santosh Shilimkar
2011-02-04 11:39 ` Santosh Shilimkar
2011-06-16 15:30 ` Pihet-XID, Jean
2011-06-16 16:11 ` Santosh Shilimkar
2011-06-17 8:58 ` Jean Pihet
2011-06-17 9:13 ` Santosh Shilimkar
2011-06-17 15:59 ` Kevin Hilman
2011-06-17 16:50 ` Santosh Shilimkar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e5e976880879f22d944bb8cf98cc3aa9@mail.gmail.com \
--to=vishwanath.bs@ti.com \
--cc=j-pihet@ti.com \
--cc=jean.pihet@newoldbits.com \
--cc=linux-omap@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox