ARM: OMAP4: device off support
Subsystems (5)
v2 cover ARM: OMAP4: device off support
Hi,
Changes compared to previous version:
- generic: dropped a few redundant cpu_is_omapXxxx checks
- generic: changed the ordering of patches a bit to allow new code + their users to be added in the same patch
- patch 3: removed dpll/cm/sar calls from this patch
- patch 4: added call to dpll save/restore to idle loop
- patch 5: indentation changes, added call to cm save/restore to idle loop merged cm1/cm2 save/restore funcs to single cm save/restores
- patch 6: added call to sar_save to idle loop
- patch 12: added errata flag for the feature instead of runtime cpu type check
- patch 15: reads the value of the register to be restored instead of using a magic number
Device off requires I2C save/restore context patch to function properly, otherwise MMC driver sees issues during wakeup from off.
Tested with omap4460 GP panda + omap4430 EMU blaze devices.
Patches also available here:
tree: git://gitorious.org/~kristo/omap-pm/omap-pm-work.git
branch: mainline-3.4-omap4-dev-off-v2
-Tero
PATCH v2 1/19 ARM: OMAP4: PM: powerdomain: Add HWSAR flag to L3INIT
From: Santosh Shilimkar <[email protected]>
L3INIT powerdomain has USB HOST and USB TLL modules which support hardware save-and-restore (HW SAR) mechanism.
This patch updates the L3INIT power domain to mark them as capable of doing H/w save and restore and provides functions to do them explicitly.
Note: Eventually, these custom function implementation will be abstracted and might be done in hwmod or in other layer.
--- arch/arm/mach-omap2/powerdomain44xx.c | 41 +++++++++++++++++++++++++++ arch/arm/mach-omap2/powerdomains44xx_data.c | 2 +- 2 files changed, 42 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/powerdomain44xx.c +41 -0
@@ -23,6 +23,10 @@#include "prm44xx.h" #include "prminst44xx.h" #include "prm-regbits-44xx.h" +#include "cm-regbits-44xx.h" +#include "prcm44xx.h" +#include "cm2_44xx.h" +#include "cminst44xx.h" static int omap4_pwrdm_set_next_pwrst (struct powerdomain *pwrdm,u8 pwrst) {
@@ -238,6 +242,41 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)return 0 ; } +static int omap4_pwrdm_enable_hdwr_sar (struct powerdomain *pwrdm) +{ +/* +* FIXME: This should be fixed right way by moving it into HWMOD +* or clock framework since sar control is moved to module level +*/ +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +1 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ); +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +1 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ); +return 0 ; +} + +static int omap4_pwrdm_disable_hdwr_sar (struct powerdomain *pwrdm) +{ +/* +* FIXME: This should be fixed right way by moving it into HWMOD +* or clock framework since sar control is moved to module level +*/ +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +0 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ); +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +0 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ); + +return 0 ; +} +struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
@@ -255,4 +294,6 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, .pwrdm_wait_transition = omap4_pwrdm_wait_transition, + .pwrdm_enable_hdwr_sar = omap4_pwrdm_enable_hdwr_sar, + .pwrdm_disable_hdwr_sar = omap4_pwrdm_disable_hdwr_sar, };
arch/arm/mach-omap2/powerdomains44xx_data.c +1 -1
@@ -276,7 +276,7 @@ static struct powerdomain l3init_44xx_pwrdm = { .pwrsts_mem_on = { [0] = PWRSTS_ON, /* l3init_bank1 */ }, - .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE | PWRDM_HAS_HDWR_SAR, };/* l4per_44xx_pwrdm: Target peripherals power domain */
Signature · 1 line
1.7.4.1
PATCH v2 1/19 ARM: OMAP4: PM: powerdomain: Add HWSAR flag to L3INIT
Quoted 10 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
L3INIT powerdomain has USB HOST and USB TLL modules which support hardware save-and-restore (HW SAR) mechanism.
This patch updates the L3INIT power domain to mark them as capable of doing H/w save and restore and provides functions to do them explicitly.Note: Eventually, these custom function implementation will be abstracted and might be done in hwmod or in other layer.
Why not do it the right way now?
Also, these new functions need kerneldoc.
Kevin
Quoted 84 lines
Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/powerdomain44xx.c | 41 +++++++++++++++++++++++++++ arch/arm/mach-omap2/powerdomains44xx_data.c | 2 +- 2 files changed, 42 insertions(+), 1 deletions(-)arch/arm/mach-omap2/powerdomain44xx.c +41
-0@@ -23,6 +23,10 @@#include "prm44xx.h" #include "prminst44xx.h" #include "prm-regbits-44xx.h" +#include "cm-regbits-44xx.h" +#include "prcm44xx.h" +#include "cm2_44xx.h" +#include "cminst44xx.h" static int omap4_pwrdm_set_next_pwrst (struct powerdomain *pwrdm,u8 pwrst) {@@ -238,6 +242,41 @@ static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)return 0 ; } +static int omap4_pwrdm_enable_hdwr_sar (struct powerdomain *pwrdm) +{ +/* +* FIXME: This should be fixed right way by moving it into HWMOD +* or clock framework since sar control is moved to module level +*/ +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +1 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ); +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +1 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ); +return 0 ; +} + +static int omap4_pwrdm_disable_hdwr_sar (struct powerdomain *pwrdm) +{ +/* +* FIXME: This should be fixed right way by moving it into HWMOD +* or clock framework since sar control is moved to module level +*/ +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +0 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET ); +omap4_cminst_rmw_inst_reg_bits (OMAP4430_SAR_MODE_MASK , +0 <<OMAP4430_SAR_MODE_SHIFT ,OMAP4430_CM2_PARTITION , +OMAP4430_CM2_L3INIT_INST , +OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET ); + +return 0 ; +} +struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst, .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,@@ -255,4 +294,6 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst, .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst, .pwrdm_wait_transition = omap4_pwrdm_wait_transition, + .pwrdm_enable_hdwr_sar = omap4_pwrdm_enable_hdwr_sar, + .pwrdm_disable_hdwr_sar = omap4_pwrdm_disable_hdwr_sar, };arch/arm/mach-omap2/powerdomains44xx_data.c +1
-1@@ -276,7 +276,7 @@ static struct powerdomain l3init_44xx_pwrdm = { .pwrsts_mem_on = { [0] = PWRSTS_ON, /* l3init_bank1 */ }, - .flags = PWRDM_HAS_LOWPOWERSTATECHANGE, + .flags = PWRDM_HAS_LOWPOWERSTATECHANGE | PWRDM_HAS_HDWR_SAR, };/* l4per_44xx_pwrdm: Target peripherals power domain */
PATCH v2 2/19 ARM: OMAP4: Add SAR ROM base address
In reply to Tero KristoAdded in preparation for device off mode. SAR ROM contains the mapping from SAR RAM to IO registers, and this will eventually be parsed during init time to do the reverse before device off.
--- arch/arm/plat-omap/include/plat/omap44xx.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
arch/arm/plat-omap/include/plat/omap44xx.h +1 -0
@@ -46,6 +46,7 @@#define OMAP44XX_MCPDM_BASE 0x40132000#define OMAP44XX_MCPDM_L3_BASE 0x49032000#define OMAP44XX_SAR_RAM_BASE 0x4a326000 +#define OMAP44XX_SAR_ROM_BASE 0x4a05e000#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
Signature · 1 line
1.7.4.1
PATCH v2 2/19 ARM: OMAP4: Add SAR ROM base address
Quoted 5 lines · Tero Kristo
Added in preparation for device off mode. SAR ROM contains the mapping from SAR RAM to IO registers, and this will eventually be parsed during init time to do the reverse before device off.
Signed-off-by Tero Kristo <[email protected]>
This should be combined with the patch that uses the #define.
Kevin
Quoted 16 lines
--- arch/arm/plat-omap/include/plat/omap44xx.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)arch/arm/plat-omap/include/plat/omap44xx.h +1
-0@@ -46,6 +46,7 @@#define OMAP44XX_MCPDM_BASE 0x40132000#define OMAP44XX_MCPDM_L3_BASE 0x49032000#define OMAP44XX_SAR_RAM_BASE 0x4a326000 +#define OMAP44XX_SAR_ROM_BASE 0x4a05e000#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
PATCH v2 2/19 ARM: OMAP4: Add SAR ROM base address
Quoted 9 lines · Kevin Hilman
Quoted 5 lines · Tero Kristo
Added in preparation for device off mode. SAR ROM contains the mapping from SAR RAM to IO registers, and this will eventually be parsed during init time to do the reverse before device off.
Signed-off-by Tero Kristo <[email protected]>This should be combined with the patch that uses the #define.
Okay sounds good.
-Tero
Quoted 19 lines
Kevin
Quoted 16 lines
--- arch/arm/plat-omap/include/plat/omap44xx.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)arch/arm/plat-omap/include/plat/omap44xx.h +1
-0@@ -46,6 +46,7 @@#define OMAP44XX_MCPDM_BASE 0x40132000#define OMAP44XX_MCPDM_L3_BASE 0x49032000#define OMAP44XX_SAR_RAM_BASE 0x4a326000 +#define OMAP44XX_SAR_ROM_BASE 0x4a05e000#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
PATCH v2 3/19 ARM: OMAP4: PM: Add device-off support
In reply to Tero KristoThis patch adds device off support to OMAP4 device type.
OFF mode is disabled by default, however, there are two ways to enable OFF mode:
a) In the board file, call omap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry
echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).
--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 10 ++++- arch/arm/mach-omap2/omap-wakeupgen.c | 47 +++++++++++++++++++- arch/arm/mach-omap2/pm-debug.c | 17 +++++-- arch/arm/mach-omap2/pm.h | 20 +++++++++ arch/arm/mach-omap2/pm44xx.c | 45 +++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 66 +++++++++++++++++++++++++++++ 6 files changed, 197 insertions(+), 8 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +9 -1
@@ -60,6 +60,7 @@#include "prcm44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" +#include "cm44xx.h" #ifdef CONFIG_SMP
@@ -263,9 +264,13 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); -if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && +if (omap4_device_next_state_off ()) + save_state =3 ; +else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) save_state =2 ; +else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) + save_state =3 ;cpu_clear_prev_logic_pwrst (cpu);set_cpu_next_pwrst (cpu, power_state);
@@ -288,6 +293,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); +if (omap4_device_prev_state_off ()) +omap4_device_clear_prev_off_state (); +pwrdm_post_transition ();return 0 ;
arch/arm/mach-omap2/omap-wakeupgen.c +45 -2
82 lines not on this page · raw message
arch/arm/mach-omap2/pm-debug.c +12 -5
@@ -40,6 +40,7 @@u32 enable_off_mode;static u32 enable_oswr_mode; +static void (*off_mode_enable_func) (int );#ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h>
@@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)else omap_pm_disable_off_mode (); -omap3_pm_off_mode_enable (val); +if (off_mode_enable_func) +off_mode_enable_func (val); }if (option == &enable_oswr_mode)
@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void)pwrdm_for_each (pwrdms_setup, (void *)d); -if (cpu_is_omap34xx ()) - (void )debugfs_create_file ("enable_off_mode" , -S_IRUGO |S_IWUSR , d, &enable_off_mode, - &pm_dbg_option_fops); + (void )debugfs_create_file ("enable_off_mode" , +S_IRUGO |S_IWUSR , d, &enable_off_mode, + &pm_dbg_option_fops);if (cpu_is_omap44xx ()) (void )debugfs_create_file ("enable_oswr_mode" ,S_IRUGO |S_IWUSR , d, &enable_oswr_mode, &pm_dbg_option_fops); +if (cpu_is_omap34xx ()) + off_mode_enable_func = omap3_pm_off_mode_enable; + +if (cpu_is_omap44xx ()) + off_mode_enable_func = omap4_pm_off_mode_enable; + pm_dbg_init_done =1 ;return 0 ;
arch/arm/mach-omap2/pm.h +20 -0
@@ -18,6 +18,7 @@extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap4_pm_oswr_mode_enable (int ); +extern void omap4_pm_off_mode_enable (int );extern void omap_sram_idle (void );extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap3_idle_init (void );
@@ -25,6 +26,25 @@ extern int omap4_idle_init(void);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void ); +#ifdef CONFIG_PM +extern void omap4_device_set_state_off (u8 enable); +extern bool omap4_device_prev_state_off (void ); +extern bool omap4_device_next_state_off (void ); +extern void omap4_device_clear_prev_off_state (void ); +#else +static inline void omap4_device_set_state_off (u8 enable) +{ +} +static inline bool omap4_device_prev_state_off (void ) +{ +return false; +} +static inline bool omap4_device_next_state_off (void ) +{ +return false; +} +#endif +#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );extern int omap4_opp_init (void );
arch/arm/mach-omap2/pm44xx.c +45 -0
57 lines not on this page · raw message
arch/arm/mach-omap2/prm44xx.c +66 -0
72 lines not on this page · raw message
Signature · 1 line
1.7.4.1
PATCH v2 3/19 ARM: OMAP4: PM: Add device-off support
+Jean for functional power states
Quoted 1 line · Tero Kristo
This patch adds device off support to OMAP4 device type.
Description is rather thin for a patch that is doing so much.
Quoted 1 line
OFF mode is disabled by default,
why?
Quoted 5 lines
however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).
This part needs to be a separate patch.
But, as stated in the core retention series, I'd like to move away from these global flags all together.
The way we manage the disabling of certain states (like off) is already clumsy for OMAP3, and it's getting worse with OMAP4. Basically, I think this feature needs to be supported by using constraints on functional
power states. Having checks all over the place is getting unwieldy and
not attractive to maintain.
The combination of constraints and functional power states should make
this much more manageable. Until we have that, I'd prefer to keep
the debugfs enable/disable stuff as separate patches at the end of the series used only for testing.
Quoted 2 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]
then the sign-off above from Santosh probably doesn't apply anymore. You should change that to a Cc and just mention tht this is based upon some original work from Santosh.
First, some general comments:
There is a lot going on in this patch, so it is hard to follow what all is related, and why. Just a quick glance suggests it needs to be broken up into at least a few parts:
- low-level PRM support: new APIs for various off-mode features) (should probably be done on top of functional power states)
- powerdomain core support or "achievable" states (should probably be done on top of functional power states)
- IRQ/GIC context save/restore
- secure RAM save/restore (this has been tightly coupled to the GIC but it's not obvious why)
- PM debug support to enable/disable off-mode
(for testing only, not for merge)
Quoted 23 lines
Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 10 ++++- arch/arm/mach-omap2/omap-wakeupgen.c | 47 +++++++++++++++++++- arch/arm/mach-omap2/pm-debug.c | 17 +++++-- arch/arm/mach-omap2/pm.h | 20 +++++++++ arch/arm/mach-omap2/pm44xx.c | 45 +++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 66 +++++++++++++++++++++++++++++ 6 files changed, 197 insertions(+), 8 deletions(-)arch/arm/mach-omap2/omap-mpuss-lowpower.c +1
-0@@ -60,6 +60,7 @@#include "prcm44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" +#include "cm44xx.h" #ifdef CONFIG_SMP
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 268
Quoted 6 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +2
-1@@ -263,9 +264,13 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); - if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) && +if (omap4_device_next_state_off ()) + save_state =3 ;
Why?
I don't see why this check is needed in addition to the mpuss_pd check added just below?
Quoted 8 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0+else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) save_state =2 ; +else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) + save_state =3 ;cpu_clear_prev_logic_pwrst (cpu);set_cpu_next_pwrst (cpu, power_state);
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 298
Quoted 6 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0@@ -288,6 +293,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); +if (omap4_device_prev_state_off ()) +omap4_device_clear_prev_off_state (); +
The 'clear prev off state' is subsequently removed in the last patch "ARM: OMAP4: powerdomain: update mpu / core off counters during device
off." Why is it needed here?
Quoted 43 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0pwrdm_post_transition ();return 0 ;arch/arm/mach-omap2/omap-wakeupgen.c +5
-2@@ -32,6 +32,7 @@#include "omap4-sar-layout.h" #include "common.h" +#include "pm.h" #define NR_REG_BANKS 4#define MAX_IRQS 128@@ -46,6 +47,8 @@ static void __iomem *sar_base;static DEFINE_SPINLOCK (wakeupgen_lock);static unsigned int irq_target_cpu[NR_IRQS ]; +static struct powerdomain *mpuss_pd; +/* * Static helper functions. */ @@ -259,7 +262,7 @@ static void irq_save_context(void)/* * Clear WakeupGen SAR backup status. */ -void irq_sar_clear (void ) +static void irq_sar_clear (void ) {u32 val; val =__raw_readl (sar_base +SAR_BACKUP_STATUS_OFFSET );@@ -271,7 +274,7 @@ void irq_sar_clear(void)* Save GIC and Wakeupgen interrupt context using secure API * for HS/EMU devices. */ -static void irq_save_secure_context (void ) +static void irq_save_secure_gic (void ) {u32 ret; ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 290
Quoted 6 lines
arch/arm/mach-omap2/omap-wakeupgen.c +3
-0@@ -282,6 +285,40 @@ static void irq_save_secure_context(void) }#endif +static void save_secure_ram (void ) +{ +u32 ret;
CodingStyle nit: blank line needed here (and in multiple other places)
Quoted 8 lines
arch/arm/mach-omap2/omap-wakeupgen.c +8
-0+ ret =omap_secure_dispatcher (OMAP4_HAL_SAVESECURERAM_INDEX , +FLAG_START_CRITICAL , +1 ,omap_secure_ram_mempool_base (), +0 ,0 ,0 ); +if (ret !=API_HAL_RET_VALUE_OK ) +pr_err ("Secure ram context save failed\n" ); +} +
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 308
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c +10
-0+static void save_secure_all (void ) +{ +u32 ret; + ret =omap_secure_dispatcher (OMAP4_HAL_SAVEALL_INDEX , +FLAG_START_CRITICAL , +1 ,omap_secure_ram_mempool_base (), +0 ,0 ,0 ); +if (ret !=API_HAL_RET_VALUE_OK ) +pr_err ("Secure all context save failed\n" ); +}
This secure mode save/restore seems misplaced in the wakeupgen driver. Seems to me like it belongs in omap-secure.c.
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 314
Quoted 6 lines
arch/arm/mach-omap2/omap-wakeupgen.c +6
-0+ +static void irq_save_secure_context (void ) +{ +if (omap4_device_next_state_off ()) { +save_secure_all (); + }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) {
Why is this check needed? This is called from the CPU_CLUSTER_PM_ENTER notifier, which AFAICT, is only called when the cluster is going off.
Quoted 126 lines
arch/arm/mach-omap2/omap-wakeupgen.c +13
-0+irq_save_secure_gic (); +save_secure_ram (); + }else { +irq_save_secure_gic (); + } +} +#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit irq_cpu_hotplug_notify (struct notifier_block *self,unsigned long action,void *hcpu)@@ -388,5 +425,11 @@ int __init omap_wakeupgen_init(void)irq_hotplug_init ();irq_pm_init (); + mpuss_pd =pwrdm_lookup ("mpu_pwrdm" ); +if (!mpuss_pd) { +pr_err ("wakeupgen: unable to get mpu_pwrdm\n" ); +return -EINVAL ; + } +return 0 ; }arch/arm/mach-omap2/pm-debug.c +12
-5@@ -40,6 +40,7 @@u32 enable_off_mode;static u32 enable_oswr_mode; +static void (*off_mode_enable_func) (int );#ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> @@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)else omap_pm_disable_off_mode (); -omap3_pm_off_mode_enable (val); +if (off_mode_enable_func) +off_mode_enable_func (val); }if (option == &enable_oswr_mode)@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void)pwrdm_for_each (pwrdms_setup, (void *)d); -if (cpu_is_omap34xx ()) - (void )debugfs_create_file ("enable_off_mode" , -S_IRUGO |S_IWUSR , d, &enable_off_mode, - &pm_dbg_option_fops); + (void )debugfs_create_file ("enable_off_mode" , +S_IRUGO |S_IWUSR , d, &enable_off_mode, + &pm_dbg_option_fops);if (cpu_is_omap44xx ()) (void )debugfs_create_file ("enable_oswr_mode" ,S_IRUGO |S_IWUSR , d, &enable_oswr_mode, &pm_dbg_option_fops); +if (cpu_is_omap34xx ()) + off_mode_enable_func = omap3_pm_off_mode_enable; + +if (cpu_is_omap44xx ()) + off_mode_enable_func = omap4_pm_off_mode_enable; + pm_dbg_init_done =1 ;return 0 ;arch/arm/mach-omap2/pm.h +20
-0@@ -18,6 +18,7 @@extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap4_pm_oswr_mode_enable (int ); +extern void omap4_pm_off_mode_enable (int );extern void omap_sram_idle (void );extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap3_idle_init (void );@@ -25,6 +26,25 @@ extern int omap4_idle_init(void);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void ); +#ifdef CONFIG_PM +extern void omap4_device_set_state_off (u8 enable); +extern bool omap4_device_prev_state_off (void ); +extern bool omap4_device_next_state_off (void ); +extern void omap4_device_clear_prev_off_state (void ); +#else +static inline void omap4_device_set_state_off (u8 enable) +{ +} +static inline bool omap4_device_prev_state_off (void ) +{ +return false; +} +static inline bool omap4_device_next_state_off (void ) +{ +return false; +} +#endif +#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );extern int omap4_opp_init (void );arch/arm/mach-omap2/pm44xx.c +10
-0@@ -87,6 +87,27 @@ static int omap4_pm_suspend(void) }#endif /* CONFIG_SUSPEND */ +/** +* get_achievable_state() - Provide achievable state +* @available_states: what states are available +* @req_min_state: what state is the minimum we'd like to hit +* +* Power domains have varied capabilities. When attempting a low power +* state such as OFF/RET, a specific min requested state may not be +* supported on the power domain, in which case, the next higher power +* state which is supported is returned. This is because a combination +* of system power states where the parent PD's state is not in line
arch/arm/mach-omap2/pm44xx.c static int omap4_pm_suspend(void) · line 109
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+* with expectation can result in system instabilities. +*/ +static inline u8 get_achievable_state (u8 available_states,u8 req_min_state) +{ +u16 mask =0xFF << req_min_state; + +if (available_states & mask) +return __ffs (available_states & mask); +return PWRDM_POWER_ON ; +}
This feature needs to be generalized (preferably on top of functional power states) because we have the same need on various AM3xxx SoCs which don't support RET/OFF. Mark Greer has started on this, but I think it needs to be part of the functional power states work.
It also needs to be part of the powerdomain layer, IMO.
Quoted 55 lines
arch/arm/mach-omap2/pm44xx.c +24
-0static int __init pwrdms_setup (struct powerdomain *pwrdm,void *unused) {struct power_state *pwrst;@@ -115,6 +136,30 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)return omap_set_pwrdm_state (pwrst->pwrdm, pwrst->next_state); } +void omap4_pm_off_mode_enable (int enable) +{ +u32 next_state =PWRDM_POWER_RET ; +u32 next_logic_state =PWRDM_POWER_ON ; +struct power_state *pwrst; + +if (enable) { + next_state =PWRDM_POWER_OFF ; + next_logic_state =PWRDM_POWER_OFF ; + } + +omap4_device_set_state_off (enable); + +list_for_each_entry (pwrst, &pwrst_list, node) { + pwrst->next_state = +get_achievable_state (pwrst->pwrdm->pwrsts, next_state); + pwrst->next_logic_state = +get_achievable_state (pwrst->pwrdm->pwrsts_logic_ret, + next_logic_state); +omap_set_pwrdm_state (pwrst->pwrdm, pwrst->next_state); +pwrdm_set_logic_retst (pwrst->pwrdm, pwrst->next_logic_state); + } +} +void omap4_pm_oswr_mode_enable (int enable) {u32 next_logic_state;arch/arm/mach-omap2/prm44xx.c +13
-0@@ -289,6 +289,72 @@ static void __init omap44xx_prm_enable_io_wakeup(void) OMAP4_PRM_IO_PMCTRL_OFFSET); } +/** +* omap4_device_set_state_off() - setup device off state +* @enable: set to off or not. +* +* When Device OFF is enabled, Device is allowed to perform +* transition to off mode as soon as all power domains in MPU, IVA +* and CORE voltage are in OFF or OSWR state (open switch retention) +*/ +void omap4_device_set_state_off (u8 enable) +{ +if (enable) + omap4_prminst_write_inst_reg(0x1 << + OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 314
Quoted 10 lines
arch/arm/mach-omap2/prm44xx.c +10
-0+OMAP4430_PRM_PARTITION , +OMAP4430_PRM_DEVICE_INST , + OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET); + else + omap4_prminst_write_inst_reg(0x0 << +OMAP4430_DEVICE_OFF_ENABLE_SHIFT , +OMAP4430_PRM_PARTITION , +OMAP4430_PRM_DEVICE_INST , +OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET ); +}
minor: a more compact, and more readable (so it's obvious at first glance that the same register is being written) would be:
void omap4_device_set_state_off(u8 enable)
{
u8 val = enable ? 0x1 : 0x0;
omap4_prminst_write_inst_reg(val <<
OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST,
OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET);
}arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 326
Quoted 11 lines
arch/arm/mach-omap2/prm44xx.c +11
-0+/** +* omap4_device_prev_state_off: +* returns true if the device hit OFF mode +* This is API to check whether OMAP is waking up from device OFF mode. +* There is no other status bit available for SW to read whether last state +* entered was device OFF. To work around this, CORE PD, RFF context state +* is used which is lost only when we hit device OFF state +*/ +bool omap4_device_prev_state_off (void ) +{ +u32 reg;
minor: reg makes me think the result of the read is a register address, not a value. How about s/reg/val/.
Quoted 18 lines
arch/arm/mach-omap2/prm44xx.c +18
-0+ reg =omap4_prminst_read_inst_reg (OMAP4430_PRM_PARTITION , +OMAP4430_PRM_CORE_INST , +OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET ) + &OMAP4430_LOSTCONTEXT_RFF_MASK ; + +return reg ? true : false; +} + +void omap4_device_clear_prev_off_state (void ) +{ +omap4_prminst_write_inst_reg (OMAP4430_LOSTCONTEXT_RFF_MASK | +OMAP4430_LOSTCONTEXT_DFF_MASK , +OMAP4430_PRM_PARTITION , +OMAP4430_PRM_CORE_INST , +OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET ); +} + +/**
arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 355
Quoted 10 lines
arch/arm/mach-omap2/prm44xx.c +10
-0+* omap4_device_next_state_off: +* returns true if the device next state is OFF +* This is API to check whether OMAP is programmed for device OFF +*/ +bool omap4_device_next_state_off (void ) +{ +return omap4_prminst_read_inst_reg (OMAP4430_PRM_PARTITION , +OMAP4430_PRM_DEVICE_INST , +OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET ) + &OMAP4430_DEVICE_OFF_ENABLE_MASK ? true : false;
minor: when using these long register read helpers, IMO readability improves if this is of the form:
val = <read register>;
val &= <mask>;
return val ? true : false;arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 360
Quoted 5 lines
arch/arm/mach-omap2/prm44xx.c +2
-0+} +static int __init omap4xxx_prcm_init (void ) {if (cpu_is_omap44xx ()) {
Kevin
PATCH v2 3/19 ARM: OMAP4: PM: Add device-off support
Quoted 47 lines · Kevin Hilman
+Jean for functional power states
Quoted 1 line · Tero Kristo
This patch adds device off support to OMAP4 device type.
Description is rather thin for a patch that is doing so much.
Quoted 1 line
OFF mode is disabled by default,
why?
Quoted 5 lines
however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).This part needs to be a separate patch.
But, as stated in the core retention series, I'd like to move away from these global flags all together.
The way we manage the disabling of certain states (like off) is already clumsy for OMAP3, and it's getting worse with OMAP4. ?Basically, I think this feature needs to be supported by using constraints on functional power states. ? Having checks all over the place is getting unwieldy and not attractive to maintain.
The combination of constraints and functional power states should make this much more manageable. ? Until we have that, I'd prefer to keep the debugfs enable/disable stuff as separate patches at the end of the series used only for testing.
Quoted 2 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]then the sign-off above from Santosh probably doesn't apply anymore. You should change that to a Cc and just mention tht this is based upon some original work from Santosh.
First, ?some general comments:
There is a lot going on in this patch, so it is hard to follow what all is related, and why. ?Just a quick glance suggests it needs to be broken up into at least a few parts:
Quoted 10 lines
- low-level PRM support: new APIs for various off-mode features) ?(should probably be done on top of functional power states)
- powerdomain core support or "achievable" states ?(should probably be done on top of functional power states)
- IRQ/GIC context save/restore
- secure RAM save/restore (this has been tightly coupled to the GIC ?but it's not obvious why)
- PM debug support to enable/disable off-mode
?(for testing only, not for merge)
Further split sounds good to me.
Regards
santosh
PATCH v2 3/19 ARM: OMAP4: PM: Add device-off support
In reply to Kevin HilmanQuoted 11 lines · Kevin Hilman
+Jean for functional power states
Quoted 1 line · Tero Kristo
This patch adds device off support to OMAP4 device type.
Description is rather thin for a patch that is doing so much.
Quoted 1 line
OFF mode is disabled by default,
why?
Good question. For historical reference I guess. The device off works pretty nicely with the current kernel already, so it should be possible to enable it by default and blame the people who break it.
Quoted 18 lines
Quoted 6 lines
however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).This part needs to be a separate patch.
But, as stated in the core retention series, I'd like to move away from these global flags all together.
The way we manage the disabling of certain states (like off) is already clumsy for OMAP3, and it's getting worse with OMAP4. Basically, I think this feature needs to be supported by using constraints on functional
power states. Having checks all over the place is getting unwieldy and
not attractive to maintain.
Quoted 4 lines
The combination of constraints and functional power states should make
this much more manageable. Until we have that, I'd prefer to keep
the debugfs enable/disable stuff as separate patches at the end of the series used only for testing.
Okay, this sounds like a good plan.
Quoted 7 lines
Quoted 3 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]then the sign-off above from Santosh probably doesn't apply anymore. You should change that to a Cc and just mention tht this is based upon some original work from Santosh.
Yeah... I am not quite sure where the line goes here as I am modifying the patches quite heavily but try to keep credits to the original authors... will change this like so.
Quoted 6 lines
First, some general comments:
There is a lot going on in this patch, so it is hard to follow what all is related, and why. Just a quick glance suggests it needs to be broken up into at least a few parts:
What is the merge plan for the func power state stuff? I don't want to create new dependencies if unnecessary. Otherwise the split should be okay.
Quoted 8 lines
- low-level PRM support: new APIs for various off-mode features) (should probably be done on top of functional power states)
- powerdomain core support or "achievable" states (should probably be done on top of functional power states)
- IRQ/GIC context save/restore
- secure RAM save/restore (this has been tightly coupled to the GIC but it's not obvious why)
This is tightly coupled to GIC because the ROM code has following API calls:
- save gic
- save secure RAM
- save secure all (gic + RAM + some other mysterious stuff)
It is difficult/impossible to separate these without adding redundant code execution (e.g. doing a GIC save from the GIC code + then doing a second GIC save with save secure all from core PM code.)
Quoted 35 lines
- PM debug support to enable/disable off-mode
(for testing only, not for merge)Quoted 23 lines
Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 10 ++++- arch/arm/mach-omap2/omap-wakeupgen.c | 47 +++++++++++++++++++- arch/arm/mach-omap2/pm-debug.c | 17 +++++-- arch/arm/mach-omap2/pm.h | 20 +++++++++ arch/arm/mach-omap2/pm44xx.c | 45 +++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 66 +++++++++++++++++++++++++++++ 6 files changed, 197 insertions(+), 8 deletions(-)arch/arm/mach-omap2/omap-mpuss-lowpower.c +1
-0@@ -60,6 +60,7 @@#include "prcm44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" +#include "cm44xx.h" #ifdef CONFIG_SMP arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 268
Quoted 6 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +2
-1@@ -263,9 +264,13 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); - if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) && +if (omap4_device_next_state_off ()) + save_state =3 ;Why?
Quoted 2 lines
I don't see why this check is needed in addition to the
mpuss_pdcheck added just below?
mpuss_pd does not go to off, thats why. It goes to OSWR state during standard device-off. It is possible for it to go to OFF mode, but it is not recommended.
Quoted 12 lines
Quoted 12 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0+else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) save_state =2 ; +else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) + save_state =3 ;cpu_clear_prev_logic_pwrst (cpu);set_cpu_next_pwrst (cpu, power_state);@@ -288,6 +293,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON );
Quoted 7 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 298
Quoted 3 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0+if (omap4_device_prev_state_off ()) +omap4_device_clear_prev_off_state (); +The 'clear prev off state' is subsequently removed in the last patch "ARM: OMAP4: powerdomain: update mpu / core off counters during device
off." Why is it needed here?
That patch is moving the clear part to the lost_context_rff func, it is probably not that clear. Should be easier to follow the logic once I re-structure the code a bit more (separate the prm support funcs out to their own set etc.)
Quoted 47 lines
Quoted 47 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0pwrdm_post_transition ();return 0 ;arch/arm/mach-omap2/omap-wakeupgen.c +5
-2@@ -32,6 +32,7 @@#include "omap4-sar-layout.h" #include "common.h" +#include "pm.h" #define NR_REG_BANKS 4#define MAX_IRQS 128@@ -46,6 +47,8 @@ static void __iomem *sar_base;static DEFINE_SPINLOCK (wakeupgen_lock);static unsigned int irq_target_cpu[NR_IRQS ]; +static struct powerdomain *mpuss_pd; +/* * Static helper functions. */ @@ -259,7 +262,7 @@ static void irq_save_context(void)/* * Clear WakeupGen SAR backup status. */ -void irq_sar_clear (void ) +static void irq_sar_clear (void ) {u32 val; val =__raw_readl (sar_base +SAR_BACKUP_STATUS_OFFSET );@@ -271,7 +274,7 @@ void irq_sar_clear(void)* Save GIC and Wakeupgen interrupt context using secure API * for HS/EMU devices. */ -static void irq_save_secure_context (void ) +static void irq_save_secure_gic (void ) {u32 ret; ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,@@ -282,6 +285,40 @@ static void irq_save_secure_context(void) }#endif
Quoted 5 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 290
Quoted 3 lines
arch/arm/mach-omap2/omap-wakeupgen.c +3
-0+static void save_secure_ram (void ) +{ +u32 ret;CodingStyle nit: blank line needed here (and in multiple other places)
Okay.
Quoted 14 lines
Quoted 14 lines
arch/arm/mach-omap2/omap-wakeupgen.c +13
-0+ ret =omap_secure_dispatcher (OMAP4_HAL_SAVESECURERAM_INDEX , +FLAG_START_CRITICAL , +1 ,omap_secure_ram_mempool_base (), +0 ,0 ,0 ); +if (ret !=API_HAL_RET_VALUE_OK ) +pr_err ("Secure ram context save failed\n" ); +} + +static void save_secure_all (void ) +{ +u32 ret; + ret = omap_secure_dispatcher(OMAP4_HAL_SAVEALL_INDEX, + FLAG_START_CRITICAL,
Quoted 8 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 308
Quoted 5 lines
arch/arm/mach-omap2/omap-wakeupgen.c +5
-0+1 ,omap_secure_ram_mempool_base (), + 0, 0, 0); +if (ret !=API_HAL_RET_VALUE_OK ) +pr_err ("Secure all context save failed\n" ); +}This secure mode save/restore seems misplaced in the wakeupgen driver. Seems to me like it belongs in
omap-secure.c.
Can't really move it there, as described above. Unless we want to save GIC context twice.
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 314
Quoted 7 lines
arch/arm/mach-omap2/omap-wakeupgen.c +6
-0+ +static void irq_save_secure_context (void ) +{ +if (omap4_device_next_state_off ()) { +save_secure_all (); + }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) {Why is this check needed? This is called from the
CPU_CLUSTER_PM_ENTERnotifier, which AFAICT, is only called when the cluster is going off.
This is checking against the different MPU PD states we can go into. If:
- MPU OSWR => GIC save needed only
- MPU OFF => GIC + secure RAM save needed (not recommended to be used though)
- MPU OSWR / OFF + device-off => save all needed
Quoted 143 lines
Quoted 127 lines
arch/arm/mach-omap2/omap-wakeupgen.c +13
-0+irq_save_secure_gic (); +save_secure_ram (); + }else { +irq_save_secure_gic (); + } +} +#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit irq_cpu_hotplug_notify (struct notifier_block *self,unsigned long action,void *hcpu)@@ -388,5 +425,11 @@ int __init omap_wakeupgen_init(void)irq_hotplug_init ();irq_pm_init (); + mpuss_pd =pwrdm_lookup ("mpu_pwrdm" ); +if (!mpuss_pd) { +pr_err ("wakeupgen: unable to get mpu_pwrdm\n" ); +return -EINVAL ; + } +return 0 ; }arch/arm/mach-omap2/pm-debug.c +12
-5@@ -40,6 +40,7 @@u32 enable_off_mode;static u32 enable_oswr_mode; +static void (*off_mode_enable_func) (int );#ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> @@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)else omap_pm_disable_off_mode (); -omap3_pm_off_mode_enable (val); +if (off_mode_enable_func) +off_mode_enable_func (val); }if (option == &enable_oswr_mode)@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void)pwrdm_for_each (pwrdms_setup, (void *)d); -if (cpu_is_omap34xx ()) - (void )debugfs_create_file ("enable_off_mode" , -S_IRUGO |S_IWUSR , d, &enable_off_mode, - &pm_dbg_option_fops); + (void )debugfs_create_file ("enable_off_mode" , +S_IRUGO |S_IWUSR , d, &enable_off_mode, + &pm_dbg_option_fops);if (cpu_is_omap44xx ()) (void )debugfs_create_file ("enable_oswr_mode" ,S_IRUGO |S_IWUSR , d, &enable_oswr_mode, &pm_dbg_option_fops); +if (cpu_is_omap34xx ()) + off_mode_enable_func = omap3_pm_off_mode_enable; + +if (cpu_is_omap44xx ()) + off_mode_enable_func = omap4_pm_off_mode_enable; + pm_dbg_init_done =1 ;return 0 ;arch/arm/mach-omap2/pm.h +20
-0@@ -18,6 +18,7 @@extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap4_pm_oswr_mode_enable (int ); +extern void omap4_pm_off_mode_enable (int );extern void omap_sram_idle (void );extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap3_idle_init (void );@@ -25,6 +26,25 @@ extern int omap4_idle_init(void);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void ); +#ifdef CONFIG_PM +extern void omap4_device_set_state_off (u8 enable); +extern bool omap4_device_prev_state_off (void ); +extern bool omap4_device_next_state_off (void ); +extern void omap4_device_clear_prev_off_state (void ); +#else +static inline void omap4_device_set_state_off (u8 enable) +{ +} +static inline bool omap4_device_prev_state_off (void ) +{ +return false; +} +static inline bool omap4_device_next_state_off (void ) +{ +return false; +} +#endif +#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );extern int omap4_opp_init (void );arch/arm/mach-omap2/pm44xx.c +10
-0@@ -87,6 +87,27 @@ static int omap4_pm_suspend(void) }#endif /* CONFIG_SUSPEND */ +/** +* get_achievable_state() - Provide achievable state +* @available_states: what states are available +* @req_min_state: what state is the minimum we'd like to hit +* +* Power domains have varied capabilities. When attempting a low power +* state such as OFF/RET, a specific min requested state may not be +* supported on the power domain, in which case, the next higher power +* state which is supported is returned. This is because a combination +* of system power states where the parent PD's state is not in line arch/arm/mach-omap2/pm44xx.c static int omap4_pm_suspend(void) · line 109
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+* with expectation can result in system instabilities. +*/ +static inline u8 get_achievable_state (u8 available_states,u8 req_min_state) +{ +u16 mask =0xFF << req_min_state; + +if (available_states & mask) +return __ffs (available_states & mask); +return PWRDM_POWER_ON ; +}This feature needs to be generalized (preferably on top of functional power states) because we have the same need on various AM3xxx SoCs which don't support RET/OFF. Mark Greer has started on this, but I think it needs to be part of the functional power states work.
Quoted 1 line
It also needs to be part of the powerdomain layer, IMO.
So, are you saying this whole set should be re-based on top of the functional power states stuff? If yes, that can be done (Jean actually already did some work on this and got it working I think.)
Quoted 71 lines
Quoted 56 lines
arch/arm/mach-omap2/pm44xx.c +24
-0static int __init pwrdms_setup (struct powerdomain *pwrdm,void *unused) {struct power_state *pwrst;@@ -115,6 +136,30 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)return omap_set_pwrdm_state (pwrst->pwrdm, pwrst->next_state); } +void omap4_pm_off_mode_enable (int enable) +{ +u32 next_state =PWRDM_POWER_RET ; +u32 next_logic_state =PWRDM_POWER_ON ; +struct power_state *pwrst; + +if (enable) { + next_state =PWRDM_POWER_OFF ; + next_logic_state =PWRDM_POWER_OFF ; + } + +omap4_device_set_state_off (enable); + +list_for_each_entry (pwrst, &pwrst_list, node) { + pwrst->next_state = +get_achievable_state (pwrst->pwrdm->pwrsts, next_state); + pwrst->next_logic_state = +get_achievable_state (pwrst->pwrdm->pwrsts_logic_ret, + next_logic_state); +omap_set_pwrdm_state (pwrst->pwrdm, pwrst->next_state); +pwrdm_set_logic_retst (pwrst->pwrdm, pwrst->next_logic_state); + } +} +void omap4_pm_oswr_mode_enable (int enable) {u32 next_logic_state;arch/arm/mach-omap2/prm44xx.c +13
-0@@ -289,6 +289,72 @@ static void __init omap44xx_prm_enable_io_wakeup(void) OMAP4_PRM_IO_PMCTRL_OFFSET); } +/** +* omap4_device_set_state_off() - setup device off state +* @enable: set to off or not. +* +* When Device OFF is enabled, Device is allowed to perform +* transition to off mode as soon as all power domains in MPU, IVA +* and CORE voltage are in OFF or OSWR state (open switch retention) +*/ +void omap4_device_set_state_off (u8 enable) +{ +if (enable) + omap4_prminst_write_inst_reg(0x1 << + OMAP4430_DEVICE_OFF_ENABLE_SHIFT,arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 314
Quoted 10 lines
arch/arm/mach-omap2/prm44xx.c +10
-0+OMAP4430_PRM_PARTITION , +OMAP4430_PRM_DEVICE_INST , + OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET); + else + omap4_prminst_write_inst_reg(0x0 << +OMAP4430_DEVICE_OFF_ENABLE_SHIFT , +OMAP4430_PRM_PARTITION , +OMAP4430_PRM_DEVICE_INST , +OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET ); +}minor: a more compact, and more readable (so it's obvious at first glance that the same register is being written) would be:
void
omap4_device_set_state_off(u8 enable)
Quoted 9 lines
{
u8 val = enable ? 0x1 : 0x0;
omap4_prminst_write_inst_reg(val <<
OMAP4430_DEVICE_OFF_ENABLE_SHIFT,
OMAP4430_PRM_PARTITION,
OMAP4430_PRM_DEVICE_INST,
OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET);
}True.
Quoted 15 lines
arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 326
Quoted 12 lines
arch/arm/mach-omap2/prm44xx.c +11
-0+/** +* omap4_device_prev_state_off: +* returns true if the device hit OFF mode +* This is API to check whether OMAP is waking up from device OFF mode. +* There is no other status bit available for SW to read whether last state +* entered was device OFF. To work around this, CORE PD, RFF context state +* is used which is lost only when we hit device OFF state +*/ +bool omap4_device_prev_state_off (void ) +{ +u32 reg;minor: reg makes me think the result of the read is a register address, not a value. How about s/reg/val/.
Yea, good point.
Quoted 33 lines
Quoted 19 lines
arch/arm/mach-omap2/prm44xx.c +18
-0+ reg =omap4_prminst_read_inst_reg (OMAP4430_PRM_PARTITION , +OMAP4430_PRM_CORE_INST , +OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET ) + &OMAP4430_LOSTCONTEXT_RFF_MASK ; + +return reg ? true : false; +} + +void omap4_device_clear_prev_off_state (void ) +{ +omap4_prminst_write_inst_reg (OMAP4430_LOSTCONTEXT_RFF_MASK | +OMAP4430_LOSTCONTEXT_DFF_MASK , +OMAP4430_PRM_PARTITION , +OMAP4430_PRM_CORE_INST , +OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET ); +} + +/** arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 355
Quoted 10 lines
arch/arm/mach-omap2/prm44xx.c +10
-0+* omap4_device_next_state_off: +* returns true if the device next state is OFF +* This is API to check whether OMAP is programmed for device OFF +*/ +bool omap4_device_next_state_off (void ) +{ +return omap4_prminst_read_inst_reg (OMAP4430_PRM_PARTITION , +OMAP4430_PRM_DEVICE_INST , +OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET ) + &OMAP4430_DEVICE_OFF_ENABLE_MASK ? true : false;minor: when using these long register read helpers, IMO readability improves if this is of the form:
Quoted 3 lines
val = <read register>;
val &= <mask>;
return val ? true : false;True.
Quoted 9 lines
arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 360
Quoted 6 lines
arch/arm/mach-omap2/prm44xx.c +2
-0+} +static int __init omap4xxx_prcm_init (void ) {if (cpu_is_omap44xx ()) {Kevin
PATCH v2 3/19 ARM: OMAP4: PM: Add device-off support
Hi Tero, Kevin, Santosh,
Quoted 9 lines · Tero Kristo
Quoted 8 lines · Kevin Hilman
+Jean for functional power states
Quoted 1 line · Tero Kristo
This patch adds device off support to OMAP4 device type.
Description is rather thin for a patch that is doing so much.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
OFF mode is disabled by default,
why?
Good question. For historical reference I guess. The device off works pretty nicely with the current kernel already, so it should be possible to enable it by default and blame the people who break it.
Agree. The next problem is 'who will fix the breakage?'.
Quoted 39 lines
Quoted 17 lines
Quoted 5 lines
however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).This part needs to be a separate patch.
But, as stated in the core retention series, I'd like to move away from these global flags all together.
The way we manage the disabling of certain states (like off) is already clumsy for OMAP3, and it's getting worse with OMAP4. ?Basically, I think this feature needs to be supported by using constraints on functional power states. ? Having checks all over the place is getting unwieldy and not attractive to maintain.
Quoted 4 lines
The combination of constraints and functional power states should make this much more manageable. ? Until we have that, I'd prefer to keep the debugfs enable/disable stuff as separate patches at the end of the series used only for testing.
Okay, this sounds like a good plan.
Quoted 7 lines
Quoted 3 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]then the sign-off above from Santosh probably doesn't apply anymore. You should change that to a Cc and just mention tht this is based upon some original work from Santosh.
Yeah... I am not quite sure where the line goes here as I am modifying the patches quite heavily but try to keep credits to the original authors... will change this like so.
Quoted 3 lines
First, ?some general comments:
Quoted 7 lines
Quoted 3 lines
There is a lot going on in this patch, so it is hard to follow what all is related, and why. ?Just a quick glance suggests it needs to be broken up into at least a few parts:
What is the merge plan for the func power state stuff? I don't want to create new dependencies if unnecessary. Otherwise the split should be okay.
That is something I am interested in too ;p
I did port and test Tero's patches on top of the functional power states, which is the logical approach to me. Now given the reviews status on both this patch series and the func power states series I am not sure which one needs to be ported on top of the other ;-|
[1] https://gitorious.org/jpihet/linux-omap/commits/omap4_dev_off
Using the functional power states for the OMAP4 core and device off has some advantages in simplifying the code, especially in the previous/current/next states checking and programming.
Quoted 329 lines
Quoted 9 lines
- low-level PRM support: new APIs for various off-mode features) ? (should probably be done on top of functional power states)
- powerdomain core support or "achievable" states
? (should probably be done on top of functional power states)
- IRQ/GIC context save/restore
- secure RAM save/restore (this has been tightly coupled to the GIC ? but it's not obvious why)This is tightly coupled to GIC because the ROM code has following API calls:
- save gic
- save secure RAM
- save secure all (gic + RAM + some other mysterious stuff)It is difficult/impossible to separate these without adding redundant code execution (e.g. doing a GIC save from the GIC code + then doing a second GIC save with save secure all from core PM code.)
Quoted 35 lines
- PM debug support to enable/disable off-mode
? (for testing only, not for merge)Quoted 23 lines
Signed-off-by Tero Kristo <[email protected]>---
?arch/arm/mach-omap2/omap-mpuss-lowpower.c | ? 10 ++++- ?arch/arm/mach-omap2/omap-wakeupgen.c ? ? ?| ? 47 +++++++++++++++++++- ?arch/arm/mach-omap2/pm-debug.c ? ? ? ? ? ?| ? 17 +++++-- ?arch/arm/mach-omap2/pm.h ? ? ? ? ? ? ? ? ?| ? 20 +++++++++ ?arch/arm/mach-omap2/pm44xx.c ? ? ? ? ? ? ?| ? 45 +++++++++++++++++++ ?arch/arm/mach-omap2/prm44xx.c ? ? ? ? ? ? | ? 66 +++++++++++++++++++++++++++++?6 files changed, 197 insertions(+), 8 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0@@ -60,6 +60,7 @@?#include "
prcm44xx.h"
?#include "prm44xx.h"
?#include "prm-regbits-44xx.h"
+#include "cm44xx.h"?#ifdef
CONFIG_SMParch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0@@ -263,9 +264,13 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)Quoted 6 lines
? ? ?* In MPUSS OSWR or device OFF, interrupt controller ?contest is lost. ? ? ?*/
? ?mpuss_clear_prev_logic_pwrst();
- ? if ((pwrdm_read_next_pwrst(mpuss_pd)==PWRDM_POWER_RET) &&
+ ? if (omap4_device_next_state_off())
+ ? ? ? ? ?save_state= 3;Why?
Quoted 2 lines
I don't see why this check is needed in addition to the
mpuss_pdcheck added just below?
mpuss_pddoes not go to off, thats why. It goes to OSWR state during standard device-off. It is possible for it to go to OFF mode, but it is not recommended.Quoted 12 lines
Quoted 12 lines
+ ? else if ((
pwrdm_read_next_pwrst(mpuss_pd)==PWRDM_POWER_RET) && ? ? ? ? ? ? (pwrdm_read_logic_retst(mpuss_pd)==PWRDM_POWER_OFF)) ? ? ? ? ? ?save_state= 2;
+ ? else if (pwrdm_read_next_pwrst(mpuss_pd)==PWRDM_POWER_OFF)
+ ? ? ? ? ?save_state= 3;
? ?cpu_clear_prev_logic_pwrst(cpu);
? ?set_cpu_next_pwrst(cpu, power_state);arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0@@ -288,6 +293,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) ? ? wakeup_cpu = smp_processor_id(); ? ? set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON);Quoted 7 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 298
Quoted 3 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0+ ? if (omap4_device_prev_state_off()) + ? ? ? ? ? omap4_device_clear_prev_off_state(); +The 'clear prev off state' is subsequently removed in the last patch "ARM: OMAP4: powerdomain: update mpu / core off counters during device off." ? Why is it needed here?
That patch is moving the clear part to the
lost_context_rfffunc, it is probably not that clear. Should be easier to follow the logic once I re-structure the code a bit more (separate the prm support funcs out to their own set etc.)Quoted 47 lines
Quoted 47 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0? ? pwrdm_post_transition(); ? ? return 0;arch/arm/mach-omap2/omap-wakeupgen.c +0
-0@@ -32,6 +32,7 @@?#include "
omap4-sar-layout.h"
?#include "common.h"
+#include "pm.h"?#define
NR_REG_BANKS? ? ? ? ? ? ? 4
?#defineMAX_IRQS? ? ? ? ? 128arch/arm/mach-omap2/omap-wakeupgen.c +2
-0@@ -46,6 +47,8 @@ static void __iomem *sar_base; ?static DEFINE_SPINLOCK(wakeupgen_lock); ?static unsigned int irq_target_cpu[NR_IRQS]; +static struct powerdomain *mpuss_pd; +?/*
? * Static helper functions.
? */arch/arm/mach-omap2/omap-wakeupgen.c +0
-0@@ -259,7 +262,7 @@ static void irq_save_context(void)?/*
? * Clear WakeupGen SAR backup status.
? */arch/arm/mach-omap2/omap-wakeupgen.c +1
-1-void irq_sar_clear (void ) +static void irq_sar_clear (void )?{
? ? u32 val;
? ? val =__raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET);arch/arm/mach-omap2/omap-wakeupgen.c +0
-0@@ -271,7 +274,7 @@ void irq_sar_clear(void)? * Save GIC and Wakeupgen interrupt context using secure API ? * for HS/EMU devices.
? */arch/arm/mach-omap2/omap-wakeupgen.c +1
-1-static void irq_save_secure_context (void ) +static void irq_save_secure_gic (void )?{
? ? u32 ret;
? ? ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,arch/arm/mach-omap2/omap-wakeupgen.c +0
-0@@ -282,6 +285,40 @@ static void irq_save_secure_context(void) ?}?#endif
Quoted 5 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void)
Quoted 3 lines
arch/arm/mach-omap2/omap-wakeupgen.c +3
-0+static void save_secure_ram (void ) +{ + ? u32 ret;CodingStyle nit: blank line needed here (and in multiple other places)
Okay.
Quoted 14 lines
Quoted 14 lines
+ ? ret = omap_secure_dispatcher(OMAP4_HAL_SAVESECURERAM_INDEX,
+ ? ? ? ? ? ? ? ? ? ? ? ? ?FLAG_START_CRITICAL,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? 1,omap_secure_ram_mempool_base(),
+ ? ? ? ? ? ? ? ? ? ? ? ? ? 0, 0, 0);
+ ? if (ret !=API_HAL_RET_VALUE_OK)
+ ? ? ? ? ?pr_err("Secure ram context save failed\n");arch/arm/mach-omap2/omap-wakeupgen.c +7
-0+} + +static void save_secure_all (void ) +{ + ? u32 ret; + ? ret = omap_secure_dispatcher(OMAP4_HAL_SAVEALL_INDEX, + ? ? ? ? ? ? ? ? ? ? ? ? ? FLAG_START_CRITICAL,Quoted 8 lines
Quoted 5 lines
+ ? ? ? ? ? ? ? ? ? ? ? ? ? 1,
omap_secure_ram_mempool_base(),
+ ? ? ? ? ? ? ? ? ? ? ? ? ? 0, 0, 0);
+ ? if (ret !=API_HAL_RET_VALUE_OK)
+ ? ? ? ? ?pr_err("Secure all context save failed\n"); +}This secure mode save/restore seems misplaced in the wakeupgen driver. Seems to me like it belongs in
omap-secure.c.Can't really move it there, as described above. Unless we want to save GIC context twice.
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void)
Quoted 7 lines
arch/arm/mach-omap2/omap-wakeupgen.c +6
-0+ +static void irq_save_secure_context (void ) +{ + ? if (omap4_device_next_state_off()) { + ? ? ? ? ? save_secure_all(); + ? } else if (pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_OFF) {Why is this check needed? ?This is called from the
CPU_CLUSTER_PM_ENTERnotifier, which AFAICT, is only called when the cluster is going off.This is checking against the different MPU PD states we can go into. If:
- MPU OSWR => GIC save needed only
- MPU OFF => GIC + secure RAM save needed (not recommended to be used though)
- MPU OSWR / OFF + device-off => save all neededQuoted 143 lines
Quoted 127 lines
+ ? ? ? ? ?
irq_save_secure_gic();
+ ? ? ? ? ?save_secure_ram();
+ ? } else {
+ ? ? ? ? ?irq_save_secure_gic();
+ ? }arch/arm/mach-omap2/omap-wakeupgen.c +2
-0+} +?#ifdef
CONFIG_HOTPLUG_CPU
?static int__cpuinitirq_cpu_hotplug_notify(struct notifier_block *self, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned long action, void *hcpu)arch/arm/mach-omap2/omap-wakeupgen.c +6
-0@@ -388,5 +425,11 @@ int __init omap_wakeupgen_init(void) ? ? irq_hotplug_init(); ? ? irq_pm_init(); + ? mpuss_pd = pwrdm_lookup("mpu_pwrdm"); + ? if (!mpuss_pd) { + ? ? ? ? ? pr_err("wakeupgen: unable to get mpu_pwrdm\n"); + ? ? ? ? ? return -EINVAL; + ? } + ? ? return 0; ?}arch/arm/mach-omap2/pm-debug.c +1
-0@@ -40,6 +40,7 @@ ?u32 enable_off_mode; ?static u32 enable_oswr_mode; +static void (*off_mode_enable_func) (int );?#ifdef
CONFIG_DEBUG_FS
?#include <linux/debugfs.h>arch/arm/mach-omap2/pm-debug.c +0
-0@@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ?omap_pm_disable_off_mode();- ? ? ? ? ?
omap3_pm_off_mode_enable(val);
+ ? ? ? ? ? if (off_mode_enable_func)
+ ? ? ? ? ? ? ? ? ?off_mode_enable_func(val);
? ? }? ? if (option ==
&enable_oswr_mode)arch/arm/mach-omap2/pm-debug.c +9
-4@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void) ? ? pwrdm_for_each(pwrdms_setup, (void *)d); - ? if (cpu_is_omap34xx()) - ? ? ? ? ? (void) debugfs_create_file("enable_off_mode", - ? ? ? ? ? ? ? ? ? S_IRUGO | S_IWUSR, d, &enable_off_mode, - ? ? ? ? ? ? ? ? ? &pm_dbg_option_fops); + ? (void) debugfs_create_file("enable_off_mode", + ? ? ? ? ? S_IRUGO | S_IWUSR, d, &enable_off_mode, + ? ? ? ? ? &pm_dbg_option_fops); ? ? if (cpu_is_omap44xx()) ? ? ? ? ? ? (void) debugfs_create_file("enable_oswr_mode", ? ? ? ? ? ? ? ? ? ? S_IRUGO | S_IWUSR, d, &enable_oswr_mode, ? ? ? ? ? ? ? ? ? ? &pm_dbg_option_fops); + ? if (cpu_is_omap34xx()) + ? ? ? ? ? off_mode_enable_func = omap3_pm_off_mode_enable; + + ? if (cpu_is_omap44xx()) + ? ? ? ? ? off_mode_enable_func = omap4_pm_off_mode_enable; + ? ? pm_dbg_init_done = 1; ? ? return 0;arch/arm/mach-omap2/pm.h +20
-0@@ -18,6 +18,7 @@ ?extern void *omap3_secure_ram_storage; ?extern void omap3_pm_off_mode_enable(int); ?extern void omap4_pm_oswr_mode_enable(int); +extern void omap4_pm_off_mode_enable (int ); ?extern void omap_sram_idle(void); ?extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); ?extern int omap3_idle_init(void);@@ -25,6 +26,25 @@ extern int omap4_idle_init(void); ?extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused); ?extern int (*omap_pm_suspend)(void); +#ifdef CONFIG_PM +extern void omap4_device_set_state_off (u8 enable); +extern bool omap4_device_prev_state_off (void ); +extern bool omap4_device_next_state_off (void ); +extern void omap4_device_clear_prev_off_state (void ); +#else +static inline void omap4_device_set_state_off (u8 enable) +{ +} +static inline bool omap4_device_prev_state_off (void ) +{ + ? return false; +} +static inline bool omap4_device_next_state_off (void ) +{ + ? return false; +} +#endif + ?#if defined(CONFIG_PM_OPP) ?extern int omap3_opp_init(void); ?extern int omap4_opp_init(void);arch/arm/mach-omap2/pm44xx.c +0
-0@@ -87,6 +87,27 @@ static int omap4_pm_suspend(void) ?}?#endif /*
CONFIG_SUSPEND*/arch/arm/mach-omap2/pm44xx.c +10
-0+/** +* get_achievable_state() - Provide achievable state +* @available_states: ? ? ?what states are available +* @req_min_state: what state is the minimum we'd like to hit +* +* Power domains have varied capabilities. When attempting a low power +* state such as OFF/RET, a specific min requested state may not be +* supported on the power domain, in which case, the next higher power +* state which is supported is returned. This is because a combination +* of system power states where the parent PD's state is not in line arch/arm/mach-omap2/pm44xx.c static int omap4_pm_suspend(void) · line 109
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+* with expectation can result in system instabilities. +*/ +static inline u8 get_achievable_state(u8 available_states, u8 req_min_state) +{ + ? u16 mask = 0xFF << req_min_state; + + ? if (available_states & mask) + ? ? ? ? ? return __ffs(available_states & mask); + ? return PWRDM_POWER_ON; +}This feature needs to be generalized (preferably on top of functional power states) because we have the same need on various AM3xxx SoCs which don't support RET/OFF. ?Mark Greer has started on this, but I think it needs to be part of the functional power states work.
Quoted 5 lines
Quoted 1 line
It also needs to be part of the powerdomain layer, IMO.
So, are you saying this whole set should be re-based on top of the functional power states stuff? If yes, that can be done (Jean actually already did some work on this and got it working I think.)
Indeed, cf. [1]. It has been done and works on OMAP3&4 with cpuidle and suspend/resume.
Quoted 134 lines
Quoted 74 lines
Quoted 56 lines
?static int
__initpwrdms_setup(struct powerdomain *pwrdm, void *unused)?{
? ? structpower_state*pwrst;arch/arm/mach-omap2/pm44xx.c +24
-0@@ -115,6 +136,30 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) ? ? return omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); ?} +void omap4_pm_off_mode_enable(int enable) +{ + ? u32 next_state = PWRDM_POWER_RET; + ? u32 next_logic_state = PWRDM_POWER_ON; + ? struct power_state *pwrst; + + ? if (enable) { + ? ? ? ? ? next_state = PWRDM_POWER_OFF; + ? ? ? ? ? next_logic_state = PWRDM_POWER_OFF; + ? } + + ? omap4_device_set_state_off(enable); + + ? list_for_each_entry(pwrst, &pwrst_list, node) { + ? ? ? ? ? pwrst->next_state = + ? ? ? ? ? ? ? ? ? get_achievable_state(pwrst->pwrdm->pwrsts, next_state); + ? ? ? ? ? pwrst->next_logic_state = + ? ? ? ? ? ? ? ? ? get_achievable_state(pwrst->pwrdm->pwrsts_logic_ret, + ? ? ? ? ? ? ? ? ? ? ? ? ? next_logic_state); + ? ? ? ? ? omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state); + ? ? ? ? ? pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->next_logic_state); + ? } +} + ?void omap4_pm_oswr_mode_enable(int enable) ?{ ? ? u32 next_logic_state;arch/arm/mach-omap2/prm44xx.c +13
-0@@ -289,6 +289,72 @@ static void __init omap44xx_prm_enable_io_wakeup(void) ? ? ? ? ? ? ? ? ? ? OMAP4_PRM_IO_PMCTRL_OFFSET); ?} +/** +* omap4_device_set_state_off() - setup device off state +* @enable: ? ? ? ?set to off or not. +* +* When Device OFF is enabled, Device is allowed to perform +* transition to off mode as soon as all power domains in MPU, IVA +* and CORE voltage are in OFF or OSWR state (open switch retention) +*/ +void omap4_device_set_state_off (u8 enable) +{ + ? if (enable) + ? ? ? ? ? omap4_prminst_write_inst_reg(0x1 << + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_DEVICE_OFF_ENABLE_SHIFT,arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 314
Quoted 10 lines
arch/arm/mach-omap2/prm44xx.c +10
-0+ ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_PRM_PARTITION, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_PRM_DEVICE_INST, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET); + ? else + ? ? ? ? ? omap4_prminst_write_inst_reg(0x0 << + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_DEVICE_OFF_ENABLE_SHIFT, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_PRM_PARTITION, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_PRM_DEVICE_INST, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET); +}minor: a more compact, and more readable (so it's obvious at first glance that the same register is being written) would be:
void
omap4_device_set_state_off(u8 enable)
{
? ? ? ? u8 val = enable ?0x1:0x0;Quoted 6 lines
? ? ? omap4_prminst_write_inst_reg(val <<
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OMAP4430_DEVICE_OFF_ENABLE_SHIFT, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OMAP4430_PRM_PARTITION, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OMAP4430_PRM_DEVICE_INST, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET); }True.
Quoted 15 lines
arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void)
Quoted 12 lines
arch/arm/mach-omap2/prm44xx.c +11
-0+/** +* omap4_device_prev_state_off: +* returns true if the device hit OFF mode +* This is API to check whether OMAP is waking up from device OFF mode. +* There is no other status bit available for SW to read whether last state +* entered was device OFF. To work around this, CORE PD, RFF context state +* is used which is lost only when we hit device OFF state +*/ +bool omap4_device_prev_state_off (void ) +{ + ? u32 reg;minor: reg makes me think the result of the read is a register address, not a value. ?How about s/reg/val/.
Yea, good point.
Quoted 33 lines
Quoted 19 lines
arch/arm/mach-omap2/prm44xx.c +18
-0+ ? reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_PRM_CORE_INST, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET) + ? ? ? ? ? & OMAP4430_LOSTCONTEXT_RFF_MASK; + + ? return reg ? true : false; +} + +void omap4_device_clear_prev_off_state (void ) +{ + ? omap4_prminst_write_inst_reg(OMAP4430_LOSTCONTEXT_RFF_MASK | + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_LOSTCONTEXT_DFF_MASK, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_PRM_PARTITION, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4430_PRM_CORE_INST, + ? ? ? ? ? ? ? ? ? ? ? ? ? OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET); +} + +/** arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void)
Quoted 10 lines
arch/arm/mach-omap2/prm44xx.c +10
-0+* omap4_device_next_state_off: +* returns true if the device next state is OFF +* This is API to check whether OMAP is programmed for device OFF +*/ +bool omap4_device_next_state_off (void ) +{ + ? return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, + ? ? ? ? ? ? ? ? ? OMAP4430_PRM_DEVICE_INST, + ? ? ? ? ? ? ? ? ? OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET) + ? ? ? ? ? ? ? ? ? & OMAP4430_DEVICE_OFF_ENABLE_MASK ? true : false;minor: when using these long register read helpers, IMO readability improves if this is of the form:
Quoted 17 lines
Quoted 3 lines
? ? ? ?val = <read register>;
? ? ? ?val &= <mask>;
? ? ? ?return val ? true : false;True.
Quoted 9 lines
arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 358
Quoted 6 lines
arch/arm/mach-omap2/prm44xx.c +2
-0+} + ?static int __init omap4xxx_prcm_init(void) ?{ ? ? if (cpu_is_omap44xx()) {Kevin
Jean
PATCH v2 3/19 ARM: OMAP4: PM: Add device-off support
Quoted 74 lines · Jean Pihet
Hi Tero, Kevin, Santosh,
Quoted 9 lines · Tero Kristo
Quoted 8 lines · Kevin Hilman
+Jean for functional power states
Quoted 1 line · Tero Kristo
This patch adds device off support to OMAP4 device type.
Description is rather thin for a patch that is doing so much.
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
OFF mode is disabled by default,
why?
Good question. For historical reference I guess. The device off works pretty nicely with the current kernel already, so it should be possible to enable it by default and blame the people who break it.
Agree. The next problem is 'who will fix the breakage?'.
Quoted 39 lines
Quoted 17 lines
Quoted 5 lines
however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).This part needs to be a separate patch.
But, as stated in the core retention series, I'd like to move away from these global flags all together.
The way we manage the disabling of certain states (like off) is already clumsy for OMAP3, and it's getting worse with OMAP4. ?Basically, I think this feature needs to be supported by using constraints on functional power states. ? Having checks all over the place is getting unwieldy and not attractive to maintain.
Quoted 4 lines
The combination of constraints and functional power states should make this much more manageable. ? Until we have that, I'd prefer to keep the debugfs enable/disable stuff as separate patches at the end of the series used only for testing.
Okay, this sounds like a good plan.
Quoted 7 lines
Quoted 3 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]then the sign-off above from Santosh probably doesn't apply anymore. You should change that to a Cc and just mention tht this is based upon some original work from Santosh.
Yeah... I am not quite sure where the line goes here as I am modifying the patches quite heavily but try to keep credits to the original authors... will change this like so.
Quoted 3 lines
First, ?some general comments:
Quoted 7 lines
Quoted 3 lines
There is a lot going on in this patch, so it is hard to follow what all is related, and why. ?Just a quick glance suggests it needs to be broken up into at least a few parts:
What is the merge plan for the func power state stuff? I don't want to create new dependencies if unnecessary. Otherwise the split should be okay.
That is something I am interested in too ;p
I did port and test Tero's patches on top of the functional power states, which is the logical approach to me. Now given the reviews status on both this patch series and the func power states series I am not sure which one needs to be ported on top of the other ;-|
[1] https://gitorious.org/jpihet/linux-omap/commits/omap4_dev_off
Quoted 3 lines
Using the functional power states for the OMAP4 core and device off has some advantages in simplifying the code, especially in the previous/current/next states checking and programming.
For these reasons, I suggest basing this series on top of the functional power states series.
Kevin
PATCH v2 3/19 ARM: OMAP4: PM: Add device-off support
In reply to Tero KristoQuoted 46 lines · Tero Kristo
Quoted 11 lines · Kevin Hilman
+Jean for functional power states
Quoted 1 line · Tero Kristo
This patch adds device off support to OMAP4 device type.
Description is rather thin for a patch that is doing so much.
Quoted 1 line
OFF mode is disabled by default,
why?
Good question. For historical reference I guess. The device off works pretty nicely with the current kernel already, so it should be possible to enable it by default and blame the people who break it.
Quoted 18 lines
Quoted 6 lines
however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).This part needs to be a separate patch.
But, as stated in the core retention series, I'd like to move away from these global flags all together.
The way we manage the disabling of certain states (like off) is already clumsy for OMAP3, and it's getting worse with OMAP4. Basically, I think this feature needs to be supported by using constraints on functional
power states. Having checks all over the place is getting unwieldy and
not attractive to maintain.Quoted 4 lines
The combination of constraints and functional power states should make
this much more manageable. Until we have that, I'd prefer to keep
the debugfs enable/disable stuff as separate patches at the end of the series used only for testing.Okay, this sounds like a good plan.
Quoted 4 lines
Quoted 3 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]
Quoted 7 lines
Quoted 3 lines
then the sign-off above from Santosh probably doesn't apply anymore. You should change that to a Cc and just mention tht this is based upon some original work from Santosh.
Yeah... I am not quite sure where the line goes here as I am modifying the patches quite heavily but try to keep credits to the original authors... will change this like so.
I guess it's up to you whether you keep Santosh as author. It all depends how much you've changed the original. But you can use the changlog to give credits to Santosh, or state it was a collaboration, whatever you like. You can say stuff like "based on an origianl patch by...", and/or briefly summarize the changes you made from the original verions, etc.
Quoted 22 lines
Quoted 6 lines
First, some general comments:
There is a lot going on in this patch, so it is hard to follow what all is related, and why. Just a quick glance suggests it needs to be broken up into at least a few parts:
What is the merge plan for the func power state stuff? I don't want to create new dependencies if unnecessary. Otherwise the split should be okay.
Quoted 8 lines
- low-level PRM support: new APIs for various off-mode features) (should probably be done on top of functional power states)
- powerdomain core support or "achievable" states (should probably be done on top of functional power states)
- IRQ/GIC context save/restore
- secure RAM save/restore (this has been tightly coupled to the GIC but it's not obvious why)This is tightly coupled to GIC because the ROM code has following API calls:
Quoted 7 lines
- save gic
- save secure RAM
- save secure all (gic + RAM + some other mysterious stuff)It is difficult/impossible to separate these without adding redundant code execution (e.g. doing a GIC save from the GIC code + then doing a second GIC save with save secure all from core PM code.)
Ok, thanks for clarifying.
That should be explained in the changelog for this patch when it's broken up.
Quoted 35 lines
Quoted 35 lines
- PM debug support to enable/disable off-mode
(for testing only, not for merge)Quoted 23 lines
Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 10 ++++- arch/arm/mach-omap2/omap-wakeupgen.c | 47 +++++++++++++++++++- arch/arm/mach-omap2/pm-debug.c | 17 +++++-- arch/arm/mach-omap2/pm.h | 20 +++++++++ arch/arm/mach-omap2/pm44xx.c | 45 +++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 66 +++++++++++++++++++++++++++++ 6 files changed, 197 insertions(+), 8 deletions(-)arch/arm/mach-omap2/omap-mpuss-lowpower.c +1
-0@@ -60,6 +60,7 @@#include "prcm44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" +#include "cm44xx.h" #ifdef CONFIG_SMP arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 268
Quoted 6 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +2
-1@@ -263,9 +264,13 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); - if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) && +if (omap4_device_next_state_off ()) + save_state =3 ;Why?
Quoted 6 lines
Quoted 2 lines
I don't see why this check is needed in addition to the
mpuss_pdcheck added just below?
mpuss_pddoes not go to off, thats why. It goes to OSWR state during standard device-off. It is possible for it to go to OFF mode, but it is not recommended.
What is confusing is that the check below specifically checks for mpuss_pd == off.
Quoted 20 lines
Quoted 12 lines
Quoted 12 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0+else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) save_state =2 ; +else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) + save_state =3 ;cpu_clear_prev_logic_pwrst (cpu);set_cpu_next_pwrst (cpu, power_state);@@ -288,6 +293,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON );Quoted 7 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 298
Quoted 3 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0+if (omap4_device_prev_state_off ()) +omap4_device_clear_prev_off_state (); +The 'clear prev off state' is subsequently removed in the last patch "ARM: OMAP4: powerdomain: update mpu / core off counters during device
off." Why is it needed here?
Quoted 4 lines
That patch is moving the clear part to the
lost_context_rfffunc, it is probably not that clear. Should be easier to follow the logic once I re-structure the code a bit more (separate the prm support funcs out to their own set etc.)
Yes, thanks.
Quoted 78 lines
Quoted 47 lines
Quoted 47 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0pwrdm_post_transition ();return 0 ;arch/arm/mach-omap2/omap-wakeupgen.c +5
-2@@ -32,6 +32,7 @@#include "omap4-sar-layout.h" #include "common.h" +#include "pm.h" #define NR_REG_BANKS 4#define MAX_IRQS 128@@ -46,6 +47,8 @@ static void __iomem *sar_base;static DEFINE_SPINLOCK (wakeupgen_lock);static unsigned int irq_target_cpu[NR_IRQS ]; +static struct powerdomain *mpuss_pd; +/* * Static helper functions. */ @@ -259,7 +262,7 @@ static void irq_save_context(void)/* * Clear WakeupGen SAR backup status. */ -void irq_sar_clear (void ) +static void irq_sar_clear (void ) {u32 val; val =__raw_readl (sar_base +SAR_BACKUP_STATUS_OFFSET );@@ -271,7 +274,7 @@ void irq_sar_clear(void)* Save GIC and Wakeupgen interrupt context using secure API * for HS/EMU devices. */ -static void irq_save_secure_context (void ) +static void irq_save_secure_gic (void ) {u32 ret; ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,@@ -282,6 +285,40 @@ static void irq_save_secure_context(void) }#endif Quoted 5 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 290
Quoted 3 lines
arch/arm/mach-omap2/omap-wakeupgen.c +3
-0+static void save_secure_ram (void ) +{ +u32 ret;CodingStyle nit: blank line needed here (and in multiple other places)
Okay.
Quoted 14 lines
Quoted 14 lines
arch/arm/mach-omap2/omap-wakeupgen.c +13
-0+ ret =omap_secure_dispatcher (OMAP4_HAL_SAVESECURERAM_INDEX , +FLAG_START_CRITICAL , +1 ,omap_secure_ram_mempool_base (), +0 ,0 ,0 ); +if (ret !=API_HAL_RET_VALUE_OK ) +pr_err ("Secure ram context save failed\n" ); +} + +static void save_secure_all (void ) +{ +u32 ret; + ret = omap_secure_dispatcher(OMAP4_HAL_SAVEALL_INDEX, + FLAG_START_CRITICAL,Quoted 8 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 308
Quoted 5 lines
arch/arm/mach-omap2/omap-wakeupgen.c +5
-0+1 ,omap_secure_ram_mempool_base (), + 0, 0, 0); +if (ret !=API_HAL_RET_VALUE_OK ) +pr_err ("Secure all context save failed\n" ); +}This secure mode save/restore seems misplaced in the wakeupgen driver. Seems to me like it belongs in
omap-secure.c.
Quoted 2 lines
Can't really move it there, as described above. Unless we want to save GIC context twice.
OK
Quoted 11 lines
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 314
Quoted 7 lines
arch/arm/mach-omap2/omap-wakeupgen.c +6
-0+ +static void irq_save_secure_context (void ) +{ +if (omap4_device_next_state_off ()) { +save_secure_all (); + }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) {Why is this check needed? This is called from the
CPU_CLUSTER_PM_ENTERnotifier, which AFAICT, is only called when the cluster is going off.
Quoted 5 lines
This is checking against the different MPU PD states we can go into. If:
- MPU OSWR => GIC save needed only
- MPU OFF => GIC + secure RAM save needed (not recommended to be used though)
- MPU OSWR / OFF + device-off => save all needed
OK, more detailed changelog and descriptive kerneldoc for this function would certainly help.
Quoted 143 lines
Quoted 143 lines
Quoted 127 lines
arch/arm/mach-omap2/omap-wakeupgen.c +13
-0+irq_save_secure_gic (); +save_secure_ram (); + }else { +irq_save_secure_gic (); + } +} +#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit irq_cpu_hotplug_notify (struct notifier_block *self,unsigned long action,void *hcpu)@@ -388,5 +425,11 @@ int __init omap_wakeupgen_init(void)irq_hotplug_init ();irq_pm_init (); + mpuss_pd =pwrdm_lookup ("mpu_pwrdm" ); +if (!mpuss_pd) { +pr_err ("wakeupgen: unable to get mpu_pwrdm\n" ); +return -EINVAL ; + } +return 0 ; }arch/arm/mach-omap2/pm-debug.c +12
-5@@ -40,6 +40,7 @@u32 enable_off_mode;static u32 enable_oswr_mode; +static void (*off_mode_enable_func) (int );#ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> @@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)else omap_pm_disable_off_mode (); -omap3_pm_off_mode_enable (val); +if (off_mode_enable_func) +off_mode_enable_func (val); }if (option == &enable_oswr_mode)@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void)pwrdm_for_each (pwrdms_setup, (void *)d); -if (cpu_is_omap34xx ()) - (void )debugfs_create_file ("enable_off_mode" , -S_IRUGO |S_IWUSR , d, &enable_off_mode, - &pm_dbg_option_fops); + (void )debugfs_create_file ("enable_off_mode" , +S_IRUGO |S_IWUSR , d, &enable_off_mode, + &pm_dbg_option_fops);if (cpu_is_omap44xx ()) (void )debugfs_create_file ("enable_oswr_mode" ,S_IRUGO |S_IWUSR , d, &enable_oswr_mode, &pm_dbg_option_fops); +if (cpu_is_omap34xx ()) + off_mode_enable_func = omap3_pm_off_mode_enable; + +if (cpu_is_omap44xx ()) + off_mode_enable_func = omap4_pm_off_mode_enable; + pm_dbg_init_done =1 ;return 0 ;arch/arm/mach-omap2/pm.h +20
-0@@ -18,6 +18,7 @@extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap4_pm_oswr_mode_enable (int ); +extern void omap4_pm_off_mode_enable (int );extern void omap_sram_idle (void );extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap3_idle_init (void );@@ -25,6 +26,25 @@ extern int omap4_idle_init(void);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void ); +#ifdef CONFIG_PM +extern void omap4_device_set_state_off (u8 enable); +extern bool omap4_device_prev_state_off (void ); +extern bool omap4_device_next_state_off (void ); +extern void omap4_device_clear_prev_off_state (void ); +#else +static inline void omap4_device_set_state_off (u8 enable) +{ +} +static inline bool omap4_device_prev_state_off (void ) +{ +return false; +} +static inline bool omap4_device_next_state_off (void ) +{ +return false; +} +#endif +#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );extern int omap4_opp_init (void );arch/arm/mach-omap2/pm44xx.c +10
-0@@ -87,6 +87,27 @@ static int omap4_pm_suspend(void) }#endif /* CONFIG_SUSPEND */ +/** +* get_achievable_state() - Provide achievable state +* @available_states: what states are available +* @req_min_state: what state is the minimum we'd like to hit +* +* Power domains have varied capabilities. When attempting a low power +* state such as OFF/RET, a specific min requested state may not be +* supported on the power domain, in which case, the next higher power +* state which is supported is returned. This is because a combination +* of system power states where the parent PD's state is not in line arch/arm/mach-omap2/pm44xx.c static int omap4_pm_suspend(void) · line 109
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+* with expectation can result in system instabilities. +*/ +static inline u8 get_achievable_state (u8 available_states,u8 req_min_state) +{ +u16 mask =0xFF << req_min_state; + +if (available_states & mask) +return __ffs (available_states & mask); +return PWRDM_POWER_ON ; +}This feature needs to be generalized (preferably on top of functional power states) because we have the same need on various AM3xxx SoCs which don't support RET/OFF. Mark Greer has started on this, but I think it needs to be part of the functional power states work.
Quoted 5 lines
Quoted 1 line
It also needs to be part of the powerdomain layer, IMO.
So, are you saying this whole set should be re-based on top of the functional power states stuff? If yes, that can be done (Jean actually already did some work on this and got it working I think.)
Yes please.
Kevin
PATCH v2 3/19 ARM: OMAP4: PM: Add device-off support
Quoted 89 lines · Kevin Hilman
Quoted 46 lines · Tero Kristo
Quoted 11 lines · Kevin Hilman
+Jean for functional power states
Quoted 1 line · Tero Kristo
This patch adds device off support to OMAP4 device type.
Description is rather thin for a patch that is doing so much.
Quoted 1 line
OFF mode is disabled by default,
why?
Good question. For historical reference I guess. The device off works pretty nicely with the current kernel already, so it should be possible to enable it by default and blame the people who break it.
Quoted 18 lines
Quoted 6 lines
however, there are two ways to enable OFF mode:
a) In the board file, callomap4_pm_off_mode_enable(1)
b) Enable OFF mode using the debugfs entry echo "1">/sys/kernel/debug/pm_debug/enable_off_mode (conversely echo '0' will disable it as well).This part needs to be a separate patch.
But, as stated in the core retention series, I'd like to move away from these global flags all together.
The way we manage the disabling of certain states (like off) is already clumsy for OMAP3, and it's getting worse with OMAP4. Basically, I think this feature needs to be supported by using constraints on functional
power states. Having checks all over the place is getting unwieldy and
not attractive to maintain.Quoted 4 lines
The combination of constraints and functional power states should make
this much more manageable. Until we have that, I'd prefer to keep
the debugfs enable/disable stuff as separate patches at the end of the series used only for testing.Okay, this sounds like a good plan.
Quoted 4 lines
Quoted 3 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: largely re-structured the code]Quoted 7 lines
Quoted 3 lines
then the sign-off above from Santosh probably doesn't apply anymore. You should change that to a Cc and just mention tht this is based upon some original work from Santosh.
Yeah... I am not quite sure where the line goes here as I am modifying the patches quite heavily but try to keep credits to the original authors... will change this like so.
I guess it's up to you whether you keep Santosh as author. It all depends how much you've changed the original. But you can use the changlog to give credits to Santosh, or state it was a collaboration, whatever you like. You can say stuff like "based on an origianl patch by...", and/or briefly summarize the changes you made from the original verions, etc.
Quoted 26 lines
Quoted 6 lines
First, some general comments:
There is a lot going on in this patch, so it is hard to follow what all is related, and why. Just a quick glance suggests it needs to be broken up into at least a few parts:
What is the merge plan for the func power state stuff? I don't want to create new dependencies if unnecessary. Otherwise the split should be okay.
Quoted 8 lines
- low-level PRM support: new APIs for various off-mode features) (should probably be done on top of functional power states)
- powerdomain core support or "achievable" states (should probably be done on top of functional power states)
- IRQ/GIC context save/restore
- secure RAM save/restore (this has been tightly coupled to the GIC but it's not obvious why)This is tightly coupled to GIC because the ROM code has following API calls:
- save gic
- save secure RAM
- save secure all (gic + RAM + some other mysterious stuff)
Quoted 8 lines
Quoted 3 lines
It is difficult/impossible to separate these without adding redundant code execution (e.g. doing a GIC save from the GIC code + then doing a second GIC save with save secure all from core PM code.)
Ok, thanks for clarifying.
That should be explained in the changelog for this patch when it's broken up.
Ok will add some comment about this.
Quoted 39 lines
Quoted 39 lines
Quoted 38 lines
- PM debug support to enable/disable off-mode
(for testing only, not for merge)Quoted 23 lines
Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 10 ++++- arch/arm/mach-omap2/omap-wakeupgen.c | 47 +++++++++++++++++++- arch/arm/mach-omap2/pm-debug.c | 17 +++++-- arch/arm/mach-omap2/pm.h | 20 +++++++++ arch/arm/mach-omap2/pm44xx.c | 45 +++++++++++++++++++ arch/arm/mach-omap2/prm44xx.c | 66 +++++++++++++++++++++++++++++ 6 files changed, 197 insertions(+), 8 deletions(-)arch/arm/mach-omap2/omap-mpuss-lowpower.c +1
-0@@ -60,6 +60,7 @@#include "prcm44xx.h" #include "prm44xx.h" #include "prm-regbits-44xx.h" +#include "cm44xx.h" #ifdef CONFIG_SMP arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 268
Quoted 6 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +2
-1@@ -263,9 +264,13 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); - if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) && +if (omap4_device_next_state_off ()) + save_state =3 ;Why?
I don't see why this check is needed in addition to the
mpuss_pdcheck added just below?
Quoted 6 lines
Quoted 3 lines
mpuss_pddoes not go to off, thats why. It goes to OSWR state during standard device-off. It is possible for it to go to OFF mode, but it is not recommended.What is confusing is that the check below specifically checks for
mpuss_pd== off.
Yes, I guess I'll just drop that check out. Or add an error if someone actually tries to use it.
Quoted 122 lines
Quoted 21 lines
Quoted 13 lines
Quoted 13 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0+else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) save_state =2 ; +else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) + save_state =3 ;cpu_clear_prev_logic_pwrst (cpu);set_cpu_next_pwrst (cpu, power_state);@@ -288,6 +293,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON );Quoted 7 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 298
Quoted 3 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +3
-0+if (omap4_device_prev_state_off ()) +omap4_device_clear_prev_off_state (); +The 'clear prev off state' is subsequently removed in the last patch "ARM: OMAP4: powerdomain: update mpu / core off counters during device
off." Why is it needed here?Quoted 4 lines
That patch is moving the clear part to the
lost_context_rfffunc, it is probably not that clear. Should be easier to follow the logic once I re-structure the code a bit more (separate the prm support funcs out to their own set etc.)Yes, thanks.
Quoted 78 lines
Quoted 47 lines
Quoted 47 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0pwrdm_post_transition ();return 0 ;arch/arm/mach-omap2/omap-wakeupgen.c +5
-2@@ -32,6 +32,7 @@#include "omap4-sar-layout.h" #include "common.h" +#include "pm.h" #define NR_REG_BANKS 4#define MAX_IRQS 128@@ -46,6 +47,8 @@ static void __iomem *sar_base;static DEFINE_SPINLOCK (wakeupgen_lock);static unsigned int irq_target_cpu[NR_IRQS ]; +static struct powerdomain *mpuss_pd; +/* * Static helper functions. */ @@ -259,7 +262,7 @@ static void irq_save_context(void)/* * Clear WakeupGen SAR backup status. */ -void irq_sar_clear (void ) +static void irq_sar_clear (void ) {u32 val; val =__raw_readl (sar_base +SAR_BACKUP_STATUS_OFFSET );@@ -271,7 +274,7 @@ void irq_sar_clear(void)* Save GIC and Wakeupgen interrupt context using secure API * for HS/EMU devices. */ -static void irq_save_secure_context (void ) +static void irq_save_secure_gic (void ) {u32 ret; ret = omap_secure_dispatcher(OMAP4_HAL_SAVEGIC_INDEX,@@ -282,6 +285,40 @@ static void irq_save_secure_context(void) }#endif Quoted 5 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 290
Quoted 3 lines
arch/arm/mach-omap2/omap-wakeupgen.c +3
-0+static void save_secure_ram (void ) +{ +u32 ret;CodingStyle nit: blank line needed here (and in multiple other places)
Okay.
Quoted 14 lines
Quoted 14 lines
arch/arm/mach-omap2/omap-wakeupgen.c +13
-0+ ret =omap_secure_dispatcher (OMAP4_HAL_SAVESECURERAM_INDEX , +FLAG_START_CRITICAL , +1 ,omap_secure_ram_mempool_base (), +0 ,0 ,0 ); +if (ret !=API_HAL_RET_VALUE_OK ) +pr_err ("Secure ram context save failed\n" ); +} + +static void save_secure_all (void ) +{ +u32 ret; + ret = omap_secure_dispatcher(OMAP4_HAL_SAVEALL_INDEX, + FLAG_START_CRITICAL,Quoted 8 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 308
Quoted 5 lines
arch/arm/mach-omap2/omap-wakeupgen.c +5
-0+1 ,omap_secure_ram_mempool_base (), + 0, 0, 0); +if (ret !=API_HAL_RET_VALUE_OK ) +pr_err ("Secure all context save failed\n" ); +}This secure mode save/restore seems misplaced in the wakeupgen driver. Seems to me like it belongs in
omap-secure.c.Quoted 2 lines
Can't really move it there, as described above. Unless we want to save GIC context twice.
OK
Quoted 11 lines
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c static void irq_save_secure_context(void) · line 314
Quoted 7 lines
arch/arm/mach-omap2/omap-wakeupgen.c +6
-0+ +static void irq_save_secure_context (void ) +{ +if (omap4_device_next_state_off ()) { +save_secure_all (); + }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) {Why is this check needed? This is called from the
CPU_CLUSTER_PM_ENTERnotifier, which AFAICT, is only called when the cluster is going off.
Quoted 8 lines
Quoted 5 lines
This is checking against the different MPU PD states we can go into. If:
- MPU OSWR => GIC save needed only
- MPU OFF => GIC + secure RAM save needed (not recommended to be used though)
- MPU OSWR / OFF + device-off => save all neededOK, more detailed changelog and descriptive kerneldoc for this function would certainly help.
Yep will add.
Quoted 144 lines
Quoted 144 lines
Quoted 144 lines
Quoted 128 lines
arch/arm/mach-omap2/omap-wakeupgen.c +13
-0+irq_save_secure_gic (); +save_secure_ram (); + }else { +irq_save_secure_gic (); + } +} +#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit irq_cpu_hotplug_notify (struct notifier_block *self,unsigned long action,void *hcpu)@@ -388,5 +425,11 @@ int __init omap_wakeupgen_init(void)irq_hotplug_init ();irq_pm_init (); + mpuss_pd =pwrdm_lookup ("mpu_pwrdm" ); +if (!mpuss_pd) { +pr_err ("wakeupgen: unable to get mpu_pwrdm\n" ); +return -EINVAL ; + } +return 0 ; }arch/arm/mach-omap2/pm-debug.c +12
-5@@ -40,6 +40,7 @@u32 enable_off_mode;static u32 enable_oswr_mode; +static void (*off_mode_enable_func) (int );#ifdef CONFIG_DEBUG_FS #include <linux/debugfs.h> @@ -249,7 +250,8 @@ static int option_set(void *data, u64 val)else omap_pm_disable_off_mode (); -omap3_pm_off_mode_enable (val); +if (off_mode_enable_func) +off_mode_enable_func (val); }if (option == &enable_oswr_mode)@@ -278,16 +280,21 @@ static int __init pm_dbg_init(void)pwrdm_for_each (pwrdms_setup, (void *)d); -if (cpu_is_omap34xx ()) - (void )debugfs_create_file ("enable_off_mode" , -S_IRUGO |S_IWUSR , d, &enable_off_mode, - &pm_dbg_option_fops); + (void )debugfs_create_file ("enable_off_mode" , +S_IRUGO |S_IWUSR , d, &enable_off_mode, + &pm_dbg_option_fops);if (cpu_is_omap44xx ()) (void )debugfs_create_file ("enable_oswr_mode" ,S_IRUGO |S_IWUSR , d, &enable_oswr_mode, &pm_dbg_option_fops); +if (cpu_is_omap34xx ()) + off_mode_enable_func = omap3_pm_off_mode_enable; + +if (cpu_is_omap44xx ()) + off_mode_enable_func = omap4_pm_off_mode_enable; + pm_dbg_init_done =1 ;return 0 ;arch/arm/mach-omap2/pm.h +20
-0@@ -18,6 +18,7 @@extern void *omap3_secure_ram_storage;extern void omap3_pm_off_mode_enable (int );extern void omap4_pm_oswr_mode_enable (int ); +extern void omap4_pm_off_mode_enable (int );extern void omap_sram_idle (void );extern int omap_set_pwrdm_state (struct powerdomain *pwrdm,u32 state);extern int omap3_idle_init (void );@@ -25,6 +26,25 @@ extern int omap4_idle_init(void);extern int omap_pm_clkdms_setup (struct clockdomain *clkdm,void *unused);extern int (*omap_pm_suspend)(void ); +#ifdef CONFIG_PM +extern void omap4_device_set_state_off (u8 enable); +extern bool omap4_device_prev_state_off (void ); +extern bool omap4_device_next_state_off (void ); +extern void omap4_device_clear_prev_off_state (void ); +#else +static inline void omap4_device_set_state_off (u8 enable) +{ +} +static inline bool omap4_device_prev_state_off (void ) +{ +return false; +} +static inline bool omap4_device_next_state_off (void ) +{ +return false; +} +#endif +#if defined(CONFIG_PM_OPP )extern int omap3_opp_init (void );extern int omap4_opp_init (void );arch/arm/mach-omap2/pm44xx.c +10
-0@@ -87,6 +87,27 @@ static int omap4_pm_suspend(void) }#endif /* CONFIG_SUSPEND */ +/** +* get_achievable_state() - Provide achievable state +* @available_states: what states are available +* @req_min_state: what state is the minimum we'd like to hit +* +* Power domains have varied capabilities. When attempting a low power +* state such as OFF/RET, a specific min requested state may not be +* supported on the power domain, in which case, the next higher power +* state which is supported is returned. This is because a combination +* of system power states where the parent PD's state is not in line arch/arm/mach-omap2/pm44xx.c static int omap4_pm_suspend(void) · line 109
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+* with expectation can result in system instabilities. +*/ +static inline u8 get_achievable_state (u8 available_states,u8 req_min_state) +{ +u16 mask =0xFF << req_min_state; + +if (available_states & mask) +return __ffs (available_states & mask); +return PWRDM_POWER_ON ; +}This feature needs to be generalized (preferably on top of functional power states) because we have the same need on various AM3xxx SoCs which don't support RET/OFF. Mark Greer has started on this, but I think it needs to be part of the functional power states work.
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
It also needs to be part of the powerdomain layer, IMO.
So, are you saying this whole set should be re-based on top of the functional power states stuff? If yes, that can be done (Jean actually already did some work on this and got it working I think.)
Yes please.
Okay, next version will be based on top of func power states.
-Tero
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
In reply to Tero KristoFrom: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.
--- arch/arm/mach-omap2/cm44xx.h | 5 + arch/arm/mach-omap2/dpll44xx.c | 271 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap-mpuss-lowpower.c | 14 +- 3 files changed, 285 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/cm44xx.h +5 -0
@@ -23,4 +23,9 @@#define OMAP4_CM_CLKSTCTRL 0x0000#define OMAP4_CM_STATICDEP 0x0004 +#ifndef __ASSEMBLER__ +extern void omap4_dpll_prepare_off (void ); +extern void omap4_dpll_resume_off (void ); +#endif +#endif
arch/arm/mach-omap2/dpll44xx.c +271 -0
286 lines not on this page · raw message
arch/arm/mach-omap2/omap-mpuss-lowpower.c +9 -5
@@ -264,13 +264,15 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)* In MPUSS OSWR or device OFF, interrupt controller contest is lost. */ mpuss_clear_prev_logic_pwrst (); -if (omap4_device_next_state_off ()) +if (omap4_device_next_state_off ()) { +omap4_dpll_prepare_off (); save_state =3 ; -else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && - (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) + }else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && + (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) { save_state =2 ; -else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) + }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) { save_state =3 ; + }cpu_clear_prev_logic_pwrst (cpu);set_cpu_next_pwrst (cpu, power_state);
@@ -293,8 +295,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); -if (omap4_device_prev_state_off ()) +if (omap4_device_prev_state_off ()) { +omap4_dpll_resume_off ();omap4_device_clear_prev_off_state (); + }pwrdm_post_transition ();
Signature · 1 line
1.7.4.1
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 7 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.
Quoted 5 lines
[nm at ti.com: minor cleanups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Tero Kristo <[email protected]>
Some general comments:
- the register dump/print doesn't belong here. If needed, should be a debug feature if needed.
- Rather than hooking into omap4_enter_lowpower(), should use the cluster PM enter/exit notifier chain.
Kevin
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 15 lines · Kevin Hilman
Quoted 7 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.Quoted 5 lines
[nm at ti.com: minor cleanups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Tero Kristo <[email protected]>
Quoted 8 lines
Some general comments:
- the register dump/print doesn't belong here. ?If needed, should be a ?debug feature if needed.
- Rather than hooking into
omap4_enter_lowpower(), should use ?the cluster PM enter/exit notifier chain.
This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Regards
Santosh
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 21 lines · Santosh
Quoted 20 lines · Kevin Hilman
Quoted 7 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.Quoted 5 lines
[nm at ti.com: minor cleanups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Tero Kristo <[email protected]>Some general comments:
- the register dump/print doesn't belong here. ?If needed, should be a ?debug feature if needed.
Quoted 9 lines
Quoted 3 lines
- Rather than hooking into
omap4_enter_lowpower(), should use ?the cluster PM enter/exit notifier chain.This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Just a thought, we can have a separate notifier chain for device OFF. It can allow use to get rid of 'enable_off_mode" kind of flags and can be used by many drivers too.
Regards
Santosh
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 29 lines · Santosh
Quoted 27 lines · Santosh
Quoted 15 lines · Kevin Hilman
Quoted 7 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.Quoted 5 lines
[nm at ti.com: minor cleanups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Tero Kristo <[email protected]>Quoted 8 lines
Some general comments:
- the register dump/print doesn't belong here. ?If needed, should be a ?debug feature if needed.
- Rather than hooking into
omap4_enter_lowpower(), should use ?the cluster PM enter/exit notifier chain.This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
Quoted 6 lines
Quoted 3 lines
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Just a thought, we can have a separate notifier chain for device OFF. It can allow use to get rid of '
enable_off_mode" kind of flags and can be used by many drivers too.
Yes, I like this idea.
It allows a much cleaner collection of all the activities needed for device off.
Kevin
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 34 lines · Kevin Hilman
Quoted 32 lines · Santosh
Quoted 30 lines · Santosh
Quoted 15 lines · Kevin Hilman
Quoted 7 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.Quoted 5 lines
[nm at ti.com: minor cleanups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Tero Kristo <[email protected]>Quoted 8 lines
Some general comments:
- the register dump/print doesn't belong here. If needed, should be a debug feature if needed.
- Rather than hooking into
omap4_enter_lowpower(), should use the cluster PM enter/exit notifier chain.This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Quoted 8 lines
Quoted 3 lines
Just a thought, we can have a separate notifier chain for device OFF. It can allow use to get rid of '
enable_off_mode" kind of flags and can be used by many drivers too.Yes, I like this idea.
It allows a much cleaner collection of all the activities needed for device off.
I can just read the device next state off in the notifier func.
-Tero
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
In reply to Shilimkar, SantoshQuoted 5 lines · Santosh
Quoted 3 lines · Santosh
Quoted 2 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
- Rather than hooking into
omap4_enter_lowpower(), should use ?the cluster PM enter/exit notifier chain.This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
Quoted 6 lines
Quoted 3 lines
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Just a thought, we can have a separate notifier chain for device OFF. It can allow use to get rid of '
enable_off_mode" kind of flags and can be used by many drivers too.
Like the overall idea, but one minor dumb concern might be sequencing of notifiers
- OFF entry and restore needs things to be executed in a specific sequence.
How do we plan to ensure the sequence is maintained in a notifier call chain? one
possible option might be a "priority" based scheme?
Regards,
Nishanth Menon
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 21 lines · Nishanth
Quoted 5 lines · Santosh
Quoted 3 lines · Santosh
Quoted 2 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
- Rather than hooking into
omap4_enter_lowpower(), should use ?the cluster PM enter/exit notifier chain.This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
Quoted 6 lines
Quoted 3 lines
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Just a thought, we can have a separate notifier chain for device OFF. It can allow use to get rid of '
enable_off_mode" kind of flags and can be used by many drivers too.
Quoted 6 lines
Like the overall idea, but one minor dumb concern might be sequencing of notifiers
- OFF entry and restore needs things to be executed in a specific sequence.
How do we plan to ensure the sequence is maintained in a notifier call chain? one
possible option might be a "priority" based scheme?
Or just combine the events that need a specific sequence into single notifier callback function.
Kevin
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 30 lines · Kevin Hilman
Quoted 21 lines · Nishanth
Quoted 5 lines · Santosh
Quoted 3 lines · Santosh
Quoted 2 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
- Rather than hooking into
omap4_enter_lowpower(), should use ?the cluster PM enter/exit notifier chain.This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
Quoted 6 lines
Quoted 3 lines
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Just a thought, we can have a separate notifier chain for device OFF. It can allow use to get rid of '
enable_off_mode" kind of flags and can be used by many drivers too.Quoted 6 lines
Like the overall idea, but one minor dumb concern might be sequencing of notifiers
?- OFF entry and restore needs things to be executed in a specific sequence. How do we plan to ensure the sequence is maintained in a notifier call chain? one
possible option might be a "priority" based scheme?
Quoted 2 lines
Or just combine the events that need a specific sequence into single notifier callback function.
There is other issues in case of failure cases -> abort of OFF sequence due to pending interrupt
detected as part of a notifier - error handling needs to be sane in proper sequence.
I understand and appreciate the intent of replacing the single mega enter_sleep with a chain of notifiers
but any such option will need to be scalable enough to handle weird erratum handling (HSI CAWAKE as an example)
which potentially break the logic flow and be either be equal or better than what we have today interms of
error handling. since these notifiers will be triggered for CPUIDLE(performance sensitive) and suspend, the intricacies might be better understood by seeing how this proposed notifiers look like.
Regards,
Nishanth Menon
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 33 lines · Nishanth
Quoted 30 lines · Kevin Hilman
Quoted 21 lines · Nishanth
Quoted 5 lines · Santosh
Quoted 3 lines · Santosh
Quoted 2 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
- Rather than hooking into
omap4_enter_lowpower(), should use ?the cluster PM enter/exit notifier chain.This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
Quoted 6 lines
Quoted 3 lines
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Just a thought, we can have a separate notifier chain for device OFF. It can allow use to get rid of '
enable_off_mode" kind of flags and can be used by many drivers too.Quoted 6 lines
Like the overall idea, but one minor dumb concern might be sequencing of notifiers
?- OFF entry and restore needs things to be executed in a specific sequence. How do we plan to ensure the sequence is maintained in a notifier call chain? one
possible option might be a "priority" based scheme?Quoted 2 lines
Or just combine the events that need a specific sequence into single notifier callback function.
Quoted 13 lines
There is other issues in case of failure cases -> abort of OFF sequence due to pending interrupt
detected as part of a notifier - error handling needs to be sane in proper sequence.
I understand and appreciate the intent of replacing the single megaenter_sleepwith a chain of notifiers
but any such option will need to be scalable enough to handle weird erratum handling (HSI CAWAKE as an example)
which potentially break the logic flow and be either be equal or better than what we have today interms of
error handling. since these notifiers will be triggered for CPUIDLE(performance sensitive) and suspend, the intricacies might be better understood by seeing how this proposed notifiers look like.
Makes sense. Thanks for clarifying.
What $SUBJECT series proposed was indeed a "mega function", but one that was just a list of function calls with no error checking or recovery, and no documentation/description about dependencies/sequencing etc. etc. Based on the patches at hadn (which is all reviewers have to go on), notifiers seemed to be a good fit.
If there are good reasons that all of the device-off events need to be coordinated/synchronized/sequenced (and it sounds like there are, thanks for pointing them out), I am not opposed to that approach. It simply needs to be well described in the changlog.
Thanks,
Kevin
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
Quoted 57 lines · Kevin Hilman
Quoted 33 lines · Nishanth
Quoted 30 lines · Kevin Hilman
Quoted 21 lines · Nishanth
Quoted 5 lines · Santosh
Quoted 3 lines · Santosh
Quoted 2 lines · Kevin Hilman
Tero Kristo <[email protected]> writes:
[...]
Quoted 6 lines
Quoted 6 lines
Quoted 3 lines
- Rather than hooking into
omap4_enter_lowpower(), should use ?the cluster PM enter/exit notifier chain.This is again specific to device OFF only and not related to CPU cluster state as such. So I don't think notifiers should be used here.
Quoted 6 lines
Quoted 3 lines
O.w even when we attempt just MPU OSWR C-state, all these functions will get called in notifier chain.
Just a thought, we can have a separate notifier chain for device OFF. It can allow use to get rid of '
enable_off_mode" kind of flags and can be used by many drivers too.Quoted 6 lines
Like the overall idea, but one minor dumb concern might be sequencing of notifiers
?- OFF entry and restore needs things to be executed in a specific sequence. How do we plan to ensure the sequence is maintained in a notifier call chain? one
possible option might be a "priority" based scheme?Quoted 2 lines
Or just combine the events that need a specific sequence into single notifier callback function.
Quoted 13 lines
There is other issues in case of failure cases -> abort of OFF sequence due to pending interrupt
detected as part of a notifier - error handling needs to be sane in proper sequence.
I understand and appreciate the intent of replacing the single megaenter_sleepwith a chain of notifiers
but any such option will need to be scalable enough to handle weird erratum handling (HSI CAWAKE as an example)
which potentially break the logic flow and be either be equal or better than what we have today interms of
error handling. since these notifiers will be triggered for CPUIDLE(performance sensitive) and suspend, the intricacies might be better understood by seeing how this proposed notifiers look like.Makes sense. ?Thanks for clarifying.
What $SUBJECT series proposed was indeed a "mega function", but one that was just a list of function calls with no error checking or recovery, and no documentation/description about dependencies/sequencing etc. etc. Based on the patches at hadn (which is all reviewers have to go on), notifiers seemed to be a good fit.
Quoted 5 lines
If there are good reasons that all of the device-off events need to be coordinated/synchronized/sequenced (and it sounds like there are, thanks for pointing them out), I am not opposed to that approach. ?It simply needs to be well described in the changlog.
There are sequence dependencies but lot of code can be extracted and put into smaller blocks that is independent.
I agree for the error handling part notifier chain could be an issue.
Regards
Santosh
PATCH v2 4/19 ARM: OMAP4: PM: save/restore all DPLL settings in OFF mode
In reply to Kevin HilmanQuoted 15 lines · Kevin Hilman
Quoted 7 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
SAR/ROM code restores only CORE DPLL to its original state post wakeup from OFF mode.
The rest of the DPLL's in OMAP4 platform (MPU/IVA/ABE/USB/PER) are saved and restored here during an OFF transition.Quoted 5 lines
[nm at ti.com: minor cleanups]Signed-off-by Nishanth Menon <[email protected]>Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>Signed-off-by Tero Kristo <[email protected]>
Quoted 4 lines
Some general comments:
- the register dump/print doesn't belong here. If needed, should be a debug feature if needed.
Okay, I'll just drop it out.
Quoted 3 lines
- Rather than hooking into
omap4_enter_lowpower(), should use the cluster PM enter/exit notifier chain.
Yes can do that.
-Tero
PATCH v2 5/19 ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
In reply to Tero KristoFrom: Rajendra Nayak <[email protected]>
Restore all CM1/2 module registers as they are lost in OFF mode.
--- arch/arm/mach-omap2/cm44xx.c | 328 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/cm44xx.h | 2 + arch/arm/mach-omap2/omap-mpuss-lowpower.c | 2 + 3 files changed, 332 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/cm44xx.c +328 -0
@@ -21,8 +21,11 @@#include "iomap.h" #include "common.h" #include "cm.h" +#include "cm44xx.h" #include "cm1_44xx.h" #include "cm2_44xx.h" +#include "cminst44xx.h" +#include "prcm44xx.h" #include "cm-regbits-44xx.h" /* CM1 hardware module low-level functions */
@@ -50,3 +53,328 @@ void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) {__raw_writel (val,OMAP44XX_CM2_REGADDR (inst, reg)); } + +#define MAX_CM_REGISTERS 51 + +struct omap4_cm_reg { +u16 offset; +u32 val; +}; + +struct omap4_cm_regs { +u16 mod_off; +u16 no_reg; +struct omap4_cm_reg reg[MAX_CM_REGISTERS ]; +}; + +static struct omap4_cm_regs cm1_regs[] = { +/* OMAP4430_CM1_OCP_SOCKET_MOD */ + { .mod_off =OMAP4430_CM1_OCP_SOCKET_INST , .no_reg =1 , + { + {OMAP4_CM_CM1_PROFILING_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM1_CKGEN_MOD */ + { .mod_off =OMAP4430_CM1_CKGEN_INST , .no_reg =4 , + { + {OMAP4_CM_CLKSEL_CORE_OFFSET }, + {OMAP4_CM_CLKSEL_ABE_OFFSET }, + {OMAP4_CM_DLL_CTRL_OFFSET }, + {OMAP4_CM_DYN_DEP_PRESCAL_OFFSET } + }, + }, +/* OMAP4430_CM1_MPU_MOD */ + { .mod_off =OMAP4430_CM1_MPU_INST , .no_reg =4 , + { + {OMAP4_CM_MPU_CLKSTCTRL_OFFSET }, + {OMAP4_CM_MPU_STATICDEP_OFFSET }, + {OMAP4_CM_MPU_DYNAMICDEP_OFFSET }, + {OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM1_TESLA_MOD */ + { .mod_off =OMAP4430_CM1_TESLA_INST , .no_reg =4 , + { + {OMAP4_CM_TESLA_CLKSTCTRL_OFFSET }, + {OMAP4_CM_TESLA_STATICDEP_OFFSET }, + {OMAP4_CM_TESLA_DYNAMICDEP_OFFSET }, + {OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM1_ABE_MOD */ + { .mod_off =OMAP4430_CM1_ABE_INST , .no_reg =15 , + { + {OMAP4_CM1_ABE_CLKSTCTRL_OFFSET }, + {OMAP4_CM1_ABE_L4ABE_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET }, + {OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET } + }, + }, +}; + +static struct omap4_cm_regs cm2_regs[] = { +/* OMAP4430_CM2_OCP_SOCKET_MOD */ + { .mod_off =OMAP4430_CM2_OCP_SOCKET_INST , .no_reg =1 , + { + {OMAP4_CM_CM2_PROFILING_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_CKGEN_MOD */ + { .mod_off =OMAP4430_CM2_CKGEN_INST , .no_reg =12 , + { + {OMAP4_CM_CLKSEL_DUCATI_ISS_ROOT_OFFSET }, + {OMAP4_CM_CLKSEL_USB_60MHZ_OFFSET }, + {OMAP4_CM_SCALE_FCLK_OFFSET }, + {OMAP4_CM_CORE_DVFS_PERF1_OFFSET }, + {OMAP4_CM_CORE_DVFS_PERF2_OFFSET }, + {OMAP4_CM_CORE_DVFS_PERF3_OFFSET }, + {OMAP4_CM_CORE_DVFS_PERF4_OFFSET }, + {OMAP4_CM_CORE_DVFS_CURRENT_OFFSET }, + {OMAP4_CM_IVA_DVFS_PERF_TESLA_OFFSET }, + {OMAP4_CM_IVA_DVFS_PERF_IVAHD_OFFSET }, + {OMAP4_CM_IVA_DVFS_PERF_ABE_OFFSET }, + {OMAP4_CM_IVA_DVFS_CURRENT_OFFSET } + }, + }, +/* OMAP4430_CM2_ALWAYS_ON_MOD */ + { .mod_off =OMAP4430_CM2_ALWAYS_ON_INST , .no_reg =6 , + { + {OMAP4_CM_ALWON_CLKSTCTRL_OFFSET }, + {OMAP4_CM_ALWON_MDMINTC_CLKCTRL_OFFSET }, + {OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET }, + {OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET }, + {OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET }, + {OMAP4_CM_ALWON_USBPHY_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_CORE_MOD */ + { .mod_off =OMAP4430_CM2_CORE_INST , .no_reg =41 , + { + {OMAP4_CM_L3_1_CLKSTCTRL_OFFSET }, + {OMAP4_CM_L3_1_DYNAMICDEP_OFFSET }, + {OMAP4_CM_L3_1_L3_1_CLKCTRL_OFFSET }, + {OMAP4_CM_L3_2_CLKSTCTRL_OFFSET }, + {OMAP4_CM_L3_2_DYNAMICDEP_OFFSET }, + {OMAP4_CM_L3_2_L3_2_CLKCTRL_OFFSET }, + {OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET }, + {OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET }, + {OMAP4_CM_DUCATI_CLKSTCTRL_OFFSET }, + {OMAP4_CM_DUCATI_STATICDEP_OFFSET }, + {OMAP4_CM_DUCATI_DYNAMICDEP_OFFSET }, + {OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET }, + {OMAP4_CM_SDMA_CLKSTCTRL_OFFSET }, + {OMAP4_CM_SDMA_STATICDEP_OFFSET }, + {OMAP4_CM_SDMA_DYNAMICDEP_OFFSET }, + {OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET }, + {OMAP4_CM_MEMIF_CLKSTCTRL_OFFSET }, + {OMAP4_CM_MEMIF_DMM_CLKCTRL_OFFSET }, + {OMAP4_CM_MEMIF_EMIF_FW_CLKCTRL_OFFSET }, + {OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET }, + {OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET }, + {OMAP4_CM_MEMIF_DLL_CLKCTRL_OFFSET }, + {OMAP4_CM_MEMIF_EMIF_H1_CLKCTRL_OFFSET }, + {OMAP4_CM_MEMIF_EMIF_H2_CLKCTRL_OFFSET }, + {OMAP4_CM_MEMIF_DLL_H_CLKCTRL_OFFSET }, + {OMAP4_CM_D2D_CLKSTCTRL_OFFSET }, + {OMAP4_CM_D2D_STATICDEP_OFFSET }, + {OMAP4_CM_D2D_DYNAMICDEP_OFFSET }, + {OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET }, + {OMAP4_CM_D2D_MODEM_ICR_CLKCTRL_OFFSET }, + {OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET }, + {OMAP4_CM_L4CFG_CLKSTCTRL_OFFSET }, + {OMAP4_CM_L4CFG_DYNAMICDEP_OFFSET }, + {OMAP4_CM_L4CFG_L4_CFG_CLKCTRL_OFFSET }, + {OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET }, + {OMAP4_CM_L4CFG_MAILBOX_CLKCTRL_OFFSET }, + {OMAP4_CM_L4CFG_SAR_ROM_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INSTR_CLKSTCTRL_OFFSET }, + {OMAP4_CM_L3INSTR_L3_3_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INSTR_L3_INSTR_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_IVAHD_MOD */ + { .mod_off =OMAP4430_CM2_IVAHD_INST , .no_reg =5 , + { + {OMAP4_CM_IVAHD_CLKSTCTRL_OFFSET }, + {OMAP4_CM_IVAHD_STATICDEP_OFFSET }, + {OMAP4_CM_IVAHD_DYNAMICDEP_OFFSET }, + {OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET }, + {OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_CAM_MOD */ + { .mod_off =OMAP4430_CM2_CAM_INST , .no_reg =5 , + { + {OMAP4_CM_CAM_CLKSTCTRL_OFFSET }, + {OMAP4_CM_CAM_STATICDEP_OFFSET }, + {OMAP4_CM_CAM_DYNAMICDEP_OFFSET }, + {OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET }, + {OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_DSS_MOD */ + { .mod_off =OMAP4430_CM2_DSS_INST , .no_reg =5 , + { + {OMAP4_CM_DSS_CLKSTCTRL_OFFSET }, + {OMAP4_CM_DSS_STATICDEP_OFFSET }, + {OMAP4_CM_DSS_DYNAMICDEP_OFFSET }, + {OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET }, + {OMAP4_CM_DSS_DEISS_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_GFX_MOD */ + { .mod_off =OMAP4430_CM2_GFX_INST , .no_reg =4 , + { + {OMAP4_CM_GFX_CLKSTCTRL_OFFSET }, + {OMAP4_CM_GFX_STATICDEP_OFFSET }, + {OMAP4_CM_GFX_DYNAMICDEP_OFFSET }, + {OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_L3INIT_MOD */ + { .mod_off =OMAP4430_CM2_L3INIT_INST , .no_reg =20 , + { + {OMAP4_CM_L3INIT_CLKSTCTRL_OFFSET }, + {OMAP4_CM_L3INIT_STATICDEP_OFFSET }, + {OMAP4_CM_L3INIT_DYNAMICDEP_OFFSET }, + {OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_UNIPRO1_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_USB_HOST_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_USB_OTG_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_USB_TLL_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_P1500_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_EMAC_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_SATA_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_TPPSS_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_PCIESS_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_CCPTX_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_XHPI_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_MMC6_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET }, + {OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_L4PER_MOD */ + { .mod_off =OMAP4430_CM2_L4PER_INST , .no_reg =51 , + { + {OMAP4_CM_L4PER_CLKSTCTRL_OFFSET }, + {OMAP4_CM_L4PER_DYNAMICDEP_OFFSET }, + {OMAP4_CM_L4PER_ADC_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_HECC1_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_HECC2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_L4PER_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MCASP2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MCASP3_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MGATE_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MSPROHG_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET }, + {OMAP4_CM_L4PER_I2C5_CLKCTRL_OFFSET }, + {OMAP4_CM_L4SEC_CLKSTCTRL_OFFSET }, + {OMAP4_CM_L4SEC_STATICDEP_OFFSET }, + {OMAP4_CM_L4SEC_DYNAMICDEP_OFFSET }, + {OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET }, + {OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET }, + {OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET }, + {OMAP4_CM_L4SEC_PKAEIP29_CLKCTRL_OFFSET }, + {OMAP4_CM_L4SEC_RNG_CLKCTRL_OFFSET }, + {OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET }, + {OMAP4_CM_L4SEC_CRYPTODMA_CLKCTRL_OFFSET } + }, + }, +/* OMAP4430_CM2_CEFUSE_MOD */ + { .mod_off =OMAP4430_CM2_CEFUSE_INST , .no_reg =2 , + { + {OMAP4_CM_CEFUSE_CLKSTCTRL_OFFSET }, + {OMAP4_CM_CEFUSE_CEFUSE_CLKCTRL_OFFSET } + }, + }, +}; + +static void omap4_cm_part_prepare_off (u32 part,struct omap4_cm_regs *cm_reg, +int size) +{ +u32 i, j; + +for (i =0 ; i < size; i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { + cm_reg->reg[j].val = +omap4_cminst_read_inst_reg (part, + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +static void omap4_cm_part_resume_off (u32 part,struct omap4_cm_regs *cm_reg, +int size) +{ +u32 i, j; + +for (i =0 ; i < size; i++, cm_reg++) { +for (j =0 ; j < cm_reg->no_reg; j++) { +omap4_cminst_write_inst_reg (cm_reg->reg[j].val, + part, + cm_reg->mod_off, + cm_reg->reg[j].offset); + } + } +} + +void omap4_cm_prepare_off (void ) +{ +omap4_cm_part_prepare_off (OMAP4430_CM1_PARTITION , cm1_regs, +ARRAY_SIZE (cm1_regs)); +omap4_cm_part_prepare_off (OMAP4430_CM2_PARTITION , cm2_regs, +ARRAY_SIZE (cm2_regs)); +} + +void omap4_cm_resume_off (void ) +{ +omap4_cm_part_resume_off (OMAP4430_CM1_PARTITION , cm1_regs, +ARRAY_SIZE (cm1_regs)); +omap4_cm_part_resume_off (OMAP4430_CM2_PARTITION , cm2_regs, +ARRAY_SIZE (cm2_regs)); +}
arch/arm/mach-omap2/cm44xx.h +2 -0
@@ -24,6 +24,8 @@#define OMAP4_CM_STATICDEP 0x0004#ifndef __ASSEMBLER__ +extern void omap4_cm_prepare_off (void ); +extern void omap4_cm_resume_off (void );extern void omap4_dpll_prepare_off (void );extern void omap4_dpll_resume_off (void );#endif
arch/arm/mach-omap2/omap-mpuss-lowpower.c +2 -0
@@ -265,6 +265,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)*/ mpuss_clear_prev_logic_pwrst ();if (omap4_device_next_state_off ()) { +omap4_cm_prepare_off ();omap4_dpll_prepare_off (); save_state =3 ; } else if ((pwrdm_read_next_pwrst(mpuss_pd) == PWRDM_POWER_RET) &&
@@ -297,6 +298,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off (); +omap4_cm_resume_off ();omap4_device_clear_prev_off_state (); }
Signature · 1 line
1.7.4.1
PATCH v2 5/19 ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
Quoted 3 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
Restore all CM1/2 module registers as they are lost in OFF mode.
Save and restore?
Also, as in the previous patch. Can this be done using cluster PM
notifier as well? (I realize that this series was probably done
before the PM notifiers were upstream, but now that we have them, we should use them.)
Kevin
PATCH v2 5/19 ARM: OMAP4: PM: save/restore all CM1/2 settings in OFF mode
Quoted 4 lines · Kevin Hilman
Quoted 2 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
Quoted 9 lines
Quoted 1 line
Restore all CM1/2 module registers as they are lost in OFF mode.
Save and restore?
Also, as in the previous patch. ?Can this be done using cluster PM notifier as well? ? ?(I realize that this series was probably done before the PM notifiers were upstream, but now that we have them, we should use them.)
Device OFF specific and not related to CPU cluster state as such.
Regards
Santosh
PATCH v2 6/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
In reply to Tero KristoFrom: Santosh Shilimkar <[email protected]>
The SAR RAM is maintained during Device OFF mode. The register layout is fixed in SAR ROM. SAR is split into 4 banks with different privilege accesses based on device type
---------------------------------------------------------------
Access mode Bank Address Range
---------------------------------------------------------------
HS/GP : Public 1 0x4A32_6000 - 0x4A32_6FFF (4kB)
HS/GP : Public 2 0x4A32_7000 - 0x4A32_73FF (1kB)
HS/EMU : Secured
GP : Public 3 0x4A32_8000 - 0x4A32_87FF (2kB)
HS/GP :Secure
write once. 4 0x4A32_9000 - 0x4A32_93FF (1kB)
---------------------------------------------------------------
The save process is done entirely by software and restore is done by hardware using the auto-restore feature. The restore feature is enabled by default and cannot be disabled. The software must save the data to be restored in a dedicated location in SAR RAM.
[with contributions for 4460, cleanups from:
Rajeev Kulkarni <[email protected]>
Nishanth Menon <[email protected]>
Axel Haslam <[email protected]>
Avinash.H.M <[email protected]>]
[t-kristo at ti.com: dropped huge data tables as they are no longer needed
with subsequent patches that generate the layouts based on SAR ROM contents, also dropped unnecessary dmm-44xx.h header file.]
--- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/cm1_44xx.h | 2 + arch/arm/mach-omap2/cm2_44xx.h | 2 + arch/arm/mach-omap2/omap-mpuss-lowpower.c | 7 + arch/arm/mach-omap2/omap-sar.c | 330 ++++++++++++++++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 28 --- arch/arm/mach-omap2/omap4-sar-layout.h | 50 +++++ arch/arm/mach-omap2/pm.h | 12 + arch/arm/plat-omap/include/plat/omap44xx.h | 5 + 9 files changed, 409 insertions(+), 29 deletions(-) create mode 100644 arch/arm/mach-omap2/omap-sar.c
arch/arm/mach-omap2/Makefile +1 -1
@@ -27,7 +27,7 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \ - sleep44xx.o + sleep44xx.o omap-sar.o plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec)
arch/arm/mach-omap2/cm1_44xx.h +2 -0
@@ -218,8 +218,10 @@#define OMAP4430_CM1_ABE_WDT3_CLKCTRL OMAP44XX_CM1_REGADDR(OMAP4430_CM1_ABE_INST, 0x0088)/* Function prototypes */ +#ifndef __ASSEMBLER__extern u32 omap4_cm1_read_inst_reg (s16 inst,u16 idx);extern void omap4_cm1_write_inst_reg (u32 val,s16 inst,u16 idx);extern u32 omap4_cm1_rmw_inst_reg_bits (u32 mask,u32 bits,s16 inst,s16 idx); +#endif #endif
arch/arm/mach-omap2/cm2_44xx.h +2 -0
@@ -450,8 +450,10 @@#define OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL OMAP44XX_CM2_REGADDR(OMAP4430_CM2_CEFUSE_INST, 0x0020)/* Function prototypes */ +#ifndef __ASSEMBLER__extern u32 omap4_cm2_read_inst_reg (s16 inst,u16 idx);extern void omap4_cm2_write_inst_reg (u32 val,s16 inst,u16 idx);extern u32 omap4_cm2_rmw_inst_reg_bits (u32 mask,u32 bits,s16 inst,s16 idx); +#endif #endif
arch/arm/mach-omap2/omap-mpuss-lowpower.c +7 -0
@@ -233,6 +233,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) {unsigned int save_state =0 ;unsigned int wakeup_cpu; +int ret;if (omap_rev () ==OMAP4430_REV_ES1_0 )return -ENXIO ;
@@ -265,6 +266,11 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)*/ mpuss_clear_prev_logic_pwrst ();if (omap4_device_next_state_off ()) { +/* Save the device context to SAR RAM */ + ret =omap_sar_save (); +if (ret) + goto sar_save_failed; +omap_sar_overwrite ();omap4_cm_prepare_off ();omap4_dpll_prepare_off (); save_state =3 ;
@@ -302,6 +308,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)omap4_device_clear_prev_off_state (); } +sar_save_failed:pwrdm_post_transition ();return 0 ;
arch/arm/mach-omap2/omap-sar.c new file +330 -0
330 lines not on this page · raw message
arch/arm/mach-omap2/omap4-common.c +0 -28
@@ -37,7 +37,6 @@static void __iomem *l2cache_base;#endif -static void __iomem *sar_ram_base;static void __iomem *gic_dist_base_addr;#ifdef CONFIG_OMAP4_ERRATA_I688
@@ -186,30 +185,3 @@ static int __init omap_l2_cache_init(void) }early_initcall (omap_l2_cache_init);#endif - -void __iomem *omap4_get_sar_ram_base (void ) -{ -return sar_ram_base; -} - -/* -* SAR RAM used to save and restore the HW -* context in low power modes -*/ -static int __init omap4_sar_ram_init (void ) -{ -/* -* To avoid code running on other OMAPs in -* multi-omap builds -*/ -if (!cpu_is_omap44xx ()) -return -ENOMEM ; - -/* Static mapping, never released */ - sar_ram_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); -if (WARN_ON (!sar_ram_base)) -return -ENOMEM ; - -return 0 ; -} -early_initcall (omap4_sar_ram_init);
arch/arm/mach-omap2/omap4-sar-layout.h +50 -0
56 lines not on this page · raw message
arch/arm/mach-omap2/pm.h +12 -0
@@ -157,4 +157,16 @@ static inline int omap4_twl_init(void) }#endif +#ifdef CONFIG_PM +extern int omap_sar_save (void ); +extern void omap_sar_overwrite (void ); +#else +static inline void omap_sar_save (void ) +{ +} +static inline void omap_sar_overwrite (void ) +{ +} +#endif +#endif
arch/arm/plat-omap/include/plat/omap44xx.h +5 -0
@@ -22,6 +22,9 @@#define L4_PER_44XX_BASE 0x48000000#define L4_EMU_44XX_BASE 0x54000000#define L3_44XX_BASE 0x44000000 +#define L3_44XX_BASE_CLK1 L3_44XX_BASE +#define L3_44XX_BASE_CLK2 0x44800000 +#define L3_44XX_BASE_CLK3 0x45000000#define OMAP44XX_EMIF1_BASE 0x4c000000#define OMAP44XX_EMIF2_BASE 0x4d000000#define OMAP44XX_DMM_BASE 0x4e000000
@@ -59,5 +62,7 @@#define OMAP44XX_HSUSB_OHCI_BASE (L4_44XX_BASE + 0x64800)#define OMAP44XX_HSUSB_EHCI_BASE (L4_44XX_BASE + 0x64C00) +#define OMAP44XX_C2C_BASE 0x5c000000 +#endif /* __ASM_ARCH_OMAP44XX_H */
Signature · 1 line
1.7.4.1
PATCH v2 6/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
Quoted 3 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The SAR RAM is maintained during Device OFF mode.
so why is this patch bothering to save and restore it?
-ECONFUSED
Quoted 13 lines
The register layout
is fixed in SAR ROM. SAR is split into 4 banks with different privilege accesses based on device type---------------------------------------------------------------
Access mode Bank Address Range
---------------------------------------------------------------
HS/GP : Public 1 0x4A32_6000 - 0x4A32_6FFF (4kB)
HS/GP : Public 2 0x4A32_7000 - 0x4A32_73FF (1kB)HS/EMU : Secured
GP : Public 3 0x4A32_8000 - 0x4A32_87FF (2kB)
Quoted 8 lines
HS/GP :Secure
write once. 4 0x4A32_9000 - 0x4A32_93FF (1kB)
---------------------------------------------------------------The save process is done entirely by software and restore is done by hardware using the auto-restore feature. The restore feature is enabled by default and cannot be disabled. The software must save the data to be restored in a dedicated location in SAR RAM.
Some general comments:
- can the cluster PM notifier be used for the save path?
- This patch adds lots of data that is immediately removed by the next patch. Probably the two just need to be combined.
- BUG_ON() should not be used unless there is absolutely no recovery
path, since it casues a full kernel panic. Instead, some error
recovery should be added.
Kevin
PATCH v2 6/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
Quoted 8 lines · Kevin Hilman
Quoted 3 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The SAR RAM is maintained during Device OFF mode.
so why is this patch bothering to save and restore it?
SAR RAM is maintained(not powered down) but somebody needs to feel the contents which will be preserved :-)
Quoted 19 lines
-ECONFUSEDQuoted 17 lines
The register layout
is fixed in SAR ROM. SAR is split into 4 banks with different privilege accesses based on device type?--------------------------------------------------------------- ?Access mode ? ? ? ? ?Bank ? ?Address Range ?--------------------------------------------------------------- ?HS/GP : Public ? ? ? ? ? ? ? 1 ? ? ? 0x4A32_6000 - 0x4A32_6FFF (4kB) ?HS/GP : Public ? ? ? ? ? ? ? 2 ? ? ? 0x4A32_7000 - 0x4A32_73FF (1kB)
?HS/EMU : Secured
?GP : Public ? ? ? ? ?3 ? ? ? 0x4A32_8000 - 0x4A32_87FF (2kB)?HS/GP :Secure
?write once. ? ? ? ? ?4 ? ? ? 0x4A32_9000 - 0x4A32_93FF (1kB) ?---------------------------------------------------------------
Quoted 9 lines
Quoted 4 lines
The save process is done entirely by software and restore is done by hardware using the auto-restore feature. The restore feature is enabled by default and cannot be disabled. The software must save the data to be restored in a dedicated location in SAR RAM.
Some general comments:
- can the cluster PM notifier be used for the save path?
Nope. This is for device OFF only case. CPU Cluster state as such has no dependency.
Quoted 3 lines
- This patch adds lots of data that is immediately removed by the next ?patch. ?Probably the two just need to be combined.
iormap() hunk from this patch can be completely dropped since it is getting fixed in next patch. Other infrastructure is maintained.
Quoted 4 lines
-
BUG_ON()should not be used unless there is absolutely no recovery ?path, since it casues a full kernel panic. ? Instead, some error ?recovery should be added.
WARN_ON should suffice.
PATCH v2 6/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
Quoted 36 lines · Santosh
Quoted 8 lines · Kevin Hilman
Quoted 3 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The SAR RAM is maintained during Device OFF mode.
so why is this patch bothering to save and restore it?
SAR RAM is maintained(not powered down) but somebody needs to feel the contents which will be preserved :-)
Quoted 24 lines
-ECONFUSEDQuoted 21 lines
The register layout
is fixed in SAR ROM. SAR is split into 4 banks with different privilege accesses based on device type?--------------------------------------------------------------- ?Access mode ? ? ? ? ?Bank ? ?Address Range ?--------------------------------------------------------------- ?HS/GP : Public ? ? ? ? ? ? ? 1 ? ? ? 0x4A32_6000 - 0x4A32_6FFF (4kB) ?HS/GP : Public ? ? ? ? ? ? ? 2 ? ? ? 0x4A32_7000 - 0x4A32_73FF (1kB)
?HS/EMU : Secured
?GP : Public ? ? ? ? ?3 ? ? ? 0x4A32_8000 - 0x4A32_87FF (2kB)?HS/GP :Secure
?write once. ? ? ? ? ?4 ? ? ? 0x4A32_9000 - 0x4A32_93FF (1kB) ?---------------------------------------------------------------The save process is done entirely by software and restore is done by hardware using the auto-restore feature. The restore feature is enabled by default and cannot be disabled. The software must save the data to be restored in a dedicated location in SAR RAM.
Quoted 6 lines
Quoted 4 lines
Some general comments:
- can the cluster PM notifier be used for the save path?
Nope. This is for device OFF only case. CPU Cluster state as such has no dependency.
Yeah, I see now. I like your idea of a device-off notifier chain modeled on the CPU PM notifier chain.
Quoted 5 lines
Quoted 3 lines
- This patch adds lots of data that is immediately removed by the next ?patch. ?Probably the two just need to be combined.
iormap()hunk from this patch can be completely dropped since it is getting fixed in next patch. Other infrastructure is maintained.
Look again at how much stuff is deleted in the next patch that is added in this patch, and think about how a reviewer is supposed to follow that easily.
Quoted 5 lines
Quoted 4 lines
-
BUG_ON()should not be used unless there is absolutely no recovery ?path, since it casues a full kernel panic. ? Instead, some error ?recovery should be added.
WARN_ONshould suffice.
Not really. Error recovery should be added.
Kevin
PATCH v2 6/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
Quoted 51 lines · Kevin Hilman
Quoted 36 lines · Santosh
Quoted 8 lines · Kevin Hilman
Quoted 3 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The SAR RAM is maintained during Device OFF mode.
so why is this patch bothering to save and restore it?
SAR RAM is maintained(not powered down) but somebody needs to feel the contents which will be preserved :-)
Quoted 24 lines
-ECONFUSEDQuoted 21 lines
The register layout
is fixed in SAR ROM. SAR is split into 4 banks with different privilege accesses based on device type?--------------------------------------------------------------- ?Access mode ? ? ? ? ?Bank ? ?Address Range ?--------------------------------------------------------------- ?HS/GP : Public ? ? ? ? ? ? ? 1 ? ? ? 0x4A32_6000 - 0x4A32_6FFF (4kB) ?HS/GP : Public ? ? ? ? ? ? ? 2 ? ? ? 0x4A32_7000 - 0x4A32_73FF (1kB)
?HS/EMU : Secured
?GP : Public ? ? ? ? ?3 ? ? ? 0x4A32_8000 - 0x4A32_87FF (2kB)?HS/GP :Secure
?write once. ? ? ? ? ?4 ? ? ? 0x4A32_9000 - 0x4A32_93FF (1kB) ?---------------------------------------------------------------The save process is done entirely by software and restore is done by hardware using the auto-restore feature. The restore feature is enabled by default and cannot be disabled. The software must save the data to be restored in a dedicated location in SAR RAM.
Quoted 6 lines
Quoted 4 lines
Some general comments:
- can the cluster PM notifier be used for the save path?
Nope. This is for device OFF only case. CPU Cluster state as such has no dependency.
Yeah, I see now. ?I like your idea of a device-off notifier chain modeled on the CPU PM notifier chain.
Quoted 3 lines
Quoted 3 lines
- This patch adds lots of data that is immediately removed by the next ?patch. ?Probably the two just need to be combined.
Quoted 7 lines
Quoted 2 lines
iormap()hunk from this patch can be completely dropped since it is getting fixed in next patch. Other infrastructure is maintained.Look again at how much stuff is deleted in the next patch that is added in this patch, and think about how a reviewer is supposed to follow that easily.
OK. With me. Actually with proposed split of further patch, things can be sorted out in different patches quite well.
Quoted 8 lines
Quoted 5 lines
Quoted 4 lines
-
BUG_ON()should not be used unless there is absolutely no recovery ?path, since it casues a full kernel panic. ? Instead, some error ?recovery should be added.
WARN_ONshould suffice.Not really. ?Error recovery should be added.
Agree
PATCH v2 6/19 ARM: OMAP4: PM: Add SAR backup support towards device OFF
Quoted 55 lines · Santosh
Quoted 54 lines · Kevin Hilman
Quoted 36 lines · Santosh
Quoted 8 lines · Kevin Hilman
Quoted 3 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The SAR RAM is maintained during Device OFF mode.
so why is this patch bothering to save and restore it?
SAR RAM is maintained(not powered down) but somebody needs to feel the contents which will be preserved :-)
Quoted 24 lines
-ECONFUSEDQuoted 21 lines
The register layout
is fixed in SAR ROM. SAR is split into 4 banks with different privilege accesses based on device type---------------------------------------------------------------
Access mode Bank Address Range
---------------------------------------------------------------HS/GP : Public 1 0x4A32_6000 - 0x4A32_6FFF (4kB) HS/GP : Public 2 0x4A32_7000 - 0x4A32_73FF (1kB)HS/EMU : Secured
GP : Public 3 0x4A32_8000 - 0x4A32_87FF (2kB)HS/GP :Secure
write once. 4 0x4A32_9000 - 0x4A32_93FF (1kB)
---------------------------------------------------------------The save process is done entirely by software and restore is done by hardware using the auto-restore feature. The restore feature is enabled by default and cannot be disabled. The software must save the data to be restored in a dedicated location in SAR RAM.
Quoted 6 lines
Quoted 4 lines
Some general comments:
- can the cluster PM notifier be used for the save path?
Nope. This is for device OFF only case. CPU Cluster state as such has no dependency.
Yeah, I see now. I like your idea of a device-off notifier chain modeled on the CPU PM notifier chain.
Quoted 5 lines
Quoted 3 lines
- This patch adds lots of data that is immediately removed by the next patch. Probably the two just need to be combined.
iormap()hunk from this patch can be completely dropped since it is getting fixed in next patch. Other infrastructure is maintained.
Quoted 6 lines
Quoted 4 lines
Look again at how much stuff is deleted in the next patch that is added in this patch, and think about how a reviewer is supposed to follow that easily.
OK. With me. Actually with proposed split of further patch, things can be sorted out in different patches quite well.
I'll take a look if I'll merge these patches completely or modify the contents. In some work version I had, this patch was completely merged with the next.
Quoted 10 lines
Quoted 9 lines
Quoted 6 lines
Quoted 5 lines
-
BUG_ON()should not be used unless there is absolutely no recovery
path, since it casues a full kernel panic. Instead, some error
recovery should be added.
WARN_ONshould suffice.Not really. Error recovery should be added.
Agree
Will fix that also.
-Tero
PATCH v2 7/19 ARM: OMAP4: Auto generate SAR layout contents
In reply to Tero KristoSAR layout contents are now generated automatically based on SAR ROM contents during boot.
u32 offset description
---------- -------------------------
0 pointer to next entry
1 size of DMA transfer in bytes
2 SAR RAM address for save / restore
3 IO address for save / restore
sar_layout_generate() parses this info and stores the resulting data to a list of sar_ram_entry structs, which in turn will be used by sar_save.
--- arch/arm/mach-omap2/omap-sar.c | 270 +++++++++++++++++++++++++++------------- 1 files changed, 183 insertions(+), 87 deletions(-)
arch/arm/mach-omap2/omap-sar.c +183 -87
@@ -2,7 +2,8 @@* OMAP4 Save Restore source file * * Copyright (C) 2010 Texas Instruments, Inc. -* Written by Santosh Shilimkar <[email protected]> +* Santosh Shilimkar <[email protected]> +* Tero Kristo <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +15,7 @@#include <linux/io.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/slab.h> #include "iomap.h" #include "pm.h"
@@ -25,35 +27,18 @@#include "cminst44xx.h" static void __iomem *sar_ram_base; -static void __iomem *omap4_sar_modules[MAX_SAR_MODULES ];static struct powerdomain *l3init_pwrdm;static struct clockdomain *l3init_clkdm;static struct clk *usb_host_ck, *usb_tll_ck; -/* -* SAR_RAM1 register layout consist of EMIF1, EMIF2, CM1, CM2, -* CONTROL_CORE efuse, DMM and USB TLL registers. -* The layout is arranged is a two dimentional array like -* below, -* const u32 sar_ramX_layout[nb_regs_sets][4] = { -* {module_index, reg_offset, size, sar_ram_offset}, -* } -*/ -static const u32 omap443x_sar_ram1_layout[][4 ] = { -}; - -/* -* SAR_RAM2 register layout consist of SYSCTRL_PADCONF_CORE regsiters -*/ -static const u32 omap443x_sar_ram2_layout[][4 ] = { +struct sar_ram_entry { +void __iomem *io_base; +u32 offset; +u32 size; +u32 ram_addr; }; -/* -* SAR_RAM3 and SAR_RAM4 layout is not listed since moslty it's handle by -* secure software. -*/ -static const u32 omap443x_sar_ram3_layout[][4 ] = { -}; +static struct sar_ram_entry *sar_ram_layout[3 ];/* * omap_sar_save :
@@ -63,25 +48,20 @@ static const u32 omap443x_sar_ram3_layout[][4] = {* @sar_bank_offset - where to backup * @sar_layout - constant table containing the backup info */ -static void sar_save (u32 nb_regs,u32 sar_bank,const u32 sar_layout_table[][4 ]) +static void sar_save (struct sar_ram_entry *entry) { -u32 reg_val, size, i, j; +u32 reg_val, size, i;void __iomem *reg_read_addr, *sar_wr_addr; -for (i =0 ; i < nb_regs; i++) { -if (omap4_sar_modules[(sar_layout_table[i][MODULE_ADDR_IDX ])]) { - size = sar_layout_table[i][MODULE_NB_REGS_IDX ]; - reg_read_addr = - omap4_sar_modules[sar_layout_table[i] - [MODULE_ADDR_IDX ]] - + sar_layout_table[i][MODULE_OFFSET_IDX ]; - sar_wr_addr = sar_ram_base + sar_bank + - sar_layout_table[i][SAR_RAM_OFFSET_IDX ]; -for (j =0 ; j < size; j++) { - reg_val =__raw_readl (reg_read_addr + j *4 ); -__raw_writel (reg_val, sar_wr_addr + j *4 ); - } +while (entry->size) { + size = entry->size; + reg_read_addr = entry->io_base + entry->offset; + sar_wr_addr = sar_ram_base + entry->ram_addr; +for (i =0 ; i < size; i++) { + reg_val =__raw_readl (reg_read_addr + i *4 ); +__raw_writel (reg_val, sar_wr_addr + i *4 ); } + entry++; } }
@@ -100,8 +80,7 @@ static void save_sar_bank3(void) l4_secure_clkdm =clkdm_lookup ("l4_secure_clkdm" );clkdm_wakeup (l4_secure_clkdm); -sar_save (ARRAY_SIZE (omap443x_sar_ram3_layout),SAR_BANK3_OFFSET , - omap443x_sar_ram3_layout); +sar_save (sar_ram_layout[2 ]);clkdm_allow_idle (l4_secure_clkdm); }
@@ -155,8 +134,7 @@ int omap_sar_save(void)clk_enable (usb_tll_ck);/* Save SAR BANK1 */ -sar_save (ARRAY_SIZE (omap443x_sar_ram1_layout),SAR_BANK1_OFFSET , - omap443x_sar_ram1_layout); +sar_save (sar_ram_layout[0 ]);clk_disable (usb_host_ck);clk_disable (usb_tll_ck);
@@ -164,8 +142,7 @@ int omap_sar_save(void)clkdm_allow_idle (l3init_clkdm);/* Save SAR BANK2 */ -sar_save (ARRAY_SIZE (omap443x_sar_ram2_layout),SAR_BANK2_OFFSET , - omap443x_sar_ram2_layout); +sar_save (sar_ram_layout[1 ]);return 0 ; }
@@ -189,7 +166,8 @@ int omap_sar_save(void)void omap_sar_overwrite (void ) {u32 val =0 ; -u32 offset =0 ; +u32 usb_offset =0x2ec ; +u32 usb_offset2 =0x91c ;/* Overwriting Phase1 data to be restored */ /* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */
@@ -204,7 +182,7 @@ void omap_sar_overwrite(void)/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */ val =__raw_readl (OMAP4430_CM_SHADOW_FREQ_CONFIG1 ); val |=1 <<OMAP4430_FREQ_UPDATE_SHIFT ; - val &= ~OMAP4430_DLL_OVERRIDE_MASK ; + val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK ;__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET +0x104 );/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */ __raw_writel (0x3 , sar_ram_base +SAR_BANK1_OFFSET +0x124 );
@@ -212,29 +190,29 @@ void omap_sar_overwrite(void)/* Overwriting Phase2a data to be restored */ /* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */ __raw_writel (0x00000012 , - sar_ram_base +SAR_BANK1_OFFSET +0x2ec + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset);/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */ __raw_writel (0x00000011 , - sar_ram_base +SAR_BANK1_OFFSET +0x2f0 + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset +4 );/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */ __raw_writel (0x000090e8 , - sar_ram_base +SAR_BANK1_OFFSET +0x2f4 + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset +8 );/* Overwriting Phase2b data to be restored */ /* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ val =__raw_readl (OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL ); val &= (OMAP4430_CLKSEL_UTMI_P1_MASK |OMAP4430_CLKSEL_UTMI_P2_MASK ); -__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET +0x91c + offset); +__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET + usb_offset2);/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ __raw_writel (0x0000000 , - sar_ram_base +SAR_BANK1_OFFSET +0x920 + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +4 );/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */ __raw_writel (0x00000040 , - sar_ram_base +SAR_BANK1_OFFSET +0x924 + offset); + sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +8 );/* readback to ensure data reaches to SAR RAM */ barrier (); - val =__raw_readl (sar_ram_base +SAR_BANK1_OFFSET +0x924 + offset); + val =__raw_readl (sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +8 ); }void __iomem *omap4_get_sar_ram_base (void )
@@ -242,6 +220,152 @@ void __iomem *omap4_get_sar_ram_base(void)return sar_ram_base; } +static const u32 sar_rom_phases[] = { +0 ,0x30 ,0x60 +}; + +struct sar_module { +void __iomem *io_base; +u32 base; +u32 size; +bool invalid; +}; + +static struct sar_module *sar_modules; + +static void sar_ioremap_modules (void ) +{ +struct sar_module *mod; + + mod = sar_modules; + +while (mod->base) { +if (!mod->invalid) { + mod->io_base =ioremap (mod->base, mod->size); +if (!mod->io_base) +pr_err ("%s: ioremap failed for %08x[%08x]\n" , + __func__, mod->base, mod->size); +BUG_ON (!mod->io_base); + } + mod++; + } +} + +static int set_sar_io_addr (struct sar_ram_entry *entry,u32 addr) +{ +struct sar_module *mod; + + mod = sar_modules; + +while (mod->base) { +if (addr >= mod->base && addr <= mod->base + mod->size) { +if (mod->invalid) +break ; + entry->io_base = mod->io_base; + entry->offset = addr - mod->base; +return 0 ; + } + mod++; + } +pr_warn ("%s: no matching sar_module for %08x\n" , __func__, addr); +return -EINVAL ; +} + +static int sar_layout_generate (void ) +{ +int phase; +void __iomem *sarrom; +u32 rombase, romend, rambase, ramend; +u32 offset, next; +u16 size; +u32 ram_addr, io_addr; +void *sarram; +struct sar_ram_entry *entry[3 ]; +int bank; +int ret =0 ; + +pr_info ("generating sar_ram layout...\n" ); + + rombase =OMAP44XX_SAR_ROM_BASE ; + romend = rombase +SZ_8K ; + rambase =OMAP44XX_SAR_RAM_BASE ; + ramend = rambase +SAR_BANK4_OFFSET -1 ; + + sarrom =ioremap (rombase,SZ_8K ); + +/* Allocate temporary memory for sar ram layout */ + sarram =kmalloc (SAR_BANK4_OFFSET ,GFP_KERNEL ); +for (bank =0 ; bank <3 ; bank++) + entry[bank] = sarram +SAR_BANK2_OFFSET * bank; + +for (phase =0 ; phase <ARRAY_SIZE (sar_rom_phases); phase++) { + offset = sar_rom_phases[phase]; + +while (1 ) { + next =__raw_readl (sarrom + offset); + size =__raw_readl (sarrom + offset +4 ) &0xffff ; + ram_addr =__raw_readl (sarrom + offset +8 ); + io_addr =__raw_readl (sarrom + offset +12 ); + +if (ram_addr >= rambase && ram_addr <= ramend) { +/* Valid ram address, add entry */ + ram_addr -= rambase; + bank = ram_addr /SAR_BANK2_OFFSET ; +if (!set_sar_io_addr (entry[bank], io_addr)) { + entry[bank]->size = size; + entry[bank]->ram_addr = ram_addr; + entry[bank]++; + } + } + +if (next < rombase || next > romend) +break ; + + offset = next - rombase; + } + } + +for (bank =0 ; bank <3 ; bank++) { + size = (u32 )entry[bank] - + (u32)(sarram +SAR_BANK2_OFFSET * bank); + sar_ram_layout[bank] =kmalloc (size + +sizeof (struct sar_ram_entry ),GFP_KERNEL ); +if (!sar_ram_layout[bank]) { +pr_err ("%s: kmalloc failed\n" , __func__); + goto cleanup; + } +memcpy (sar_ram_layout[bank], sarram +SAR_BANK2_OFFSET * bank, + size); +memset ((void *)sar_ram_layout[bank] + size,0 , +sizeof (struct sar_ram_entry )); + entry[bank] = sar_ram_layout[bank]; + } + +cleanup: +kfree (sarram); +iounmap (sarrom); +pr_info ("sar ram layout created\n" ); +return ret; +} + +static struct sar_module omap44xx_sar_modules[] = { + { .base =OMAP44XX_EMIF1_BASE , .size =SZ_1M }, + { .base =OMAP44XX_EMIF2_BASE , .size =SZ_1M }, + { .base =OMAP44XX_DMM_BASE , .size =SZ_1M }, + { .base =OMAP4430_CM1_BASE , .size =SZ_8K }, + { .base =OMAP4430_CM2_BASE , .size =SZ_8K }, + { .base =OMAP44XX_C2C_BASE , .size =SZ_1M }, + { .base =OMAP443X_CTRL_BASE , .size =SZ_4K }, + { .base =L3_44XX_BASE_CLK1 , .size =SZ_1M }, + { .base =L3_44XX_BASE_CLK2 , .size =SZ_1M }, + { .base =L3_44XX_BASE_CLK3 , .size =SZ_1M }, + { .base =OMAP44XX_USBTLL_BASE , .size =SZ_1M }, + { .base =OMAP44XX_UHH_CONFIG_BASE , .size =SZ_1M }, + { .base =L4_44XX_PHYS , .size =SZ_4M }, + { .base =L4_PER_44XX_PHYS , .size =SZ_4M }, + { .base =0 }, +}; +/* * SAR RAM used to save and restore the HW * context in low power modes
@@ -262,39 +386,11 @@ static int __init omap4_sar_ram_init(void) sar_ram_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K );BUG_ON (!sar_ram_base); -/* -* All these are static mappings so ioremap() will -* just return with mapped VA -*/ - omap4_sar_modules[EMIF1_INDEX ] =ioremap (OMAP44XX_EMIF1_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[EMIF1_INDEX ]); - omap4_sar_modules[EMIF2_INDEX ] =ioremap (OMAP44XX_EMIF2_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[EMIF2_INDEX ]); - omap4_sar_modules[DMM_INDEX ] =ioremap (OMAP44XX_DMM_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[DMM_INDEX ]); - omap4_sar_modules[CM1_INDEX ] =ioremap (OMAP4430_CM1_BASE ,SZ_8K ); -BUG_ON (!omap4_sar_modules[CM1_INDEX ]); - omap4_sar_modules[CM2_INDEX ] =ioremap (OMAP4430_CM2_BASE ,SZ_8K ); -BUG_ON (!omap4_sar_modules[CM2_INDEX ]); - omap4_sar_modules[C2C_INDEX ] =ioremap (OMAP44XX_C2C_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[C2C_INDEX ]); - omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX ] = -ioremap (OMAP443X_CTRL_BASE ,SZ_4K ); -BUG_ON (!omap4_sar_modules[CTRL_MODULE_PAD_CORE_INDEX ]); - omap4_sar_modules[L3_CLK1_INDEX ] =ioremap (L3_44XX_BASE_CLK1 ,SZ_1M ); -BUG_ON (!omap4_sar_modules[L3_CLK1_INDEX ]); - omap4_sar_modules[L3_CLK2_INDEX ] =ioremap (L3_44XX_BASE_CLK2 ,SZ_1M ); -BUG_ON (!omap4_sar_modules[L3_CLK2_INDEX ]); - omap4_sar_modules[L3_CLK3_INDEX ] =ioremap (L3_44XX_BASE_CLK3 ,SZ_1M ); -BUG_ON (!omap4_sar_modules[L3_CLK3_INDEX ]); - omap4_sar_modules[USBTLL_INDEX ] =ioremap (OMAP44XX_USBTLL_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[USBTLL_INDEX ]); - omap4_sar_modules[UHH_INDEX ] =ioremap (OMAP44XX_UHH_CONFIG_BASE ,SZ_1M ); -BUG_ON (!omap4_sar_modules[UHH_INDEX ]); - omap4_sar_modules[L4CORE_INDEX ] =ioremap (L4_44XX_PHYS ,SZ_4M ); -BUG_ON (!omap4_sar_modules[L4CORE_INDEX ]); - omap4_sar_modules[L4PER_INDEX ] =ioremap (L4_PER_44XX_PHYS ,SZ_4M ); -BUG_ON (!omap4_sar_modules[L4PER_INDEX ]); + sar_modules = omap44xx_sar_modules; + +sar_ioremap_modules (); + +sar_layout_generate ();/* * SAR BANK3 contains all firewall settings and it's saved through
Signature · 1 line
1.7.4.1
PATCH v2 8/19 ARM: OMAP4: SAR: generate overwrite data based on SAR ROM contents
In reply to Tero Kristoomap_sar_overwrite() now uses offsets detected during init time from the SAR ROM contents.
--- arch/arm/mach-omap2/omap-sar.c | 159 +++++++++++++++++++++++++++++----------- 1 files changed, 115 insertions(+), 44 deletions(-)
arch/arm/mach-omap2/omap-sar.c +115 -44
@@ -38,7 +38,52 @@ struct sar_ram_entry {u32 ram_addr; }; +struct sar_overwrite_entry { +u32 reg_addr; +u32 sar_offset; +bool valid; +}; + +enum { +MEMIF_CLKSTCTRL_IDX , +SHADOW_FREQ_CFG2_IDX , +SHADOW_FREQ_CFG1_IDX , +MEMIF_CLKSTCTRL_2_IDX , +HSUSBHOST_CLKCTRL_IDX , +HSUSBHOST_CLKCTRL_2_IDX , +OW_IDX_SIZE +}; +static struct sar_ram_entry *sar_ram_layout[3 ]; +static struct sar_overwrite_entry *sar_overwrite_data; + +static struct sar_overwrite_entry omap4_sar_overwrite_data[OW_IDX_SIZE ] = { + [MEMIF_CLKSTCTRL_IDX ] = { .reg_addr =0x4a009e0c }, + [SHADOW_FREQ_CFG2_IDX ] = { .reg_addr =0x4a004e2c }, + [SHADOW_FREQ_CFG1_IDX ] = { .reg_addr =0x4a004e30 }, + [MEMIF_CLKSTCTRL_2_IDX ] = { .reg_addr =0x4a009e0c }, + [HSUSBHOST_CLKCTRL_IDX ] = { .reg_addr =0x4a009e54 }, + [HSUSBHOST_CLKCTRL_2_IDX ] = { .reg_addr =0x4a009e54 }, +}; + +static void check_overwrite_data (u32 io_addr,u32 ram_addr,int size) +{ +int i; + +while (size) { +for (i =0 ; i <OW_IDX_SIZE ; i++) { +if (sar_overwrite_data[i].reg_addr == io_addr && + !sar_overwrite_data[i].valid) { + sar_overwrite_data[i].sar_offset = ram_addr; + sar_overwrite_data[i].valid = true; +break ; + } + } + size--; + io_addr +=4 ; + ram_addr +=4 ; + } +}/* * omap_sar_save :
@@ -166,53 +211,76 @@ int omap_sar_save(void)void omap_sar_overwrite (void ) {u32 val =0 ; -u32 usb_offset =0x2ec ; -u32 usb_offset2 =0x91c ; - -/* Overwriting Phase1 data to be restored */ -/* CM2 MEMIF_CLKTRCTRL = SW_WKUP, before FREQ UPDATE */ -__raw_writel (0x2 , sar_ram_base +SAR_BANK1_OFFSET +0xd0 ); -/* CM1 CM_SHADOW_FREQ_CONFIG2, Enable FREQ UPDATE */ - val =__raw_readl (OMAP4430_CM_SHADOW_FREQ_CONFIG2 ); -/* -* FIXME: Implement FREQ UPDATE for L#/M5 before enabling this -* val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT; -*/ -__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET +0x100 ); -/* CM1 CM_SHADOW_FREQ_CONFIG1, Enable FREQ UPDATE */ - val =__raw_readl (OMAP4430_CM_SHADOW_FREQ_CONFIG1 ); - val |=1 <<OMAP4430_FREQ_UPDATE_SHIFT ; - val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK ; -__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET +0x104 ); -/* CM2 MEMIF_CLKTRCTRL = HW_AUTO, after FREQ UPDATE */ -__raw_writel (0x3 , sar_ram_base +SAR_BANK1_OFFSET +0x124 ); - -/* Overwriting Phase2a data to be restored */ -/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */ -__raw_writel (0x00000012 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset); -/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */ -__raw_writel (0x00000011 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset +4 ); -/* CM2 CM_SDMA_STATICDEP : Enable static depedency for SAR modules */ -__raw_writel (0x000090e8 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset +8 ); - -/* Overwriting Phase2b data to be restored */ -/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ - val =__raw_readl (OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL ); - val &= (OMAP4430_CLKSEL_UTMI_P1_MASK |OMAP4430_CLKSEL_UTMI_P2_MASK ); -__raw_writel (val, sar_ram_base +SAR_BANK1_OFFSET + usb_offset2); -/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ -__raw_writel (0x0000000 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +4 ); -/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */ -__raw_writel (0x00000040 , - sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +8 ); +u32 offset =0 ; + +if (sar_overwrite_data[MEMIF_CLKSTCTRL_IDX ].valid) +__raw_writel (0x2 , sar_ram_base + + sar_overwrite_data[MEMIF_CLKSTCTRL_IDX ].sar_offset); + +if (sar_overwrite_data[SHADOW_FREQ_CFG1_IDX ].valid) { + offset = sar_overwrite_data[SHADOW_FREQ_CFG1_IDX ].sar_offset; + val =__raw_readl (sar_ram_base + offset); + val |=1 <<OMAP4430_FREQ_UPDATE_SHIFT ; + val &= ~OMAP4430_DLL_OVERRIDE_2_2_MASK ; +__raw_writel (val, sar_ram_base + offset); + } + +if (sar_overwrite_data[SHADOW_FREQ_CFG2_IDX ].valid) { + offset = sar_overwrite_data[SHADOW_FREQ_CFG2_IDX ].sar_offset; + val =__raw_readl (sar_ram_base + offset); +/* +* FIXME: Implement FREQ UPDATE for L#/M5 before enabling +* val |= 1 << OMAP4430_FREQ_UPDATE_SHIFT; +*/ +__raw_writel (val, sar_ram_base + offset); + } + +if (sar_overwrite_data[MEMIF_CLKSTCTRL_2_IDX ].valid) +__raw_writel (0x3 , sar_ram_base + + sar_overwrite_data[MEMIF_CLKSTCTRL_2_IDX ].sar_offset); + +if (sar_overwrite_data[HSUSBHOST_CLKCTRL_IDX ].valid) { + offset = sar_overwrite_data[HSUSBHOST_CLKCTRL_IDX ].sar_offset; + +/* Overwriting Phase2a data to be restored */ +/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 1, MODULEMODE = 2 */ +__raw_writel (OMAP4430_SAR_MODE_MASK |0x2 , + sar_ram_base + offset); +/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 1, MODULEMODE = 1 */ +__raw_writel (OMAP4430_SAR_MODE_MASK |0x1 , + sar_ram_base + offset +4 ); +/* +* CM2 CM_SDMA_STATICDEP : Enable static depedency for +* SAR modules +*/ +__raw_writel (OMAP4430_L4WKUP_STATDEP_MASK | +OMAP4430_L4CFG_STATDEP_MASK | +OMAP4430_L3INIT_STATDEP_MASK | +OMAP4430_L3_1_STATDEP_MASK | +OMAP4430_L3_2_STATDEP_MASK | +OMAP4430_ABE_STATDEP_MASK , + sar_ram_base + offset +8 ); + } + +if (sar_overwrite_data[HSUSBHOST_CLKCTRL_2_IDX ].valid) { + offset = sar_overwrite_data[HSUSBHOST_CLKCTRL_2_IDX ].sar_offset; + +/* Overwriting Phase2b data to be restored */ +/* CM_L3INIT_USB_HOST_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ + val =__raw_readl (OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL ); + val &= (OMAP4430_CLKSEL_UTMI_P1_MASK | +OMAP4430_CLKSEL_UTMI_P2_MASK ); +__raw_writel (val, sar_ram_base + offset); +/* CM_L3INIT_USB_TLL_CLKCTRL: SAR_MODE = 0, MODULEMODE = 0 */ +__raw_writel (0 , sar_ram_base + offset +4 ); +/* CM2 CM_SDMA_STATICDEP : Clear the static depedency */ +__raw_writel (OMAP4430_L3_2_STATDEP_MASK , + sar_ram_base + offset +8 ); + }/* readback to ensure data reaches to SAR RAM */ barrier (); - val =__raw_readl (sar_ram_base +SAR_BANK1_OFFSET + usb_offset2 +8 ); + val =__raw_readl (sar_ram_base + offset); }void __iomem *omap4_get_sar_ram_base (void )
@@ -314,6 +382,8 @@ static int sar_layout_generate(void)if (!set_sar_io_addr (entry[bank], io_addr)) { entry[bank]->size = size; entry[bank]->ram_addr = ram_addr; +check_overwrite_data (io_addr, ram_addr, + size); entry[bank]++; } }
@@ -387,6 +457,7 @@ static int __init omap4_sar_ram_init(void)BUG_ON (!sar_ram_base); sar_modules = omap44xx_sar_modules; + sar_overwrite_data = omap4_sar_overwrite_data;sar_ioremap_modules ();
Signature · 1 line
1.7.4.1
PATCH v2 9/19 ARM: OMAP4: PM: add errata support
In reply to Tero KristoAdded similar PM errata flag support as omap3 has. A few errata flags will be added in subsequent patches.
--- arch/arm/mach-omap2/pm.h | 7 +++++++ arch/arm/mach-omap2/pm44xx.c | 1 + 2 files changed, 8 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm.h +7 -0
@@ -130,6 +130,13 @@ extern void enable_omap3630_toggle_l2_on_restore(void);static inline void enable_omap3630_toggle_l2_on_restore (void ) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 ) +extern u16 pm44xx_errata; +#define IS_PM44XX_ERRATUM (id) (pm44xx_errata & (id)) +#else +#define IS_PM44XX_ERRATUM (id) 0 +#endif +#ifdef CONFIG_OMAP_SMARTREFLEX extern int omap_devinit_smartreflex (void );extern void omap_enable_smartreflex_on_init (void );
arch/arm/mach-omap2/pm44xx.c +1 -0
@@ -35,6 +35,7 @@ struct power_state { };static LIST_HEAD (pwrst_list); +u16 pm44xx_errata;#ifdef CONFIG_SUSPEND static int omap4_pm_suspend (void )
Signature · 1 line
1.7.4.1
PATCH v2 9/19 ARM: OMAP4: PM: add errata support
Quoted 2 lines · Tero Kristo
Added similar PM errata flag support as omap3 has. A few errata flags will be added in subsequent patches.
Considering that we might have erratas for future SoCs as well, should'nt we just
set up a common errata flag for all SoCs and since we have i123 numbers, would it help being able to reuse errata flags cross SoC generations (if we need to)?
Quoted 40 lines
Signed-off-by Tero Kristo <[email protected]>---
?arch/arm/mach-omap2/pm.h ? ? | ? ?7 +++++++
?arch/arm/mach-omap2/pm44xx.c | ? ?1 +
?2 files changed, 8 insertions(+), 0 deletions(-)arch/arm/mach-omap2/pm.h +0
-0@@ -130,6 +130,13 @@ extern void enable_omap3630_toggle_l2_on_restore(void); ?static inline void enable_omap3630_toggle_l2_on_restore(void) { }?#endif ? ? ? ? /*
defined(CONFIG_PM)&&defined(CONFIG_ARCH_OMAP3)*/arch/arm/mach-omap2/pm.h +7
-0+#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 ) +extern u16 pm44xx_errata; +#define IS_PM44XX_ERRATUM (id) ? ? ? ? ?(pm44xx_errata & (id)) +#else +#define IS_PM44XX_ERRATUM (id) ? ? ? ? ?0 +#endif +?#ifdef
CONFIG_OMAP_SMARTREFLEX
?extern intomap_devinit_smartreflex(void); ?extern voidomap_enable_smartreflex_on_init(void);arch/arm/mach-omap2/pm44xx.c +1
-0@@ -35,6 +35,7 @@ struct power_state { ?}; ?static LIST_HEAD(pwrst_list); +u16 pm44xx_errata;?#ifdef
CONFIG_SUSPEND
?static intomap4_pm_suspend(void)
--
1.7.4.1
Quoted 4 lines
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Regards,
Nishanth Menon
PATCH v2 9/19 ARM: OMAP4: PM: add errata support
Quoted 8 lines · Nishanth
Quoted 2 lines · Tero Kristo
Added similar PM errata flag support as omap3 has. A few errata flags will be added in subsequent patches.
Considering that we might have erratas for future SoCs as well, should'nt we just
set up a common errata flag for all SoCs and since we have i123 numbers, would it help being able to reuse errata flags cross SoC generations (if we need to)?
Not sure... how quickly do we run out of bits that way? :) Also, at least pm34xx / pm44xx erratas don't have anything in common. We can probably re-use pm44xx erratas for omap5 though.
One annoyance is that, the OMAP4 erratas are going to have a number of ROM code erratas on them, which don't really have any public i123 numbers available. >.<
-Tero
Quoted 49 lines
Quoted 41 lines
Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/pm.h | 7 +++++++ arch/arm/mach-omap2/pm44xx.c | 1 + 2 files changed, 8 insertions(+), 0 deletions(-)arch/arm/mach-omap2/pm.h +7
-0@@ -130,6 +130,13 @@ extern void enable_omap3630_toggle_l2_on_restore(void);static inline void enable_omap3630_toggle_l2_on_restore (void ) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 ) +extern u16 pm44xx_errata; +#define IS_PM44XX_ERRATUM (id) (pm44xx_errata & (id)) +#else +#define IS_PM44XX_ERRATUM (id) 0 +#endif +#ifdef CONFIG_OMAP_SMARTREFLEX extern int omap_devinit_smartreflex (void );extern void omap_enable_smartreflex_on_init (void );arch/arm/mach-omap2/pm44xx.c +1
-1@@ -35,6 +35,7 @@ struct power_state { };static LIST_HEAD (pwrst_list); +u16 pm44xx_errata;#ifdef CONFIG_SUSPEND static int omap4_pm_suspend (void ) --1.7.4.1
Quoted 4 lines
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernelRegards,
Nishanth Menon
PATCH v2 9/19 ARM: OMAP4: PM: add errata support
Quoted 10 lines · Tero Kristo
Quoted 8 lines · Nishanth
Quoted 2 lines · Tero Kristo
Added similar PM errata flag support as omap3 has. A few errata flags will be added in subsequent patches.
Considering that we might have erratas for future SoCs as well, should'nt we just
set up a common errata flag for all SoCs and since we have i123 numbers, would it help being able to reuse errata flags cross SoC generations (if we need to)?
Quoted 7 lines
Not sure... how quickly do we run out of bits that way? :) Also, at least pm34xx / pm44xx erratas don't have anything in common. We can probably re-use pm44xx erratas for omap5 though.
One annoyance is that, the OMAP4 erratas are going to have a number of ROM code erratas on them, which don't really have any public i123 numbers available. >.<
Sounds good to me.
Regards,
Nishanth Menon
PATCH v2 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
In reply to Tero KristoFrom: Santosh Shilimkar <[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
The IVAHD Clocks and Power Domain settings are:
IVAHD_CM2 IVAHD_CLKCTRL_MODULE_MODE = DISABLE IVAHD_CM2 SL2_CLKCTRL_MODULE_MODE = DISABLE IVAHD_CM2 SL2_CLKSTCTRL_CLKTRCTRL = HW_AUTO IVAHD_PRM IVAHD_PWRSTCTRL_POWERSTATE = OFF
The TESLA Clocks and Power Domain settings are:
TESLA_CM1 TESLA_CLKCTRL_MODULE_MODE = DISABLE TESLA_CM1 TESLA_CLKSTCTRL_CLKTRCTRL = HW_AUTO TESLA_PRM TESLA_PWRSTCTRL_POWERSTATE = OFF
This patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
This erratum impacts only OMAP4430 HS/EMU and is fixed on devices from OMAP4430 ES2.3 onwards.
--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 53 +++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.h | 2 + arch/arm/mach-omap2/pm44xx.c | 11 ++++++ 3 files changed, 66 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +53 -0
@@ -52,6 +52,7 @@#include <plat/omap44xx.h> +#include "iomap.h" #include "common.h" #include "omap4-sar-layout.h" #include "pm.h"
@@ -76,6 +77,24 @@ static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);static struct powerdomain *mpuss_pd;static void __iomem *sar_base; +struct reg_tuple { +void __iomem *addr; +u32 val; +}; + +static struct reg_tuple tesla_reg[] = { + {.addr =OMAP4430_CM_TESLA_CLKSTCTRL }, + {.addr =OMAP4430_CM_TESLA_TESLA_CLKCTRL }, + {.addr =OMAP4430_PM_TESLA_PWRSTCTRL }, +}; + +static struct reg_tuple ivahd_reg[] = { + {.addr =OMAP4430_CM_IVAHD_CLKSTCTRL }, + {.addr =OMAP4430_CM_IVAHD_IVAHD_CLKCTRL }, + {.addr =OMAP4430_CM_IVAHD_SL2_CLKCTRL }, + {.addr =OMAP4430_PM_IVAHD_PWRSTCTRL } +}; +/* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup.
@@ -215,6 +234,34 @@ static void save_l2x0_context(void) {}#endif +static inline void save_ivahd_tesla_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (tesla_reg); i++) + tesla_reg[i].val =__raw_readl (tesla_reg[i].addr); + +for (i =0 ; i <ARRAY_SIZE (ivahd_reg); i++) + ivahd_reg[i].val =__raw_readl (ivahd_reg[i].addr); +} + +static inline void restore_ivahd_tesla_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (tesla_reg); i++) +__raw_writel (tesla_reg[i].val, tesla_reg[i].addr); + +for (i =0 ; i <ARRAY_SIZE (ivahd_reg); i++) +__raw_writel (ivahd_reg[i].val, ivahd_reg[i].addr); +} +/** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming
@@ -273,11 +320,14 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)omap_sar_overwrite ();omap4_cm_prepare_off ();omap4_dpll_prepare_off (); +save_ivahd_tesla_regs (); save_state =3 ; }else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) { +save_ivahd_tesla_regs (); save_state =2 ; }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) { +save_ivahd_tesla_regs (); save_state =3 ; }
@@ -302,6 +352,9 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); +if (omap4_mpuss_read_prev_context_state ()) +restore_ivahd_tesla_regs (); +if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();omap4_cm_resume_off ();
arch/arm/mach-omap2/pm.h +2 -0
@@ -130,6 +130,8 @@ extern void enable_omap3630_toggle_l2_on_restore(void);static inline void enable_omap3630_toggle_l2_on_restore (void ) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ +#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM (1 << 0) +#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 )extern u16 pm44xx_errata;#define IS_PM44XX_ERRATUM (id) (pm44xx_errata & (id))
arch/arm/mach-omap2/pm44xx.c +11 -0
@@ -263,6 +263,17 @@ static int __init omap4_pm_init(void) (void )clkdm_for_each (omap_pm_clkdms_setup,NULL ); +/* +* ROM code initializes IVAHD and TESLA clock registers during +* secure RAM restore phase on omap4430 EMU/HS devices, thus +* IVAHD / TESLA clock registers must be saved / restored +* during MPU OSWR / device off. +*/ +if (omap_rev () >=OMAP4430_REV_ES1_0 && +omap_rev () <OMAP4430_REV_ES2_3 && +omap_type () !=OMAP2_DEVICE_TYPE_GP ) + pm44xx_errata |=PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM ; +#ifdef CONFIG_SUSPEND omap_pm_suspend = omap4_pm_suspend;#endif
Signature · 1 line
1.7.4.1
PATCH v2 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
Quoted 8 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
Ouch.
Quoted 10 lines
The IVAHD Clocks and Power Domain settings are:
IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTOIVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF
The TESLA Clocks and Power Domain settings are:
TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLETESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTOTESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFF
Quoted 5 lines
This patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
I don't see where this restriction is implemented.
And, can this be hooked into cluster PM notifiers.
Kevin
PATCH v2 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
Quoted 26 lines · Kevin Hilman
Quoted 8 lines · Tero Kristo
From: Santosh Shilimkar<[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
Ouch.
Quoted 13 lines
The IVAHD Clocks and Power Domain settings are:
IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTOIVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF
The TESLA Clocks and Power Domain settings are:
TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLETESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTOTESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFFThis patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Quoted 6 lines
Quoted 2 lines
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
I don't see where this restriction is implemented.
And, can this be hooked into cluster PM notifiers.
Especially since this only effects a subset of revisions, installing the notifier only on effected revisions also removes any overhead on working revisions.
Kevin
PATCH v2 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
Quoted 30 lines · Kevin Hilman
Quoted 29 lines · Kevin Hilman
Quoted 8 lines · Tero Kristo
From: Santosh Shilimkar<[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
Ouch.
Quoted 15 lines
The IVAHD Clocks and Power Domain settings are:
IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTOIVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF
The TESLA Clocks and Power Domain settings are:
TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLETESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTOTESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFFThis patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
Quoted 7 lines
Quoted 3 lines
I don't see where this restriction is implemented.
And, can this be hooked into cluster PM notifiers.
Especially since this only effects a subset of revisions, installing the notifier only on effected revisions also removes any overhead on working revisions.
Where would you recommend adding the notifiers to? Just to the same file or...? pm44xx.c?
-Tero
PATCH v2 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
Quoted 33 lines · Tero Kristo
Quoted 32 lines · Kevin Hilman
Quoted 31 lines · Kevin Hilman
Quoted 8 lines · Tero Kristo
From: Santosh Shilimkar<[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
Ouch.
Quoted 10 lines
The IVAHD Clocks and Power Domain settings are:
IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLEIVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTOIVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF
The TESLA Clocks and Power Domain settings are:
TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLETESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTOTESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFFQuoted 5 lines
This patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
I don't see where this restriction is implemented.
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
And, can this be hooked into cluster PM notifiers.
Especially since this only effects a subset of revisions, installing the notifier only on effected revisions also removes any overhead on working revisions.
Where would you recommend adding the notifiers to? Just to the same file or...?
pm44xx.c?
Same file should be ok.
Kevin
PATCH v2 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
In reply to Kevin HilmanQuoted 23 lines · Kevin Hilman
Quoted 8 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
Ouch.
Quoted 10 lines
The IVAHD Clocks and Power Domain settings are:
? ? ?IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLE ? ? ?IVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLE ? ? ?IVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTO? ? ?IVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF The TESLA Clocks and Power Domain settings are:
? ? ?TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLE ? ? ?TESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTO? ? ?TESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFF
Quoted 8 lines
Quoted 5 lines
This patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
I don't see where this restriction is implemented.
It's handled and the patch is in mainline for some time. We de-scoped MPU OFF from OMAP4430 devices in SW and hardware team de-scoped it in hardware from OMAP4460 onwards. Deepest state on MPUSS cluster is OSWR.
------------
commit a57341f780660800e1463eaedb80ed152ad6b5de
Author: Santosh Shilimkar <[email protected]> Date: Sat Jul 9 20:42:59 2011 -0600
OMAP4: powerdomain data: Remove unsupported MPU powerdomain state
On OMAP4430 devices, because of boot ROM code bug, MPU OFF state can't be attempted independently. When coming out of MPU OFF state, ROM code disables the clocks of IVAHD, TESLA which is not desirable. Hence the MPU OFF state is not usable on OMAP4430 devices.
OMAP4460 onwards, MPU OFF state will be descoped completely because the DDR firewall falls in MPU power domain. When the MPU hit OFF state, DDR won't be accessible for other initiators. The deepest state supported is open switch retention (OSWR) just like CORE and PER PD on OMAP4430.
So in summary MPU power domain OFF state is not supported on OMAP4 and onwards designs. Thanks to new PRCM design, device off mode can still be achieved with power domains hitting OSWR state.
---------------------------------------------
Quoted 2 lines
And, can this be hooked into cluster PM notifiers.
Not needed.
PATCH v2 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
Quoted 30 lines · Santosh
Quoted 29 lines · Kevin Hilman
Quoted 8 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
Ouch.
Quoted 15 lines
The IVAHD Clocks and Power Domain settings are:
? ? ?IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLE ? ? ?IVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLE ? ? ?IVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTO? ? ?IVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF The TESLA Clocks and Power Domain settings are:
? ? ?TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLE ? ? ?TESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTO? ? ?TESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFFThis patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
Quoted 6 lines
Quoted 2 lines
I don't see where this restriction is implemented.
It's handled and the patch is in mainline for some time. We de-scoped MPU OFF from OMAP4430 devices in SW and hardware team de-scoped it in hardware from OMAP4460 onwards. Deepest state on MPUSS cluster is OSWR.
The question was about the changelog.
The changelog makes it sound like the restriction is part of the patch, but it is not. Please update the changlog to clarify that, ideally adding a reference to the commit you mentioned.
Kevin
PATCH v2 10/19 ARM: OMAP4: PM: Work-around for ROM code BUG of IVAHD/TESLA
Quoted 39 lines · Kevin Hilman
Quoted 30 lines · Santosh
Quoted 29 lines · Kevin Hilman
Quoted 8 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
The ROM BUG is when MPU Domain OFF wake up sequence that can compromise IVA and Tesla execution.
At wakeup from MPU OFF on HS device only (not GP device), when restoring the Secure RAM, the ROM Code reconfigures the clocks the same way it is done at Cold Reset.
Ouch.
Quoted 15 lines
The IVAHD Clocks and Power Domain settings are:
? ? ?IVAHD_CM2IVAHD_CLKCTRL_MODULE_MODE= DISABLE ? ? ?IVAHD_CM2SL2_CLKCTRL_MODULE_MODE= DISABLE ? ? ?IVAHD_CM2SL2_CLKSTCTRL_CLKTRCTRL=HW_AUTO? ? ?IVAHD_PRMIVAHD_PWRSTCTRL_POWERSTATE= OFF The TESLA Clocks and Power Domain settings are:
? ? ?TESLA_CM1TESLA_CLKCTRL_MODULE_MODE= DISABLE ? ? ?TESLA_CM1TESLA_CLKSTCTRL_CLKTRCTRL=HW_AUTO? ? ?TESLA_PRMTESLA_PWRSTCTRL_POWERSTATE= OFFThis patch fixes the low power OFF mode code so that the these registers are saved and restore across MPU OFF state.
Also because of this limitation, MPU OFF alone is not targeted without device OFF to avoid IVAHD and TESLA execution impact
Quoted 6 lines
Quoted 2 lines
I don't see where this restriction is implemented.
It's handled and the patch is in mainline for some time. We de-scoped MPU OFF from OMAP4430 devices in SW and hardware team de-scoped it in hardware from OMAP4460 onwards. Deepest state on MPUSS cluster is OSWR.
Quoted 6 lines
The question was about the changelog.
The changelog makes it sound like the restriction is part of the patch, but it is not. ?Please update the changlog to clarify that, ideally adding a reference to the commit you mentioned.
Agree.
PATCH v2 11/19 ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
In reply to Tero KristoFrom: Rajendra Nayak <[email protected]>
On HS devices on the way out of MPU OSWR and OFF ROM code wrongly overwrites the CM L3INSTR registers. So to avoid this, save them and restore on the way out from MPU OSWR/OFF.
This errata applies to all HS/EMU versions of OMAP4.
--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 35 ++++++++++++++++++++++++++++- arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm44xx.c | 8 ++++++ 3 files changed, 43 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +34 -1
@@ -95,6 +95,12 @@ static struct reg_tuple ivahd_reg[] = { {.addr = OMAP4430_PM_IVAHD_PWRSTCTRL} }; +static struct reg_tuple l3instr_reg[] = { + {.addr =OMAP4430_CM_L3INSTR_L3_3_CLKCTRL }, + {.addr =OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL }, + {.addr =OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL }, +}; +/* * Program the wakeup routine address for the CPU0 and CPU1 * used for OFF or DORMANT wakeup.
@@ -262,6 +268,28 @@ static inline void restore_ivahd_tesla_regs(void)__raw_writel (ivahd_reg[i].val, ivahd_reg[i].addr); } +static inline void save_l3instr_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_L3INSTR_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (l3instr_reg); i++) + l3instr_reg[i].val =__raw_readl (l3instr_reg[i].addr); +} + +static inline void restore_l3instr_regs (void ) +{ +int i; + +if (!IS_PM44XX_ERRATUM (PM_OMAP4_ROM_L3INSTR_ERRATUM )) +return ; + +for (i =0 ; i <ARRAY_SIZE (l3instr_reg); i++) +__raw_writel (l3instr_reg[i].val, l3instr_reg[i].addr); +} +/** * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function * The purpose of this function is to manage low power programming
@@ -321,13 +349,16 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)omap4_cm_prepare_off ();omap4_dpll_prepare_off ();save_ivahd_tesla_regs (); +save_l3instr_regs (); save_state =3 ; }else if ((pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_RET ) && (pwrdm_read_logic_retst (mpuss_pd) ==PWRDM_POWER_OFF )) {save_ivahd_tesla_regs (); +save_l3instr_regs (); save_state =2 ; }else if (pwrdm_read_next_pwrst (mpuss_pd) ==PWRDM_POWER_OFF ) {save_ivahd_tesla_regs (); +save_l3instr_regs (); save_state =3 ; }
@@ -352,8 +383,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) wakeup_cpu =smp_processor_id ();set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON ); -if (omap4_mpuss_read_prev_context_state ()) +if (omap4_mpuss_read_prev_context_state ()) {restore_ivahd_tesla_regs (); +restore_l3instr_regs (); + }if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();
arch/arm/mach-omap2/pm.h +1 -0
@@ -131,6 +131,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ #define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM (1 << 0) +#define PM_OMAP4_ROM_L3INSTR_ERRATUM (1 << 1)#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 )extern u16 pm44xx_errata;
arch/arm/mach-omap2/pm44xx.c +8 -0
@@ -274,6 +274,14 @@ static int __init omap4_pm_init(void) omap_type() != OMAP2_DEVICE_TYPE_GP) pm44xx_errata |=PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM ; +/* +* Similar to above errata, ROM code modifies L3INSTR clock +* registers also and these must be saved / restored during +* MPU OSWR / device off. +*/ +if (omap_type () !=OMAP2_DEVICE_TYPE_GP ) + pm44xx_errata |=PM_OMAP4_ROM_L3INSTR_ERRATUM ; +#ifdef CONFIG_SUSPEND omap_pm_suspend = omap4_pm_suspend;#endif
Signature · 1 line
1.7.4.1
PATCH v2 11/19 ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
Quoted 6 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
On HS devices on the way out of MPU OSWR and OFF ROM code wrongly overwrites the CM L3INSTR registers. So to avoid this, save them and restore on the way out from MPU OSWR/OFF.
Quoted 6 lines
This errata applies to all HS/EMU versions of OMAP4.
Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: added omap4 pm errata support]Signed-off-by Tero Kristo <[email protected]>
Let's use the cluster PM notifiers here too, using the PM errata check when registering the notifier.
Kevin
PATCH v2 11/19 ARM: OMAP4: PM: save/restore CM L3INSTR registers when MPU hits OSWR/OFF mode
Quoted 10 lines · Kevin Hilman
Quoted 8 lines · Tero Kristo
From: Rajendra Nayak <[email protected]>
On HS devices on the way out of MPU OSWR and OFF ROM code wrongly overwrites the CM L3INSTR registers. So to avoid this, save them and restore on the way out from MPU OSWR/OFF.
This errata applies to all HS/EMU versions of OMAP4.
Quoted 8 lines
Quoted 4 lines
Signed-off-by Rajendra Nayak <[email protected]>Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: added omap4 pm errata support]Signed-off-by Tero Kristo <[email protected]>Let's use the cluster PM notifiers here too, using the PM errata check when registering the notifier.
Good idea.
PATCH v2 12/19 ARM: OMAP4: PM: update ROM return address for OSWR and OFF
In reply to Tero KristoFrom: Carlos Leija <[email protected]>
At wakeup from OFF/OSWR CPU1 will call secure HAL service through a local secure dispatcher with MMU off, thus ROM will save a PA return address. Later in the wakeup, when SMC driver calls an RPC through omap4_secure_dispatcher (MMU is on now), ROM code won't log the new return address as RPCs are handled different. Thus ROM will attempt to return to a PA address when the MMU is on and the system will hang.
We need to do this for OSWR state and OFF state of mpu power domain, not just for device off(mpu pd OFF).
--- arch/arm/mach-omap2/include/mach/omap-secure.h | 1 + arch/arm/mach-omap2/omap-mpuss-lowpower.c | 13 +++++++++++++ arch/arm/mach-omap2/pm.h | 1 + arch/arm/mach-omap2/pm44xx.c | 8 ++++++++ 4 files changed, 23 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/include/mach/omap-secure.h +1 -0
@@ -43,6 +43,7 @@#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113/* Secure PPA(Primary Protected Application) APIs */ +#define OMAP4_PPA_SERVICE_0 0x21#define OMAP4_PPA_L2_POR_INDEX 0x23#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
arch/arm/mach-omap2/omap-mpuss-lowpower.c +13 -0
@@ -52,6 +52,8 @@#include <plat/omap44xx.h> +#include <mach/omap-secure.h> +#include "iomap.h" #include "common.h" #include "omap4-sar-layout.h"
@@ -384,6 +386,17 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)set_cpu_next_pwrst (wakeup_cpu,PWRDM_POWER_ON );if (omap4_mpuss_read_prev_context_state ()) { +/* +* Dummy dispatcher call after OSWR and OFF +* Restore the right return Kernel address (with MMU on) for +* subsequent calls to secure ROM. Otherwise the return address +* will be to a PA return address and the system will hang. +*/ +if (IS_PM44XX_ERRATUM (PM_OMAP4_ROM_RETURN_ADDRESS_ERRATUM )) +omap_secure_dispatcher (OMAP4_PPA_SERVICE_0 , +FLAG_START_CRITICAL , +0 ,0 ,0 ,0 ,0 ); +restore_ivahd_tesla_regs ();restore_l3instr_regs (); }
arch/arm/mach-omap2/pm.h +1 -0
@@ -132,6 +132,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }#define PM_OMAP4_ROM_IVAHD_TESLA_ERRATUM (1 << 0)#define PM_OMAP4_ROM_L3INSTR_ERRATUM (1 << 1) +#define PM_OMAP4_ROM_RETURN_ADDRESS_ERRATUM (1 << 2)#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP4 )extern u16 pm44xx_errata;
arch/arm/mach-omap2/pm44xx.c +8 -0
@@ -282,6 +282,14 @@ static int __init omap4_pm_init(void)if (omap_type () !=OMAP2_DEVICE_TYPE_GP ) pm44xx_errata |=PM_OMAP4_ROM_L3INSTR_ERRATUM ; +/* +* Restore the right return Kernel address (with MMU on) for +* subsequent calls to secure ROM. Otherwise the return address +* will be to a PA return address and the system will hang. +*/ +if (omap_type () !=OMAP2_DEVICE_TYPE_GP ) + pm44xx_errata |=PM_OMAP4_ROM_RETURN_ADDRESS_ERRATUM ; +#ifdef CONFIG_SUSPEND omap_pm_suspend = omap4_pm_suspend;#endif
Signature · 1 line
1.7.4.1
PATCH v2 12/19 ARM: OMAP4: PM: update ROM return address for OSWR and OFF
Quoted 4 lines · Tero Kristo
From: Carlos Leija <[email protected]>
At wakeup from OFF/OSWR CPU1 will call secure HAL service through a local secure dispatcher with MMU off,
Reviewers who are uninitaited in this level of detail need some more help here (even those who are deeply familiar will need more help in a few months when they forget the details.)
So, some more detail about where this is in the code would be helpful here.
Quoted 3 lines
thus ROM will save a PA return address.
Later in the wakeup, when SMC driver calls an RPC throughomap4_secure_dispatcher(MMU is on now),
Again, pointer to where is this in the code would be helpful.
Also, it's not obvious why RPC use used here. Is that referring to the fact that the secure calls on CPU1 are dispatched to CPU0? Whatever it means, it should be summarized in the changelog.
Quoted 6 lines
ROM code won't log the new return
address as RPCs are handled different. Thus ROM will attempt to return to a PA address when the MMU is on and the system will hang.We need to do this for OSWR state and OFF state of mpu power domain, not just for device off(mpu pd OFF).
The code suggests that affects *all* OMAP4 revisions? Is that correct?
And once again, can this be implmented using cluster PM notifiers, where the notifier is registered only on affected revisions?
(Sheesh, the number of ROM code workaounds in this series is rather disconcerting.)
Kevin
PATCH v2 12/19 ARM: OMAP4: PM: update ROM return address for OSWR and OFF
Quoted 11 lines · Kevin Hilman
Quoted 4 lines · Tero Kristo
From: Carlos Leija <[email protected]>
At wakeup from OFF/OSWR CPU1 will call secure HAL service through a local secure dispatcher with MMU off,
Reviewers who are uninitaited in this level of detail need some more help here (even those who are deeply familiar will need more help in a few months when they forget the details.)
Quoted 8 lines
So, some more detail about where this is in the code would be helpful here.
Quoted 3 lines
thus ROM will save a PA return address.
Later in the wakeup, when SMC driver calls an RPC throughomap4_secure_dispatcher(MMU is on now),Again, pointer to where is this in the code would be helpful.
I believe this refers to any of the SMC calls done in the ASM files. Most notably the one in omap-headsmp.S, which is added (rather) illogically after this patch in the set though.
Quoted 4 lines
Also, it's not obvious why RPC use used here. Is that referring to the fact that the secure calls on CPU1 are dispatched to CPU0? Whatever it means, it should be summarized in the changelog.
Not sure about this, maybe security guys can comment on this.
Quoted 9 lines
Quoted 7 lines
ROM code won't log the new return
address as RPCs are handled different. Thus ROM will attempt to return to a PA address when the MMU is on and the system will hang.We need to do this for OSWR state and OFF state of mpu power domain, not just for device off(mpu pd OFF).
The code suggests that affects *all* OMAP4 revisions? Is that correct?
I think thats right.
Quoted 3 lines
And once again, can this be implmented using cluster PM notifiers, where the notifier is registered only on affected revisions?
Should be okay to do that. I guess this should move to omap-secure.c.
Quoted 7 lines
(Sheesh, the number of ROM code workaounds in this series is rather disconcerting.)
Kevin
PATCH v2 13/19 ARM: OMAP4: PM: Mark the PPI and SPI interrupts as non-secure for GP
In reply to Tero KristoFrom: Axel Haslam <[email protected]>
ROM code restores part of the GIC context during wakeup from device off mode from the SAR RAM. If the PPI and SPI interrupts are not marked as non-secure on GP chips, this crashes the device during wakeup, thus mark them as non-secure.
--- arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/omap-wakeupgen.c | 21 +++++++++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 5 +++++ arch/arm/mach-omap2/omap4-sar-layout.h | 3 +++ 4 files changed, 30 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/common.h +1 -0
@@ -200,6 +200,7 @@ static inline void __iomem *omap4_get_scu_base(void)extern void __init gic_init_irq (void );extern void gic_dist_disable (void ); +extern u32 gic_readl (u32 offset,u8 idx);extern void omap_smc1 (u32 fn,u32 arg);extern void __iomem *omap4_get_sar_ram_base (void );extern void omap_do_wfi (void );
arch/arm/mach-omap2/omap-wakeupgen.c +21 -0
@@ -41,6 +41,7 @@#define CPU_ENA_OFFSET 0x400#define CPU0_ID 0x0#define CPU1_ID 0x1 +#define GIC_ISR_NON_SECURE 0xffffffffstatic void __iomem *wakeupgen_base;static void __iomem *sar_base;
@@ -387,6 +388,7 @@ int __init omap_wakeupgen_init(void) {int i;unsigned int boot_cpu =smp_processor_id (); +int max_spi_reg;/* Not supported on OMAP4 ES1.0 silicon */ if (omap_rev () ==OMAP4430_REV_ES1_0 ) {
@@ -422,6 +424,25 @@ int __init omap_wakeupgen_init(void)for (i =0 ; i <NR_IRQS ; i++) irq_target_cpu[i] = boot_cpu; +/* +* Find out how many interrupts are supported. +* OMAP4 supports max of 128 SPIs where as GIC can support +* up to 1020 interrupt sources. On OMAP4, maximum SPIs are +* fused in DIST_CTR bit-fields as 128. Hence the code is safe +* from reserved register writes since its well within 1020. +*/ + max_spi_reg =gic_readl (GIC_DIST_CTR ,0 ) &0x1f ; + +if (omap_type () ==OMAP2_DEVICE_TYPE_GP ) { + sar_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU0_OFFSET ,0 ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU1_OFFSET ,0 ); +for (i =0 ; i < max_spi_reg; i++) +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i); +iounmap (sar_base); + sar_base =NULL ; + } +irq_hotplug_init ();irq_pm_init ();
arch/arm/mach-omap2/omap4-common.c +5 -0
@@ -112,6 +112,11 @@ void gic_dist_disable(void)__raw_writel (0x0 , gic_dist_base_addr +GIC_DIST_CTRL ); } +u32 gic_readl (u32 offset,u8 idx) +{ +return __raw_readl (gic_dist_base_addr + offset +4 * idx); +} +#ifdef CONFIG_CACHE_L2X0 void __iomem *omap4_get_l2cache_base (void )
arch/arm/mach-omap2/omap4-sar-layout.h +3 -0
@@ -85,6 +85,9 @@#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508) +#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c) +#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510) +#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514)/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
Signature · 1 line
1.7.4.1
PATCH v2 13/19 ARM: OMAP4: PM: Mark the PPI and SPI interrupts as non-secure for GP
Quoted 34 lines · Tero Kristo
From: Axel Haslam <[email protected]>
ROM code restores part of the GIC context during wakeup from device off mode from the SAR RAM. If the PPI and SPI interrupts are not marked as non-secure on GP chips, this crashes the device during wakeup, thus mark them as non-secure.
Signed-off-by Axel Haslam <[email protected]>[t-kristo at ti.com: fixed commit message, merged multiple patches to one]Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/omap-wakeupgen.c | 21 +++++++++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 5 +++++ arch/arm/mach-omap2/omap4-sar-layout.h | 3 +++ 4 files changed, 30 insertions(+), 0 deletions(-)arch/arm/mach-omap2/common.h +1
-0@@ -200,6 +200,7 @@ static inline void __iomem *omap4_get_scu_base(void)extern void __init gic_init_irq (void );extern void gic_dist_disable (void ); +extern u32 gic_readl (u32 offset,u8 idx);extern void omap_smc1 (u32 fn,u32 arg);extern void __iomem *omap4_get_sar_ram_base (void );extern void omap_do_wfi (void );arch/arm/mach-omap2/omap-wakeupgen.c +0
-0
arch/arm/mach-omap2/omap-wakeupgen.c line 44
Quoted 4 lines
arch/arm/mach-omap2/omap-wakeupgen.c +1
-0@@ -41,6 +41,7 @@#define CPU_ENA_OFFSET 0x400#define CPU0_ID 0x0#define CPU1_ID 0x1 +#define GIC_ISR_NON_SECURE 0xffffffff
nit: alignment with preceeding #defines
Quoted 19 lines
arch/arm/mach-omap2/omap-wakeupgen.c +6
-0static void __iomem *wakeupgen_base;static void __iomem *sar_base;@@ -387,6 +388,7 @@ int __init omap_wakeupgen_init(void) {int i;unsigned int boot_cpu =smp_processor_id (); +int max_spi_reg;/* Not supported on OMAP4 ES1.0 silicon */ if (omap_rev () ==OMAP4430_REV_ES1_0 ) {@@ -422,6 +424,25 @@ int __init omap_wakeupgen_init(void)for (i =0 ; i <NR_IRQS ; i++) irq_target_cpu[i] = boot_cpu; +/* +* Find out how many interrupts are supported. +* OMAP4 supports max of 128 SPIs where as GIC can support +* up to 1020 interrupt sources. On OMAP4, maximum SPIs are +* fused in DIST_CTR bit-fields as 128. Hence the code is safe
arch/arm/mach-omap2/omap-wakeupgen.c int __init omap_wakeupgen_init(void) · line 441
Quoted 10 lines
arch/arm/mach-omap2/omap-wakeupgen.c +10
-0+* from reserved register writes since its well within 1020. +*/ + max_spi_reg =gic_readl (GIC_DIST_CTR ,0 ) &0x1f ; + +if (omap_type () ==OMAP2_DEVICE_TYPE_GP ) { + sar_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU0_OFFSET ,0 ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU1_OFFSET ,0 ); +for (i =0 ; i < max_spi_reg; i++) +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i);
The above 4 lines are begging for some comments (something like the changelog). Since later in the series more stuff is added here, the end result has some readability problems.
Quoted 11 lines
arch/arm/mach-omap2/omap-wakeupgen.c +3
-0+iounmap (sar_base); + sar_base =NULL ; + }irq_hotplug_init ();irq_pm_init ();arch/arm/mach-omap2/omap4-common.c +0
-0
arch/arm/mach-omap2/omap4-common.c void gic_dist_disable(void) · line 116
Quoted 5 lines
arch/arm/mach-omap2/omap4-common.c +2
-0@@ -112,6 +112,11 @@ void gic_dist_disable(void)__raw_writel (0x0 , gic_dist_base_addr +GIC_DIST_CTRL ); } +u32 gic_readl (u32 offset,u8 idx) +{
probably want an 'if (gic_dist_base_addr)' like gic_dist_disable()
Quoted 11 lines
arch/arm/mach-omap2/omap4-common.c +3
-0+return __raw_readl (gic_dist_base_addr + offset +4 * idx); +} +#ifdef CONFIG_CACHE_L2X0 void __iomem *omap4_get_l2cache_base (void )arch/arm/mach-omap2/omap4-sar-layout.h +0
-0
arch/arm/mach-omap2/omap4-sar-layout.h line 90
Quoted 6 lines
arch/arm/mach-omap2/omap4-sar-layout.h +3
-0@@ -85,6 +85,9 @@#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508) +#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c) +#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510) +#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514)
SAR_ prefix?
arch/arm/mach-omap2/omap4-sar-layout.h line 93
Quoted 2 lines
arch/arm/mach-omap2/omap4-sar-layout.h +0
-0/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
Kevin
PATCH v2 13/19 ARM: OMAP4: PM: Mark the PPI and SPI interrupts as non-secure for GP
Quoted 34 lines · Kevin Hilman
Quoted 32 lines · Tero Kristo
From: Axel Haslam <[email protected]>
ROM code restores part of the GIC context during wakeup from device off mode from the SAR RAM. If the PPI and SPI interrupts are not marked as non-secure on GP chips, this crashes the device during wakeup, thus mark them as non-secure.
Signed-off-by Axel Haslam <[email protected]>[t-kristo at ti.com: fixed commit message, merged multiple patches to one]Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/common.h | 1 + arch/arm/mach-omap2/omap-wakeupgen.c | 21 +++++++++++++++++++++ arch/arm/mach-omap2/omap4-common.c | 5 +++++ arch/arm/mach-omap2/omap4-sar-layout.h | 3 +++ 4 files changed, 30 insertions(+), 0 deletions(-)arch/arm/mach-omap2/common.h +1
-0@@ -200,6 +200,7 @@ static inline void __iomem *omap4_get_scu_base(void)extern void __init gic_init_irq (void );extern void gic_dist_disable (void ); +extern u32 gic_readl (u32 offset,u8 idx);extern void omap_smc1 (u32 fn,u32 arg);extern void __iomem *omap4_get_sar_ram_base (void );extern void omap_do_wfi (void );arch/arm/mach-omap2/omap-wakeupgen.c +0
-1--- a/arch/arm/mach-omap2/omap-wakeupgen.c
Quoted 8 lines
arch/arm/mach-omap2/omap-wakeupgen.c line 44
Quoted 6 lines
+++
b/arch/arm/mach-omap2/omap-wakeupgen.carch/arm/mach-omap2/omap-wakeupgen.c +1
-0@@ -41,6 +41,7 @@#define CPU_ENA_OFFSET 0x400#define CPU0_ID 0x0#define CPU1_ID 0x1 +#define GIC_ISR_NON_SECURE 0xffffffffnit: alignment with preceeding #defines
Will fix that.
Quoted 26 lines
Quoted 26 lines
arch/arm/mach-omap2/omap-wakeupgen.c +12
-0static void __iomem *wakeupgen_base;static void __iomem *sar_base;@@ -387,6 +388,7 @@ int __init omap_wakeupgen_init(void) {int i;unsigned int boot_cpu =smp_processor_id (); +int max_spi_reg;/* Not supported on OMAP4 ES1.0 silicon */ if (omap_rev () ==OMAP4430_REV_ES1_0 ) {@@ -422,6 +424,25 @@ int __init omap_wakeupgen_init(void)for (i =0 ; i <NR_IRQS ; i++) irq_target_cpu[i] = boot_cpu; +/* +* Find out how many interrupts are supported. +* OMAP4 supports max of 128 SPIs where as GIC can support +* up to 1020 interrupt sources. On OMAP4, maximum SPIs are +* fused in DIST_CTR bit-fields as 128. Hence the code is safe +* from reserved register writes since its well within 1020. +*/ + max_spi_reg =gic_readl (GIC_DIST_CTR ,0 ) &0x1f ; + +if (omap_type () ==OMAP2_DEVICE_TYPE_GP ) { + sar_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K );
Quoted 8 lines
arch/arm/mach-omap2/omap-wakeupgen.c int __init omap_wakeupgen_init(void) · line 441
Quoted 4 lines
arch/arm/mach-omap2/omap-wakeupgen.c +4
-0+sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU0_OFFSET ,0 ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU1_OFFSET ,0 ); +for (i =0 ; i < max_spi_reg; i++) +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i);The above 4 lines are begging for some comments (something like the changelog). Since later in the series more stuff is added here, the end result has some readability problems.
Will add.
Quoted 15 lines
Quoted 15 lines
arch/arm/mach-omap2/omap-wakeupgen.c +3
-0+iounmap (sar_base); + sar_base =NULL ; + }irq_hotplug_init ();irq_pm_init ();arch/arm/mach-omap2/omap4-common.c +0
-0@@ -112,6 +112,11 @@ void gic_dist_disable(void)__raw_writel (0x0 , gic_dist_base_addr +GIC_DIST_CTRL ); }
Quoted 4 lines
arch/arm/mach-omap2/omap4-common.c void gic_dist_disable(void) · line 116
Quoted 2 lines
arch/arm/mach-omap2/omap4-common.c +2
-0+u32 gic_readl (u32 offset,u8 idx) +{probably want an 'if (
gic_dist_base_addr)' likegic_dist_disable()
Yea, will add that.
Quoted 6 lines
Quoted 6 lines
arch/arm/mach-omap2/omap4-common.c +3
-0+return __raw_readl (gic_dist_base_addr + offset +4 * idx); +} +#ifdef CONFIG_CACHE_L2X0
Quoted 14 lines
arch/arm/mach-omap2/omap4-sar-layout.h line 90
Quoted 12 lines
arch/arm/mach-omap2/omap4-common.c +0
-0void __iomem *omap4_get_l2cache_base (void )arch/arm/mach-omap2/omap4-sar-layout.h +3
-0@@ -85,6 +85,9 @@#define SAR_BACKUP_STATUS_OFFSET (SAR_BANK3_OFFSET + 0x500)#define SAR_SECURE_RAM_SIZE_OFFSET (SAR_BANK3_OFFSET + 0x504)#define SAR_SECRAM_SAVED_AT_OFFSET (SAR_BANK3_OFFSET + 0x508) +#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c) +#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510) +#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514)
SAR_prefix?
Will add that too.
-Tero
Quoted 5 lines
arch/arm/mach-omap2/omap4-sar-layout.h line 93
Quoted 3 lines
arch/arm/mach-omap2/omap4-sar-layout.h +0
-0/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)Kevin
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
In reply to Tero Kristosave_secure_all needs l3_main_3_ick and l4_secure_clkdm enabled, otherwise the secure ROM code will crash.
--- arch/arm/mach-omap2/omap-wakeupgen.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-wakeupgen.c +20 -0
@@ -29,10 +29,12 @@#include <mach/omap-wakeupgen.h> #include <mach/omap-secure.h> +#include <plat/omap_hwmod.h> #include "omap4-sar-layout.h" #include "common.h" #include "pm.h" +#include "clockdomain.h" #define NR_REG_BANKS 4#define MAX_IRQS 128
@@ -49,6 +51,8 @@ static DEFINE_SPINLOCK(wakeupgen_lock);static unsigned int irq_target_cpu[NR_IRQS ];static struct powerdomain *mpuss_pd; +static struct clockdomain *l4_secure_clkdm; +static struct omap_hwmod *l3_main_3_oh;/* * Static helper functions.
@@ -300,10 +304,18 @@ static void save_secure_ram(void)static void save_secure_all (void ) {u32 ret; + +omap_hwmod_enable (l3_main_3_oh); +clkdm_wakeup (l4_secure_clkdm); + ret =omap_secure_dispatcher (OMAP4_HAL_SAVEALL_INDEX ,FLAG_START_CRITICAL ,1 ,omap_secure_ram_mempool_base (),0 ,0 ,0 ); + +clkdm_allow_idle (l4_secure_clkdm); +omap_hwmod_idle (l3_main_3_oh); +if (ret !=API_HAL_RET_VALUE_OK )pr_err ("Secure all context save failed\n" ); }
@@ -441,6 +453,14 @@ int __init omap_wakeupgen_init(void)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i);iounmap (sar_base); sar_base =NULL ; + }else { + l3_main_3_oh =omap_hwmod_lookup ("l3_main_3" ); +if (!l3_main_3_oh) +pr_err ("%s: failed to get l3_main_3_oh\n" , __func__); + + l4_secure_clkdm =clkdm_lookup ("l4_secure_clkdm" ); +if (!l4_secure_clkdm) +pr_err ("%s: failed to get l4_secure_clkdm\n" , __func__); }irq_hotplug_init ();
Signature · 1 line
1.7.4.1
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
+Benoit
Quoted 4 lines · Tero Kristo
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Signed-off-by Tero Kristo <[email protected]>
I think I mentioned this already (I'm already lost in what I've said for thisseries), but I don't think the secure RAM stuff belongs in the wakeupgen driver.
Also, this patch suggests that the OCM RAM block needs a proper hwmod instead of manually fiddling with the l3_main_3 hwmod and the l4_secure clkdm.
Kevin
Quoted 64 lines
--- arch/arm/mach-omap2/omap-wakeupgen.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)arch/arm/mach-omap2/omap-wakeupgen.c +20
-0@@ -29,10 +29,12 @@#include <mach/omap-wakeupgen.h> #include <mach/omap-secure.h> +#include <plat/omap_hwmod.h> #include "omap4-sar-layout.h" #include "common.h" #include "pm.h" +#include "clockdomain.h" #define NR_REG_BANKS 4#define MAX_IRQS 128@@ -49,6 +51,8 @@ static DEFINE_SPINLOCK(wakeupgen_lock);static unsigned int irq_target_cpu[NR_IRQS ];static struct powerdomain *mpuss_pd; +static struct clockdomain *l4_secure_clkdm; +static struct omap_hwmod *l3_main_3_oh;/* * Static helper functions. @@ -300,10 +304,18 @@ static void save_secure_ram(void)static void save_secure_all (void ) {u32 ret; + +omap_hwmod_enable (l3_main_3_oh); +clkdm_wakeup (l4_secure_clkdm); + ret =omap_secure_dispatcher (OMAP4_HAL_SAVEALL_INDEX ,FLAG_START_CRITICAL ,1 ,omap_secure_ram_mempool_base (),0 ,0 ,0 ); + +clkdm_allow_idle (l4_secure_clkdm); +omap_hwmod_idle (l3_main_3_oh); +if (ret !=API_HAL_RET_VALUE_OK )pr_err ("Secure all context save failed\n" ); }@@ -441,6 +453,14 @@ int __init omap_wakeupgen_init(void)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i);iounmap (sar_base); sar_base =NULL ; + }else { + l3_main_3_oh =omap_hwmod_lookup ("l3_main_3" ); +if (!l3_main_3_oh) +pr_err ("%s: failed to get l3_main_3_oh\n" , __func__); + + l4_secure_clkdm =clkdm_lookup ("l4_secure_clkdm" ); +if (!l4_secure_clkdm) +pr_err ("%s: failed to get l4_secure_clkdm\n" , __func__); }irq_hotplug_init ();
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
Quoted 4 lines · Kevin Hilman
+Benoit
Tero Kristo <[email protected]> writes:
Quoted 8 lines
Quoted 4 lines
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Signed-off-by Tero Kristo <[email protected]>I think I mentioned this already (I'm already lost in what I've said for thisseries), but I don't think the secure RAM stuff belongs in the wakeupgen driver.
As mentioned, save_secure_all saves:
- secure RAM
- GIC registers
- some other mysterious stuff
Attempting to do separate saves for secure RAM + GIC hang the device during wakeup, in addition to being really inefficient (secure API calls are expensive.)
-Tero
Quoted 70 lines
Also, this patch suggests that the OCM RAM block needs a proper hwmod instead of manually fiddling with the
l3_main_3hwmod and thel4_secureclkdm.Kevin
Quoted 64 lines
--- arch/arm/mach-omap2/omap-wakeupgen.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-)arch/arm/mach-omap2/omap-wakeupgen.c +20
-0@@ -29,10 +29,12 @@#include <mach/omap-wakeupgen.h> #include <mach/omap-secure.h> +#include <plat/omap_hwmod.h> #include "omap4-sar-layout.h" #include "common.h" #include "pm.h" +#include "clockdomain.h" #define NR_REG_BANKS 4#define MAX_IRQS 128@@ -49,6 +51,8 @@ static DEFINE_SPINLOCK(wakeupgen_lock);static unsigned int irq_target_cpu[NR_IRQS ];static struct powerdomain *mpuss_pd; +static struct clockdomain *l4_secure_clkdm; +static struct omap_hwmod *l3_main_3_oh;/* * Static helper functions. @@ -300,10 +304,18 @@ static void save_secure_ram(void)static void save_secure_all (void ) {u32 ret; + +omap_hwmod_enable (l3_main_3_oh); +clkdm_wakeup (l4_secure_clkdm); + ret =omap_secure_dispatcher (OMAP4_HAL_SAVEALL_INDEX ,FLAG_START_CRITICAL ,1 ,omap_secure_ram_mempool_base (),0 ,0 ,0 ); + +clkdm_allow_idle (l4_secure_clkdm); +omap_hwmod_idle (l3_main_3_oh); +if (ret !=API_HAL_RET_VALUE_OK )pr_err ("Secure all context save failed\n" ); }@@ -441,6 +453,14 @@ int __init omap_wakeupgen_init(void)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i);iounmap (sar_base); sar_base =NULL ; + }else { + l3_main_3_oh =omap_hwmod_lookup ("l3_main_3" ); +if (!l3_main_3_oh) +pr_err ("%s: failed to get l3_main_3_oh\n" , __func__); + + l4_secure_clkdm =clkdm_lookup ("l4_secure_clkdm" ); +if (!l4_secure_clkdm) +pr_err ("%s: failed to get l4_secure_clkdm\n" , __func__); }irq_hotplug_init ();
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
Quoted 10 lines · Tero Kristo
Quoted 9 lines · Kevin Hilman
+Benoit
Quoted 4 lines · Tero Kristo
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Signed-off-by Tero Kristo <[email protected]>
Quoted 8 lines
Quoted 3 lines
I think I mentioned this already (I'm already lost in what I've said for thisseries), but I don't think the secure RAM stuff belongs in the wakeupgen driver.
As mentioned,
save_secure_allsaves:
- secure RAM
- GIC registers
- some other mysterious stuff
(mysterious: Entire firewall registers )
Regards
Santosh
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
In reply to Tero KristoQuoted 14 lines · Tero Kristo
Quoted 4 lines · Kevin Hilman
+Benoit
Tero Kristo <[email protected]> writes:
Quoted 8 lines
Quoted 4 lines
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Signed-off-by Tero Kristo <[email protected]>I think I mentioned this already (I'm already lost in what I've said for thisseries), but I don't think the secure RAM stuff belongs in the wakeupgen driver.
Quoted 8 lines
As mentioned,
save_secure_allsaves:
- secure RAM
- GIC registers
- some other mysterious stuffAttempting to do separate saves for secure RAM + GIC hang the device during wakeup, in addition to being really inefficient (secure API calls are expensive.)
I guess my comment wasn't that this isn't needed, but that it doesn't seem to belong in the wakeupgen base (which should probably converted into a real driver.)
Seems better to have this stuff in the secure code, maybe omap-secure.c?
Kevin
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
Quoted 25 lines · Kevin Hilman
Quoted 14 lines · Tero Kristo
Quoted 4 lines · Kevin Hilman
+Benoit
Tero Kristo <[email protected]> writes:
Quoted 8 lines
Quoted 4 lines
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Signed-off-by Tero Kristo <[email protected]>I think I mentioned this already (I'm already lost in what I've said for thisseries), but I don't think the secure RAM stuff belongs in the wakeupgen driver.
Quoted 8 lines
As mentioned,
save_secure_allsaves:
- secure RAM
- GIC registers
- some other mysterious stuffAttempting to do separate saves for secure RAM + GIC hang the device during wakeup, in addition to being really inefficient (secure API calls are expensive.)
Quoted 6 lines
I guess my comment wasn't that this isn't needed, but that it doesn't seem to belong in the wakeupgen base (which should probably converted into a real driver.)
Seems better to have this stuff in the secure code, maybe
omap-secure.c?
Perhaps OFF mode notifier might help best here. In addition - it might be safer to protect all calls with clkdm_wakeup around secure_dispatcher instead of just the save_secure_all.. ROM code is not smart enough around it.
an completely safe version used by security driver can be found here:
http://git.omapzoom.org/?p=kernel/omap.git;a=blob;f=security/smc/tf_comm_mshield.c;h=b5279fef0fa400438a57b3941af13d965e983bf0;hb=p-android-omap-3.0#l253
this is what the production kernels have used in the past. Regards,
Nishanth Menon
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
Quoted 33 lines · Nishanth
Quoted 25 lines · Kevin Hilman
Quoted 14 lines · Tero Kristo
Quoted 4 lines · Kevin Hilman
+Benoit
Tero Kristo <[email protected]> writes:
Quoted 8 lines
Quoted 4 lines
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Signed-off-by Tero Kristo <[email protected]>I think I mentioned this already (I'm already lost in what I've said for thisseries), but I don't think the secure RAM stuff belongs in the wakeupgen driver.
Quoted 8 lines
As mentioned,
save_secure_allsaves:
- secure RAM
- GIC registers
- some other mysterious stuffAttempting to do separate saves for secure RAM + GIC hang the device during wakeup, in addition to being really inefficient (secure API calls are expensive.)
Quoted 6 lines
I guess my comment wasn't that this isn't needed, but that it doesn't seem to belong in the wakeupgen base (which should probably converted into a real driver.)
Seems better to have this stuff in the secure code, maybe
omap-secure.c?
Quoted 7 lines
Perhaps OFF mode notifier might help best here. In addition - it might be safer to protect all calls with
clkdm_wakeuparoundsecure_dispatcherinstead of just thesave_secure_all.. ROM code is not smart enough around it.
an completely safe version used by security driver can be found here:
http://git.omapzoom.org/?p=kernel/omap.git;a=blob;f=security/smc/tf_comm_mshield.c;h=b5279fef0fa400438a57b3941af13d965e983bf0;hb=p-android-omap-3.0#l253
Thats true... the secure driver in mainline kernel is rather a stub. Previous version of this patch actually had clkdm_wakeup around every call to dispatcher, I just optimized it away. I can add it back in the next version if you think that is better.
-Tero
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
In reply to Kevin HilmanQuoted 25 lines · Kevin Hilman
Quoted 14 lines · Tero Kristo
Quoted 4 lines · Kevin Hilman
+Benoit
Tero Kristo <[email protected]> writes:
Quoted 8 lines
Quoted 4 lines
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Signed-off-by Tero Kristo <[email protected]>I think I mentioned this already (I'm already lost in what I've said for thisseries), but I don't think the secure RAM stuff belongs in the wakeupgen driver.
Quoted 8 lines
As mentioned,
save_secure_allsaves:
- secure RAM
- GIC registers
- some other mysterious stuffAttempting to do separate saves for secure RAM + GIC hang the device during wakeup, in addition to being really inefficient (secure API calls are expensive.)
Quoted 5 lines
I guess my comment wasn't that this isn't needed, but that it doesn't seem to belong in the wakeupgen base (which should probably converted into a real driver.)
Seems better to have this stuff in the secure code, maybe
omap-secure.c?
That might be an option yes. I'll see if I can move these calls over there.
-Tero
Paul Walmsley
maintainerPATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
In reply to Tero KristoHi Tero
Quoted 2 lines · Tero Kristo
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.
Do we know why the l3_main_3 interconnect has to be enabled? Is this needed to access some L3 or instrumentation registers?
- Paul
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
Quoted 9 lines · Paul Walmsley
Hi Tero
Quoted 2 lines · Tero Kristo
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Do we know why the
l3_main_3interconnect has to be enabled? Is this needed to access some L3 or instrumentation registers?
Not sure, ROM code is doing something here which requires it, and the ROM code definitely crashes without this. Your guess sounds plausible.
-Tero
PATCH v2 14/19 ARM: OMAP4: wakeupgen: enable clocks for save_secure_all
Quoted 5 lines · Tero Kristo
Quoted 4 lines · Paul Walmsley
Hi Tero
On Mon, 14 May 2012, Tero Kristo wrote:
Quoted 9 lines
Quoted 5 lines
Quoted 2 lines
save_secure_allneedsl3_main_3_ickandl4_secure_clkdmenabled, otherwise the secure ROM code will crash.Do we know why the
l3_main_3interconnect has to be enabled? ?Is this needed to access some L3 or instrumentation registers?Not sure, ROM code is doing something here which requires it, and the ROM code definitely crashes without this. Your guess sounds plausible.
ROM code accesses L3 firewall registers mostly apart from L2 INSTR firewall registers here and without that clock, those accesses will abort.
Regards
santosh
PATCH v2 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
In reply to Tero KristoFrom: Santosh Shilimkar <[email protected]>
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when EMIF_SDRAM_CONFIG is restored first before EMIF_SDRAM_CONFIG_2 is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.
--- .../include/mach/ctrl_module_wkup_44xx.h | 2 + arch/arm/mach-omap2/pm44xx.c | 37 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2 -0
@@ -28,6 +28,8 @@#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG 0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG 0x011c#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468
arch/arm/mach-omap2/pm44xx.c +37 -0
@@ -17,12 +17,18 @@#include <linux/err.h> #include <linux/slab.h> #include <asm/system_misc.h> +#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> +#include <mach/hardware.h> #include "common.h" #include "clockdomain.h" #include "powerdomain.h" #include "pm.h" +#define EMIF_SDRAM_CONFIG2_OFFSET 0xc +struct power_state {struct powerdomain *pwrdm;u32 next_state;
@@ -215,6 +221,37 @@ static int __init omap4_pm_init(void)pr_err ("Power Management for TI OMAP4.\n" ); +/* +* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF +* Mode Transition When CS1 Is Used On EMIF": +* Overwrite EMIF1/EMIF2 +* SECURE_EMIF1_SDRAM_CONFIG2_REG +* SECURE_EMIF2_SDRAM_CONFIG2_REG +*/ +if (cpu_is_omap443x ()) { +void __iomem *secure_ctrl_mod; +void __iomem *emif1; +void __iomem *emif2; +u32 val; + + secure_ctrl_mod =ioremap (OMAP4_CTRL_MODULE_WKUP ,SZ_4K ); + emif1 =ioremap (OMAP44XX_EMIF1_BASE ,SZ_1M ); + emif2 =ioremap (OMAP44XX_EMIF2_BASE ,SZ_1M ); + +BUG_ON (!secure_ctrl_mod || !emif1 || !emif2); + + val =__raw_readl (emif1 +EMIF_SDRAM_CONFIG2_OFFSET ); +__raw_writel (val, secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ); + val =__raw_readl (emif2 +EMIF_SDRAM_CONFIG2_OFFSET ); +__raw_writel (val, secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ); +wmb (); +iounmap (secure_ctrl_mod); +iounmap (emif1); +iounmap (emif2); + } + ret =pwrdm_for_each (pwrdms_setup,NULL );if (ret) {pr_err ("Failed to setup powerdomains\n" );
Signature · 1 line
1.7.4.1
PATCH v2 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
Quoted 8 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.
Please summarize the workaround here as well.
Quoted 46 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>--- .../include/mach/ctrl_module_wkup_44xx.h | 2 + arch/arm/mach-omap2/pm44xx.c | 37 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0@@ -28,6 +28,8 @@#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010 +#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG 0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG 0x011c#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468arch/arm/mach-omap2/pm44xx.c +6
-0@@ -17,12 +17,18 @@#include <linux/err.h> #include <linux/slab.h> #include <asm/system_misc.h> +#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> +#include <mach/hardware.h> #include "common.h" #include "clockdomain.h" #include "powerdomain.h" #include "pm.h" +#define EMIF_SDRAM_CONFIG2_OFFSET 0xc +struct power_state {struct powerdomain *pwrdm;u32 next_state;@@ -215,6 +221,37 @@ static int __init omap4_pm_init(void)
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 231
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +8
-0pr_err ("Power Management for TI OMAP4.\n" ); +/* +* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF +* Mode Transition When CS1 Is Used On EMIF": +* Overwrite EMIF1/EMIF2 +* SECURE_EMIF1_SDRAM_CONFIG2_REG +* SECURE_EMIF2_SDRAM_CONFIG2_REG +*/ +if (cpu_is_omap443x ()) {
This should probably be done later in this function, after PM_ERRATUM flags are setup, and then it should use a PM_ERRATUM flag instead of cpu_is*
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 241
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+void __iomem *secure_ctrl_mod; +void __iomem *emif1; +void __iomem *emif2; +u32 val; + + secure_ctrl_mod =ioremap (OMAP4_CTRL_MODULE_WKUP ,SZ_4K ); + emif1 =ioremap (OMAP44XX_EMIF1_BASE ,SZ_1M ); + emif2 =ioremap (OMAP44XX_EMIF2_BASE ,SZ_1M ); + +BUG_ON (!secure_ctrl_mod || !emif1 || !emif2);
Please avoid BUG_ON() and use proper error recovery. This is not a condition where the entire kernel should panic.
Quoted 5 lines
arch/arm/mach-omap2/pm44xx.c +5
-0+ val =__raw_readl (emif1 +EMIF_SDRAM_CONFIG2_OFFSET ); +__raw_writel (val, secure_ctrl_mod + +OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ); + val =__raw_readl (emif2 +EMIF_SDRAM_CONFIG2_OFFSET ); + __raw_writel(val, secure_ctrl_mod +
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 257
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +6
-0+ OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG); +wmb (); +iounmap (secure_ctrl_mod); +iounmap (emif1); +iounmap (emif2); + } ret =pwrdm_for_each (pwrdms_setup,NULL );if (ret) {pr_err ("Failed to setup powerdomains\n" );
Kevin
PATCH v2 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
Quoted 4 lines · Kevin Hilman
Quoted 2 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Quoted 9 lines
Quoted 6 lines
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.Please summarize the workaround here as well.
ok
Quoted 48 lines
Quoted 48 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>---
?.../include/mach/ctrl_module_wkup_44xx.h ? ? ? ? ? | ? ?2 + ?arch/arm/mach-omap2/pm44xx.c ? ? ? ? ? ? ? ? ? ? ? | ? 37 ++++++++++++++++++++ ?2 files changed, 39 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +0
-0@@ -28,6 +28,8 @@?#define
OMAP4_CTRL_MODULE_WKUP_IP_REVISION? ? ? ? ?0x0000?#defineOMAP4_CTRL_MODULE_WKUP_IP_HWINFO? ? ? ? ? ?0x0004?#defineOMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG? ? ? ? ?0x0010arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0+#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ? ?0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ? ?0x011c?#define
OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0?0x0460 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1?0x0464 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2?0x0468arch/arm/mach-omap2/pm44xx.c +0
-0@@ -17,12 +17,18 @@?#include <
linux/err.h>
?#include <linux/slab.h>
?#include <asm/system_misc.h>arch/arm/mach-omap2/pm44xx.c +4
-0+#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> +#include <mach/hardware.h> ?#include "
common.h"
?#include "clockdomain.h"
?#include "powerdomain.h"
?#include "pm.h"arch/arm/mach-omap2/pm44xx.c +2
-0+#define EMIF_SDRAM_CONFIG2_OFFSET ? ?0xc +?struct
power_state{
? ? ? struct powerdomain *pwrdm;
? ? ? u32next_state;arch/arm/mach-omap2/pm44xx.c +0
-0@@ -215,6 +221,37 @@ static int __init omap4_pm_init(void) ? ? ? pr_err("Power Management for TI OMAP4.\n");
Quoted 12 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 231
Quoted 8 lines
arch/arm/mach-omap2/pm44xx.c +8
-0+ ? ? /* + ? ? ?* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF + ? ? ?* Mode Transition When CS1 Is Used On EMIF": + ? ? ?* Overwrite EMIF1/EMIF2 + ? ? ?* SECURE_EMIF1_SDRAM_CONFIG2_REG + ? ? ?* SECURE_EMIF2_SDRAM_CONFIG2_REG + ? ? ?*/ + ? ? if (cpu_is_omap443x()) {This should probably be done later in this function, after
PM_ERRATUMflags are setup, and then it should use aPM_ERRATUMflag instead of cpu_is*
ok
Quoted 5 lines
Quoted 5 lines
arch/arm/mach-omap2/pm44xx.c +5
-0+ ? ? ? ? ? ? void __iomem *secure_ctrl_mod; + ? ? ? ? ? ? void __iomem *emif1; + ? ? ? ? ? ? void __iomem *emif2; + ? ? ? ? ? ? u32 val; +
Quoted 9 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 241
Quoted 5 lines
arch/arm/mach-omap2/pm44xx.c +5
-0+ ? ? ? ? ? ? secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K); + ? ? ? ? ? ? emif1 = ioremap(OMAP44XX_EMIF1_BASE, SZ_1M); + ? ? ? ? ? ? emif2 = ioremap(OMAP44XX_EMIF2_BASE, SZ_1M); + + ? ? ? ? ? ? BUG_ON(!secure_ctrl_mod || !emif1 || !emif2);Please avoid
BUG_ON()and use proper error recovery. ?This is not a condition where the entire kernel should panic.
Agree. WARN_ON() should suffice.
Regards
santosh
PATCH v2 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
Quoted 91 lines · Santosh
Quoted 4 lines · Kevin Hilman
Quoted 2 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Quoted 9 lines
Quoted 6 lines
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.Please summarize the workaround here as well.
ok
Quoted 48 lines
Quoted 48 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>---
?.../include/mach/ctrl_module_wkup_44xx.h ? ? ? ? ? | ? ?2 + ?arch/arm/mach-omap2/pm44xx.c ? ? ? ? ? ? ? ? ? ? ? | ? 37 ++++++++++++++++++++ ?2 files changed, 39 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +0
-0@@ -28,6 +28,8 @@?#define
OMAP4_CTRL_MODULE_WKUP_IP_REVISION? ? ? ? ?0x0000?#defineOMAP4_CTRL_MODULE_WKUP_IP_HWINFO? ? ? ? ? ?0x0004?#defineOMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG? ? ? ? ?0x0010arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0+#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ? ?0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ? ?0x011c?#define
OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0?0x0460 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1?0x0464 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2?0x0468arch/arm/mach-omap2/pm44xx.c +0
-0@@ -17,12 +17,18 @@?#include <
linux/err.h>
?#include <linux/slab.h>
?#include <asm/system_misc.h>arch/arm/mach-omap2/pm44xx.c +4
-0+#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> +#include <mach/hardware.h> ?#include "
common.h"
?#include "clockdomain.h"
?#include "powerdomain.h"
?#include "pm.h"arch/arm/mach-omap2/pm44xx.c +2
-0+#define EMIF_SDRAM_CONFIG2_OFFSET ? ?0xc +?struct
power_state{
? ? ? struct powerdomain *pwrdm;
? ? ? u32next_state;arch/arm/mach-omap2/pm44xx.c +0
-0@@ -215,6 +221,37 @@ static int __init omap4_pm_init(void) ? ? ? pr_err("Power Management for TI OMAP4.\n");Quoted 12 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 231
Quoted 8 lines
arch/arm/mach-omap2/pm44xx.c +8
-0+ ? ? /* + ? ? ?* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF + ? ? ?* Mode Transition When CS1 Is Used On EMIF": + ? ? ?* Overwrite EMIF1/EMIF2 + ? ? ?* SECURE_EMIF1_SDRAM_CONFIG2_REG + ? ? ?* SECURE_EMIF2_SDRAM_CONFIG2_REG + ? ? ?*/ + ? ? if (cpu_is_omap443x()) {This should probably be done later in this function, after
PM_ERRATUMflags are setup, and then it should use aPM_ERRATUMflag instead of cpu_is*ok
Quoted 5 lines
Quoted 5 lines
arch/arm/mach-omap2/pm44xx.c +5
-0+ ? ? ? ? ? ? void __iomem *secure_ctrl_mod; + ? ? ? ? ? ? void __iomem *emif1; + ? ? ? ? ? ? void __iomem *emif2; + ? ? ? ? ? ? u32 val; +Quoted 9 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 241
Quoted 5 lines
arch/arm/mach-omap2/pm44xx.c +5
-0+ ? ? ? ? ? ? secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K); + ? ? ? ? ? ? emif1 = ioremap(OMAP44XX_EMIF1_BASE, SZ_1M); + ? ? ? ? ? ? emif2 = ioremap(OMAP44XX_EMIF2_BASE, SZ_1M); + + ? ? ? ? ? ? BUG_ON(!secure_ctrl_mod || !emif1 || !emif2);Please avoid
BUG_ON()and use proper error recovery. ?This is not a condition where the entire kernel should panic.
Quoted 1 line
Agree.
WARN_ON()should suffice.
A WARN_ON() is ok (but noisy). Better is a pr_warn() with some proper error recovery.
Kevin
PATCH v2 15/19 ARM: OMAP4430: PM: workaround for DDR corruption on second CS
Quoted 93 lines · Kevin Hilman
Quoted 91 lines · Santosh
Quoted 4 lines · Kevin Hilman
Quoted 2 lines · Tero Kristo
From: Santosh Shilimkar <[email protected]>
Quoted 9 lines
Quoted 6 lines
Work around for Errata ID: i632 "LPDDR2 Corruption After OFF Mode Transition When CS1 Is Used On EMIF" which impacts OMAP443x silicon The issue occurs when
EMIF_SDRAM_CONFIGis restored first beforeEMIF_SDRAM_CONFIG_2is not yet restored, the register configuration is not set properly, we apply the required workaround allowing the restore sequence to work properly.Please summarize the workaround here as well.
ok
Quoted 48 lines
Quoted 48 lines
Signed-off-by Santosh Shilimkar <[email protected]>[t-kristo at ti.com: moved workaround from omap-sar.c to pm44xx.c]Signed-off-by Tero Kristo <[email protected]>---
?.../include/mach/ctrl_module_wkup_44xx.h ? ? ? ? ? | ? ?2 + ?arch/arm/mach-omap2/pm44xx.c ? ? ? ? ? ? ? ? ? ? ? | ? 37 ++++++++++++++++++++ ?2 files changed, 39 insertions(+), 0 deletions(-)arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +0
-0@@ -28,6 +28,8 @@?#define
OMAP4_CTRL_MODULE_WKUP_IP_REVISION? ? ? ? ?0x0000?#defineOMAP4_CTRL_MODULE_WKUP_IP_HWINFO? ? ? ? ? ?0x0004?#defineOMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG? ? ? ? ?0x0010arch/arm/mach-omap2/include/mach/ctrl_module_wkup_44xx.h +2
-0+#define OMAP4_CTRL_SECURE_EMIF1_SDRAM_CONFIG2_REG ? ?0x0114 +#define OMAP4_CTRL_SECURE_EMIF2_SDRAM_CONFIG2_REG ? ?0x011c?#define
OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0?0x0460 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1?0x0464 ?#defineOMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2?0x0468arch/arm/mach-omap2/pm44xx.c +0
-0@@ -17,12 +17,18 @@?#include <
linux/err.h>
?#include <linux/slab.h>
?#include <asm/system_misc.h>arch/arm/mach-omap2/pm44xx.c +4
-0+#include <linux/io.h> + +#include <mach/ctrl_module_wkup_44xx.h> +#include <mach/hardware.h> ?#include "
common.h"
?#include "clockdomain.h"
?#include "powerdomain.h"
?#include "pm.h"arch/arm/mach-omap2/pm44xx.c +2
-0+#define EMIF_SDRAM_CONFIG2_OFFSET ? ?0xc +?struct
power_state{
? ? ? struct powerdomain *pwrdm;
? ? ? u32next_state;arch/arm/mach-omap2/pm44xx.c +0
-0@@ -215,6 +221,37 @@ static int __init omap4_pm_init(void) ? ? ? pr_err("Power Management for TI OMAP4.\n");Quoted 12 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 231
Quoted 8 lines
arch/arm/mach-omap2/pm44xx.c +8
-0+ ? ? /* + ? ? ?* Work around for OMAP443x Errata i632: "LPDDR2 Corruption After OFF + ? ? ?* Mode Transition When CS1 Is Used On EMIF": + ? ? ?* Overwrite EMIF1/EMIF2 + ? ? ?* SECURE_EMIF1_SDRAM_CONFIG2_REG + ? ? ?* SECURE_EMIF2_SDRAM_CONFIG2_REG + ? ? ?*/ + ? ? if (cpu_is_omap443x()) {This should probably be done later in this function, after
PM_ERRATUMflags are setup, and then it should use aPM_ERRATUMflag instead of cpu_is*ok
Quoted 14 lines
arch/arm/mach-omap2/pm44xx.c static int __init omap4_pm_init(void) · line 241
Quoted 10 lines
arch/arm/mach-omap2/pm44xx.c +10
-0+ ? ? ? ? ? ? void __iomem *secure_ctrl_mod; + ? ? ? ? ? ? void __iomem *emif1; + ? ? ? ? ? ? void __iomem *emif2; + ? ? ? ? ? ? u32 val; + + ? ? ? ? ? ? secure_ctrl_mod = ioremap(OMAP4_CTRL_MODULE_WKUP, SZ_4K); + ? ? ? ? ? ? emif1 = ioremap(OMAP44XX_EMIF1_BASE, SZ_1M); + ? ? ? ? ? ? emif2 = ioremap(OMAP44XX_EMIF2_BASE, SZ_1M); + + ? ? ? ? ? ? BUG_ON(!secure_ctrl_mod || !emif1 || !emif2);Please avoid
BUG_ON()and use proper error recovery. ?This is not a condition where the entire kernel should panic.
Quoted 5 lines
Quoted 1 line
Agree.
WARN_ON()should suffice.A
WARN_ON()is ok (but noisy). ?Better is apr_warn()with some proper error recovery.
OK
PATCH v2 16/19 TEMP: ARM: OMAP4: prevent voltage transitions
In reply to Tero KristoDuring device off, the off-mode voltage transitions are enabled on reset. Because the voltage control logic is not still completely functional for OMAP4, we must disable the voltage transitions for device off for now. This can only be done by disabling the I2C channel it seems.
This patch does not prevent voltage scaling done by voltdm->scale / DVFS.
--- arch/arm/mach-omap2/pm44xx.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm44xx.c +22 -0
@@ -26,6 +26,9 @@#include "clockdomain.h" #include "powerdomain.h" #include "pm.h" +#include "voltage.h" +#include "prm44xx.h" +#include "prm-regbits-44xx.h" #define EMIF_SDRAM_CONFIG2_OFFSET 0xc
@@ -210,6 +213,7 @@ static int __init omap4_pm_init(void)int ret;struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm, *l4wkup;struct clockdomain *ducati_clkdm, *l3_2_clkdm, *l4_per_clkdm; +struct voltagedomain *mpu_voltdm;if (!cpu_is_omap44xx ())return -ENODEV ;
@@ -292,6 +296,24 @@ static int __init omap4_pm_init(void) goto err2; } +/* +* XXX: voltage config is not still completely valid for +* OMAP4, and this causes crashes on some platform during +* device off because voltage transitions for device off +* are enabled on reset. Thus, we have to disable the I2C +* channel completely in the VOLTCTRL register to avoid +* trouble. Remove this once voltconfigs are valid. +*/ + mpu_voltdm =voltdm_lookup ("mpu" ); +if (!mpu_voltdm) { +pr_err ("Failed to get MPU voltdm\n" ); + goto err2; + } + mpu_voltdm->write (OMAP4430_VDD_MPU_I2C_DISABLE_MASK | +OMAP4430_VDD_CORE_I2C_DISABLE_MASK | +OMAP4430_VDD_IVA_I2C_DISABLE_MASK , +OMAP4_PRM_VOLTCTRL_OFFSET ); + ret =omap4_mpuss_init ();if (ret) {pr_err ("Failed to initialise OMAP4 MPUSS\n" );
Signature · 1 line
1.7.4.1
PATCH v2 17/19 ARM: OMAP4: put cpu1 back to sleep if no wake request
In reply to Tero KristoIf AUX_CORE_BOOT0 does not indicate wakeup request for cpu1, put it back to off. This is needed during wakeup from device off to prevent cpu1 from being stuck indefinitely in the wakeup loop and also to prevent wakeup problem on GP chips with device off mode.
--- arch/arm/mach-omap2/omap-headsmp.S | 45 ++++++++++++++++++++++++++++++++--- 1 files changed, 41 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/omap-headsmp.S +41 -4
@@ -17,8 +17,37 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <mach/omap-secure.h> +#include "prcm_mpu44xx.h" + +#define CPU1_PWRSTCTRL (OMAP4430_PRCM_MPU_BASE + OMAP4430_PRCM_MPU_CPU1_INST + \ + OMAP4_PM_CPU1_PWRSTCTRL_OFFSET) __CPUINIT + +ENTRY(omap_cpu1_off) + ldr r12, =CPU1_PWRSTCTRL + ldr r0, [r12] + and r0, #3 + cmp r0, #2 + beq exit_cpu1_off + + mov r0, #0x3 + mov r1, #0x0 + ldr r12, =OMAP4_MON_SCU_PWR_INDEX + dsb + smc #0 + + isb + dsb + dmb + wfi + nop + nop +exit_cpu1_off: + mov pc, lr +ENDPROC(omap_cpu1_off) + /* * OMAP4 specific entry point for secondary CPU to jump from ROM * code. This routine also provides a holding flag into which
@@ -27,32 +56,40 @@ * register AuxCoreBoot0. */ ENTRY(omap_secondary_startup) -hold: ldr r12,=0x103 + ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 mov r0, r0, lsr #9 mrc p15, 0, r4, c0, c0, 5 and r4, r4, #0x0f cmp r0, r4 - bne hold + beq omap_cont_boot + + bl omap_cpu1_off + b omap_secondary_startup /* * we've been released from the wait loop,secondary_stack * should now contain the SVC stack for this core */ +omap_cont_boot: b secondary_startup ENDPROC(omap_secondary_startup) ENTRY(omap_secondary_startup_4460) -hold_2: ldr r12,=0x103 + ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 mov r0, r0, lsr #9 mrc p15, 0, r4, c0, c0, 5 and r4, r4, #0x0f cmp r0, r4 - bne hold_2 + beq omap4460_cont_boot + + bl omap_cpu1_off + b omap_secondary_startup_4460 +omap4460_cont_boot: /* * GIC distributor control register has changed between * CortexA9 r1pX and r2pX. The Control Register secure
Signature · 1 line
1.7.4.1
PATCH v2 17/19 ARM: OMAP4: put cpu1 back to sleep if no wake request
Quoted 2 lines · Tero Kristo
If
AUX_CORE_BOOT0does not indicate wakeup request for cpu1, put it back to off.
Why is it waking up then? (I know the answer, but will forget. The changelog serves as my long-term memory.)
Quoted 2 lines
This is needed during wakeup from device off to prevent cpu1 from being stuck indefinitely in the wakeup loop
Why does it get stuck?
Quoted 1 line
and also to prevent wakeup problem on GP chips with device off mode.
What wakeup problem?
Quoted 1 line
Signed-off-by Tero Kristo <[email protected]>
Assembly code should have some comments to aid comprehension.
Quoted 20 lines
--- arch/arm/mach-omap2/omap-headsmp.S | 45 ++++++++++++++++++++++++++++++++--- 1 files changed, 41 insertions(+), 4 deletions(-)arch/arm/mach-omap2/omap-headsmp.S +6
-0@@ -17,8 +17,37 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <mach/omap-secure.h> +#include "prcm_mpu44xx.h" + +#define CPU1_PWRSTCTRL (OMAP4430_PRCM_MPU_BASE + OMAP4430_PRCM_MPU_CPU1_INST + \ + OMAP4_PM_CPU1_PWRSTCTRL_OFFSET) __CPUINIT +
arch/arm/mach-omap2/omap-headsmp.S line 37
Quoted 10 lines
arch/arm/mach-omap2/omap-headsmp.S +10
-0+ENTRY(omap_cpu1_off) + ldr r12, =CPU1_PWRSTCTRL + ldr r0, [r12] + and r0, #3 + cmp r0, #2 + beq exit_cpu1_off + + mov r0, #0x3 + mov r1, #0x0 + ldr r12, =OMAP4_MON_SCU_PWR_INDEX
Help! no comments.
arch/arm/mach-omap2/omap-headsmp.S line 39
Quoted 2 lines
arch/arm/mach-omap2/omap-headsmp.S +2
-0+ dsb + smc #0
The DO_SMC in sleep44xx.S suggests there should be another dsb here.
arch/arm/mach-omap2/omap-headsmp.S line 46
Quoted 6 lines
arch/arm/mach-omap2/omap-headsmp.S +6
-0+ isb + dsb + dmb + wfi + nop + nop
Shoudln't this use omap_do_wfi?
Kevin
Quoted 52 lines
arch/arm/mach-omap2/omap-headsmp.S +16
-4+exit_cpu1_off: + mov pc, lr +ENDPROC(omap_cpu1_off) + /* * OMAP4 specific entry point for secondary CPU to jump from ROM * code. This routine also provides a holding flag into which@@ -27,32 +56,40 @@ * register AuxCoreBoot0. */ ENTRY(omap_secondary_startup) -hold: ldr r12,=0x103 + ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 mov r0, r0, lsr #9 mrc p15, 0, r4, c0, c0, 5 and r4, r4, #0x0f cmp r0, r4 - bne hold + beq omap_cont_boot + + bl omap_cpu1_off + b omap_secondary_startup /* * we've been released from the wait loop,secondary_stack * should now contain the SVC stack for this core */ +omap_cont_boot: b secondary_startup ENDPROC(omap_secondary_startup) ENTRY(omap_secondary_startup_4460) -hold_2: ldr r12,=0x103 + ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 mov r0, r0, lsr #9 mrc p15, 0, r4, c0, c0, 5 and r4, r4, #0x0f cmp r0, r4 - bne hold_2 + beq omap4460_cont_boot + + bl omap_cpu1_off + b omap_secondary_startup_4460 +omap4460_cont_boot: /* * GIC distributor control register has changed between * CortexA9 r1pX and r2pX. The Control Register secure
PATCH v2 17/19 ARM: OMAP4: put cpu1 back to sleep if no wake request
Quoted 7 lines · Kevin Hilman
Quoted 2 lines · Tero Kristo
If
AUX_CORE_BOOT0does not indicate wakeup request for cpu1, put it back to off.Why is it waking up then? (I know the answer, but will forget. The changelog serves as my long-term memory.)
Will add comment. (Both cpus will wake-up after device-off reset.)
Quoted 5 lines
Quoted 3 lines
This is needed during wakeup from device off to prevent cpu1 from being stuck indefinitely in the wakeup loop
Why does it get stuck?
Related to the above, if the AUX_CORE_BOOT0 is not set, the code will wait for it indefinitely in busy loop.
Quoted 4 lines
Quoted 2 lines
and also to prevent wakeup problem on GP chips with device off mode.
What wakeup problem?
This is apparently related to the GIC restore issue addressed with patch 3/8 of the core-ret set (workaround for the ROM bug because of CA9 r2pX gic register change), the interrupts get disabled. Maybe Santosh has some comments on this one.
Quoted 4 lines
Quoted 2 lines
Signed-off-by Tero Kristo <[email protected]>Assembly code should have some comments to aid comprehension.
Will add.
Quoted 35 lines
Quoted 22 lines
--- arch/arm/mach-omap2/omap-headsmp.S | 45 ++++++++++++++++++++++++++++++++--- 1 files changed, 41 insertions(+), 4 deletions(-)arch/arm/mach-omap2/omap-headsmp.S +6
-0@@ -17,8 +17,37 @@ #include <linux/linkage.h> #include <linux/init.h> +#include <mach/omap-secure.h> +#include "prcm_mpu44xx.h" + +#define CPU1_PWRSTCTRL (OMAP4430_PRCM_MPU_BASE + OMAP4430_PRCM_MPU_CPU1_INST + \ + OMAP4_PM_CPU1_PWRSTCTRL_OFFSET) __CPUINIT +arch/arm/mach-omap2/omap-headsmp.S line 37
Quoted 10 lines
arch/arm/mach-omap2/omap-headsmp.S +10
-0+ENTRY(omap_cpu1_off) + ldr r12, =CPU1_PWRSTCTRL + ldr r0, [r12] + and r0, #3 + cmp r0, #2 + beq exit_cpu1_off + + mov r0, #0x3 + mov r1, #0x0 + ldr r12, =OMAP4_MON_SCU_PWR_INDEXHelp! no comments.
Quoted 4 lines
arch/arm/mach-omap2/omap-headsmp.S line 39
Quoted 2 lines
arch/arm/mach-omap2/omap-headsmp.S +2
-0+ dsb + smc #0The
DO_SMCinsleep44xx.Ssuggests there should be another dsb here.
Not sure if that is needed here as we have multiple barriers following this, but I'll add it just to be sure.
Quoted 9 lines
arch/arm/mach-omap2/omap-headsmp.S line 46
Quoted 7 lines
arch/arm/mach-omap2/omap-headsmp.S +6
-0+ isb + dsb + dmb + wfi + nop + nopShoudln't this use
omap_do_wfi?
Can't, as we don't have stack yet at this point, and omap_do_wfi attempts to push stuff into stack.
-Tero
Quoted 55 lines
Kevin
Quoted 52 lines
arch/arm/mach-omap2/omap-headsmp.S +16
-4+exit_cpu1_off: + mov pc, lr +ENDPROC(omap_cpu1_off) + /* * OMAP4 specific entry point for secondary CPU to jump from ROM * code. This routine also provides a holding flag into which@@ -27,32 +56,40 @@ * register AuxCoreBoot0. */ ENTRY(omap_secondary_startup) -hold: ldr r12,=0x103 + ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 mov r0, r0, lsr #9 mrc p15, 0, r4, c0, c0, 5 and r4, r4, #0x0f cmp r0, r4 - bne hold + beq omap_cont_boot + + bl omap_cpu1_off + b omap_secondary_startup /* * we've been released from the wait loop,secondary_stack * should now contain the SVC stack for this core */ +omap_cont_boot: b secondary_startup ENDPROC(omap_secondary_startup) ENTRY(omap_secondary_startup_4460) -hold_2: ldr r12,=0x103 + ldr r12,=0x103 dsb smc #0 @ read from AuxCoreBoot0 mov r0, r0, lsr #9 mrc p15, 0, r4, c0, c0, 5 and r4, r4, #0x0f cmp r0, r4 - bne hold_2 + beq omap4460_cont_boot + + bl omap_cpu1_off + b omap_secondary_startup_4460 +omap4460_cont_boot: /* * GIC distributor control register has changed between * CortexA9 r1pX and r2pX. The Control Register secure
PATCH v2 17/19 ARM: OMAP4: put cpu1 back to sleep if no wake request
Tero,
Quoted 21 lines · Tero Kristo
Quoted 7 lines · Kevin Hilman
Quoted 2 lines · Tero Kristo
If
AUX_CORE_BOOT0does not indicate wakeup request for cpu1, put it back to off.Why is it waking up then? ?(I know the answer, but will forget. ?The changelog serves as my long-term memory.)
Will add comment. (Both cpus will wake-up after device-off reset.)
Quoted 5 lines
Quoted 3 lines
This is needed during wakeup from device off to prevent cpu1 from being stuck indefinitely in the wakeup loop
Why does it get stuck?
Related to the above, if the
AUX_CORE_BOOT0is not set, the code will wait for it indefinitely in busy loop.Quoted 1 line
Quoted 9 lines
Quoted 3 lines
Quoted 1 line
and also to prevent wakeup problem on GP chips with device off mode.
What wakeup problem?
This is apparently related to the GIC restore issue addressed with patch 3/8 of the core-ret set (workaround for the ROM bug because of CA9 r2pX gic register change), the interrupts get disabled. Maybe Santosh has some comments on this one.
Quoted 1 line
Not sure what you mean wakeup issue on GP device.
IIUC, the issue is:
Wakeup from device OFF, hardware releases the reset for both CPUs, This is special case and applicable only for device OFF. The reason CPU1 needs to be hold back, because the security SW is affined with CPU0 which needs to be up and running for any of the ROM code APIs to work. Like setting up SMP bit, AUX control etc. Without CPU0 booted, CPU1 won't be able to execute those ROM functions and hence won't be able to boot properly.
I think the limitation is applicable to all OMAP4 devices as well as OMAP5 devices.
Regards
Santosh
PATCH v2 17/19 ARM: OMAP4: put cpu1 back to sleep if no wake request
Quoted 35 lines · Santosh
Tero,
Quoted 21 lines · Tero Kristo
Quoted 7 lines · Kevin Hilman
Quoted 2 lines · Tero Kristo
If
AUX_CORE_BOOT0does not indicate wakeup request for cpu1, put it back to off.Why is it waking up then? ?(I know the answer, but will forget. ?The changelog serves as my long-term memory.)
Will add comment. (Both cpus will wake-up after device-off reset.)
Quoted 5 lines
Quoted 3 lines
This is needed during wakeup from device off to prevent cpu1 from being stuck indefinitely in the wakeup loop
Why does it get stuck?
Related to the above, if the
AUX_CORE_BOOT0is not set, the code will wait for it indefinitely in busy loop.Quoted 1 line
Quoted 9 lines
Quoted 3 lines
Quoted 1 line
and also to prevent wakeup problem on GP chips with device off mode.
What wakeup problem?
This is apparently related to the GIC restore issue addressed with patch 3/8 of the core-ret set (workaround for the ROM bug because of CA9 r2pX gic register change), the interrupts get disabled. Maybe Santosh has some comments on this one.
Quoted 1 line
Not sure what you mean wakeup issue on GP device.
Quoted 8 lines
IIUC, the issue is:
Wakeup from device OFF, hardware releases the reset for both CPUs, This is special case and applicable only for device OFF. The reason CPU1 needs to be hold back, because the security SW is affined with CPU0 which needs to be up and running for any of the ROM code APIs to work. Like setting up SMP bit, AUX control etc. Without CPU0 booted, CPU1 won't be able to execute those ROM functions and hence won't be able to boot properly.
That's a nice description of the problem. Please incorporate a summary like this into the changlog to describe the problem, then describe the solution.
Thanks,
Kevin
Quoted 2 lines
I think the limitation is applicable to all OMAP4 devices as well as OMAP5 devices.
PATCH v2 17/19 ARM: OMAP4: put cpu1 back to sleep if no wake request
In reply to Shilimkar, SantoshQuoted 13 lines · Santosh
Quoted 2 lines
Quoted 2 lines
Not sure what you mean wakeup issue on GP device.
IIUC, the issue is:
Wakeup from device OFF, hardware releases the reset for both CPUs, This is special case and applicable only for device OFF. The reason CPU1 needs to be hold back, because the security SW is affined with CPU0 which needs to be up and running for any of the ROM code APIs to work. Like setting up SMP bit, AUX control etc. Without CPU0 booted, CPU1 won't be able to execute those ROM functions and hence won't be able to boot properly.
Quoted 2 lines
I think the limitation is applicable to all OMAP4 devices as well as OMAP5 devices.
yes, the stagger of CPU1 behind CPU0 has a few factors:
HS devices with an older PPA release has a bug where caches can be messed up and GP devices
need slightly different WA. with the older PPA, we put CPU1 back to OFF when we detect that CPU0 is not ready for action
you can find the details and documentation in the link below:
http://git.omapzoom.org/?p=kernel/omap.git;a=blob;f=arch/arm/mach-omap2/sleep44xx.S;h=0c28def8f644e9803564bb66c8cfe8c580898978;hb=p-android-omap-3.0#l342
Regards,
Nishanth Menon
PATCH v2 18/19 ARM: OMAP4460: wakeupgen: set GIC_CPU0 backup status flag always
In reply to Tero KristoWithout this, CPU0 will crash in the ROM code during wakeup from device off. This patch also clears the GIC save area, to prevent ROM code from writing garbage to the GIC registers during wakeup. The actual GIC restore is done by kernel.
This bug fix applies only to OMAP4460, it is fixed on OMAP4470.
--- arch/arm/mach-omap2/omap-wakeupgen.c | 14 ++++++++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 1 + 2 files changed, 15 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap-wakeupgen.c +14 -0
@@ -447,10 +447,24 @@ int __init omap_wakeupgen_init(void)if (omap_type () ==OMAP2_DEVICE_TYPE_GP ) { sar_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); +/* Clean GIC SAR area */ +for (i =SAR_BACKUP_STATUS_OFFSET ; i <WAKEUPGENENB_OFFSET_CPU0 ; + i +=4 ) +sar_writel (0 , i,0 ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU0_OFFSET ,0 );sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU1_OFFSET ,0 );for (i =0 ; i < max_spi_reg; i++)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i); + +/* +* Set CPU0 GIC backup flag permanently for omap4460, +* this is needed because of the ROM code bug that breaks +* GIC during wakeup from device off +*/ +if (cpu_is_omap446x ()) +__raw_writel (SAR_BACKUP_STATUS_GIC_CPU0 , + sar_base +SAR_BACKUP_STATUS_OFFSET );iounmap (sar_base); sar_base =NULL ; }else {
arch/arm/mach-omap2/omap4-sar-layout.h +1 -0
@@ -88,6 +88,7 @@#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c)#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510)#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514) +#define SAR_BACKUP_STATUS_GIC_CPU0 0x1/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
Signature · 1 line
1.7.4.1
PATCH v2 18/19 ARM: OMAP4460: wakeupgen: set GIC_CPU0 backup status flag always
Quoted 8 lines · Tero Kristo
Without this, CPU0 will crash in the ROM code during wakeup from device off. This patch also clears the GIC save area, to prevent ROM code from writing garbage to the GIC registers during wakeup. The actual GIC restore is done by kernel.
This bug fix applies only to OMAP4460, it is fixed on OMAP4470.
Signed-off-by Tero Kristo <[email protected]>
Please create/use PM_ERRATUM flag.
Kevin
Quoted 46 lines
--- arch/arm/mach-omap2/omap-wakeupgen.c | 14 ++++++++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 1 + 2 files changed, 15 insertions(+), 0 deletions(-)arch/arm/mach-omap2/omap-wakeupgen.c +14
-0@@ -447,10 +447,24 @@ int __init omap_wakeupgen_init(void)if (omap_type () ==OMAP2_DEVICE_TYPE_GP ) { sar_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); +/* Clean GIC SAR area */ +for (i =SAR_BACKUP_STATUS_OFFSET ; i <WAKEUPGENENB_OFFSET_CPU0 ; + i +=4 ) +sar_writel (0 , i,0 ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU0_OFFSET ,0 );sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU1_OFFSET ,0 );for (i =0 ; i < max_spi_reg; i++)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i); + +/* +* Set CPU0 GIC backup flag permanently for omap4460, +* this is needed because of the ROM code bug that breaks +* GIC during wakeup from device off +*/ +if (cpu_is_omap446x ()) +__raw_writel (SAR_BACKUP_STATUS_GIC_CPU0 , + sar_base +SAR_BACKUP_STATUS_OFFSET );iounmap (sar_base); sar_base =NULL ; }else {arch/arm/mach-omap2/omap4-sar-layout.h +1
-0@@ -88,6 +88,7 @@#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c)#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510)#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514) +#define SAR_BACKUP_STATUS_GIC_CPU0 0x1/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
PATCH v2 18/19 ARM: OMAP4460: wakeupgen: set GIC_CPU0 backup status flag always
Quoted 7 lines · Kevin Hilman
Quoted 5 lines · Tero Kristo
Without this, CPU0 will crash in the ROM code during wakeup from device off. This patch also clears the GIC save area, to prevent ROM code from writing garbage to the GIC registers during wakeup. The actual GIC restore is done by kernel.
Quoted 5 lines
Quoted 3 lines
This bug fix applies only to OMAP4460, it is fixed on OMAP4470.
Signed-off-by Tero Kristo <[email protected]>Please create/use
PM_ERRATUMflag.
Okay.
-Tero
Quoted 49 lines
Kevin
Quoted 46 lines
--- arch/arm/mach-omap2/omap-wakeupgen.c | 14 ++++++++++++++ arch/arm/mach-omap2/omap4-sar-layout.h | 1 + 2 files changed, 15 insertions(+), 0 deletions(-)arch/arm/mach-omap2/omap-wakeupgen.c +14
-0@@ -447,10 +447,24 @@ int __init omap_wakeupgen_init(void)if (omap_type () ==OMAP2_DEVICE_TYPE_GP ) { sar_base =ioremap (OMAP44XX_SAR_RAM_BASE ,SZ_16K ); +/* Clean GIC SAR area */ +for (i =SAR_BACKUP_STATUS_OFFSET ; i <WAKEUPGENENB_OFFSET_CPU0 ; + i +=4 ) +sar_writel (0 , i,0 ); +sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU0_OFFSET ,0 );sar_writel (GIC_ISR_NON_SECURE ,ICDISR_CPU1_OFFSET ,0 );for (i =0 ; i < max_spi_reg; i++)sar_writel (GIC_ISR_NON_SECURE ,ICDISR_SPI_OFFSET , i); + +/* +* Set CPU0 GIC backup flag permanently for omap4460, +* this is needed because of the ROM code bug that breaks +* GIC during wakeup from device off +*/ +if (cpu_is_omap446x ()) +__raw_writel (SAR_BACKUP_STATUS_GIC_CPU0 , + sar_base +SAR_BACKUP_STATUS_OFFSET );iounmap (sar_base); sar_base =NULL ; }else {arch/arm/mach-omap2/omap4-sar-layout.h +1
-0@@ -88,6 +88,7 @@#define ICDISR_CPU0_OFFSET (SAR_BANK3_OFFSET + 0x50c)#define ICDISR_CPU1_OFFSET (SAR_BANK3_OFFSET + 0x510)#define ICDISR_SPI_OFFSET (SAR_BANK3_OFFSET + 0x514) +#define SAR_BACKUP_STATUS_GIC_CPU0 0x1/* WakeUpGen save restore offset from OMAP44XX_SAR_RAM_BASE */ #define WAKEUPGENENB_OFFSET_CPU0 (SAR_BANK3_OFFSET + 0x684)
PATCH v2 19/19 ARM: OMAP4: powerdomain: update mpu / core off counters during device off
In reply to Tero KristoCurrently device off does not have any counters / timers of its own and it is impossible to track the time spent in this state. In device off, MPU / CORE powerdomains enter OSWR, so normally the RETENTION state times / counts are increased during device off.
This patch adds a new field to the powerdomain struct for context loss register, which is checked during pwrdm_post_transition to see if a device off type context loss has happened. If this is the case, the counters + timers for OFF state are touched instead of RETENTION.
--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 1 - arch/arm/mach-omap2/powerdomain.c | 9 +++++++++ arch/arm/mach-omap2/powerdomain.h | 2 ++ arch/arm/mach-omap2/powerdomains44xx_data.c | 2 ++ arch/arm/mach-omap2/prm44xx.c | 15 +++++++++++++++ arch/arm/mach-omap2/prm44xx.h | 2 ++ 6 files changed, 30 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0 -1
@@ -404,7 +404,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();omap4_cm_resume_off (); -omap4_device_clear_prev_off_state (); } sar_save_failed:
arch/arm/mach-omap2/powerdomain.c +9 -0
@@ -156,6 +156,15 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)break ;case PWRDM_STATE_PREV : prev =pwrdm_read_prev_pwrst (pwrdm); + +/* +* If powerdomain has context offset defined, check if +* the domain has lost context (i.e. entered off) +*/ +if (pwrdm->context_offs) +if (omap4_pwrdm_lost_context_rff (pwrdm->prcm_offs, + pwrdm->context_offs)) + prev =PWRDM_POWER_OFF ;if (pwrdm->state != prev) pwrdm->state_counter[prev]++;if (prev ==PWRDM_POWER_RET )
arch/arm/mach-omap2/powerdomain.h +2 -0
@@ -82,6 +82,7 @@ struct powerdomain;* @name: Powerdomain name * @voltdm: voltagedomain containing this powerdomain * @prcm_offs: the address offset from CM_BASE/PRM_BASE +* @context_offs: the address offset for the CONTEXT register * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs * @pwrsts: Possible powerdomain power states * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION
@@ -106,6 +107,7 @@ struct powerdomain {struct voltagedomain *ptr; } voltdm;const s16 prcm_offs; +const s16 context_offs;const u8 pwrsts;const u8 pwrsts_logic_ret;const u8 flags;
arch/arm/mach-omap2/powerdomains44xx_data.c +2 -0
@@ -36,6 +36,7 @@ static struct powerdomain core_44xx_pwrdm = { .voltdm = { .name = "core" }, .prcm_offs = OMAP4430_PRM_CORE_INST, .prcm_partition = OMAP4430_PRM_PARTITION, + .context_offs = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET, .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 5,
@@ -205,6 +206,7 @@ static struct powerdomain mpu_44xx_pwrdm = { .voltdm = { .name = "mpu" }, .prcm_offs = OMAP4430_PRM_MPU_INST, .prcm_partition = OMAP4430_PRM_PARTITION, + .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET, .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 3,
arch/arm/mach-omap2/prm44xx.c +15 -0
@@ -289,6 +289,21 @@ static void __init omap44xx_prm_enable_io_wakeup(void) OMAP4_PRM_IO_PMCTRL_OFFSET); } +bool omap4_pwrdm_lost_context_rff (s16 inst,s16 offset) +{ +u32 val; + + val =omap4_prminst_read_inst_reg (OMAP4430_PRM_PARTITION , inst, offset); + +if (val &OMAP4430_LOSTCONTEXT_RFF_MASK ) { +omap4_prminst_write_inst_reg (val,OMAP4430_PRM_PARTITION , inst, + offset); +return true; + } + +return false; +} +/** * omap4_device_set_state_off() - setup device off state * @enable: set to off or not.
arch/arm/mach-omap2/prm44xx.h +2 -0
@@ -771,6 +771,8 @@ extern void omap44xx_prm_ocp_barrier(void);extern void omap44xx_prm_save_and_clear_irqen (u32 *saved_mask);extern void omap44xx_prm_restore_irqen (u32 *saved_mask); +extern bool omap4_pwrdm_lost_context_rff (s16 inst,s16 offset); +# endif #endif
Signature · 1 line
1.7.4.1
PATCH v2 19/19 ARM: OMAP4: powerdomain: update mpu / core off counters during device off
Quoted 25 lines · Tero Kristo
Currently device off does not have any counters / timers of its own and it is impossible to track the time spent in this state. In device off, MPU / CORE powerdomains enter OSWR, so normally the RETENTION state times / counts are increased during device off.
This patch adds a new field to the powerdomain struct for context loss register, which is checked during
pwrdm_post_transitionto see if a device off type context loss has happened. If this is the case, the counters + timers for OFF state are touched instead of RETENTION.Signed-off-by Tero Kristo <[email protected]>---
?arch/arm/mach-omap2/omap-mpuss-lowpower.c ? | ? ?1 - ?arch/arm/mach-omap2/powerdomain.c ? ? ? ? ? | ? ?9 +++++++++ ?arch/arm/mach-omap2/powerdomain.h ? ? ? ? ? | ? ?2 ++ ?arch/arm/mach-omap2/powerdomains44xx_data.c | ? ?2 ++ ?arch/arm/mach-omap2/prm44xx.c ? ? ? ? ? ? ? | ? 15 +++++++++++++++ ?arch/arm/mach-omap2/prm44xx.h ? ? ? ? ? ? ? | ? ?2 ++?6 files changed, 30 insertions(+), 1 deletions(-)
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 407
Quoted 4 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-1@@ -404,7 +404,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) ? ? ? ?if (omap4_device_prev_state_off()) { ? ? ? ? ? ? ? ?omap4_dpll_resume_off(); ? ? ? ? ? ? ? ?omap4_cm_resume_off(); - ? ? ? ? ? ? ? omap4_device_clear_prev_off_state();
We should probably delete the function in it's entirety - not just the call - the original implementation just clears L3 and this implementation seems superior.
Quoted 11 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0? ? ? ?}?sar_save_failed:
arch/arm/mach-omap2/powerdomain.c +0
-0@@ -156,6 +156,15 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) ? ? ? ? ? ? ? ?break;? ? ? ?case
PWRDM_STATE_PREV:
? ? ? ? ? ? ? ?prev =pwrdm_read_prev_pwrst(pwrdm);
Quoted 8 lines
+
+ ? ? ? ? ? ? ? /*
+ ? ? ? ? ? ? ? ?* If powerdomain has context offset defined, check if
+ ? ? ? ? ? ? ? ?* the domain has lost context (i.e. entered off)
+ ? ? ? ? ? ? ? ?*/
+ ? ? ? ? ? ? ? if (pwrdm->context_offs)
+ ? ? ? ? ? ? ? ? ? ? ? if (omap4_pwrdm_lost_context_rff(pwrdm->prcm_offs,
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pwrdm->context_offs))
We should wrap this under pwrdm_lost_context(pwrdm) pwrdm_lost_context should call the arch_pwrdm->lost_context_rff as needed? the rest of the powerdomain.c does not use OMAP4 specific APIs.
Quoted 37 lines
+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? prev =
PWRDM_POWER_OFF; ? ? ? ? ? ? ? ?if (pwrdm->state!= prev)
? ? ? ? ? ? ? ? ? ? ? ?pwrdm->state_counter[prev]++; ? ? ? ? ? ? ? ?if (prev ==PWRDM_POWER_RET)arch/arm/mach-omap2/powerdomain.h +0
-0@@ -82,6 +82,7 @@ struct powerdomain;?* @name: Powerdomain name
?* @voltdm: voltagedomain containing this powerdomain
?* @prcm_offs: the address offset from CM_BASE/PRM_BASE
+ * @context_offs: the address offset for the CONTEXT register ?* @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs ?* @pwrsts: Possible powerdomain power states
?* @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTIONarch/arm/mach-omap2/powerdomain.h +1
-0@@ -106,6 +107,7 @@ struct powerdomain { ? ? ? ? ? ? ? ?struct voltagedomain *ptr; ? ? ? ?} voltdm; ? ? ? ?const s16 prcm_offs; + ? ? ? const s16 context_offs; ? ? ? ?const u8 pwrsts; ? ? ? ?const u8 pwrsts_logic_ret; ? ? ? ?const u8 flags;arch/arm/mach-omap2/powerdomains44xx_data.c +1
-0@@ -36,6 +36,7 @@ static struct powerdomain core_44xx_pwrdm = { ? ? ? ?.voltdm ? ? ? ? ? = { .name = "core" }, ? ? ? ?.prcm_offs ? ? ? ?= OMAP4430_PRM_CORE_INST, ? ? ? ?.prcm_partition ? = OMAP4430_PRM_PARTITION, + ? ? ? .context_offs ? ? = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET, ? ? ? ?.pwrsts ? ? ? ? ? = PWRSTS_RET_ON, ? ? ? ?.pwrsts_logic_ret = PWRSTS_OFF_RET, ? ? ? ?.banks ? ? ? ? ? ?= 5,
arch/arm/mach-omap2/powerdomains44xx_data.c static struct powerdomain mpu_44xx_pwrdm = { · line 212
Quoted 7 lines
arch/arm/mach-omap2/powerdomains44xx_data.c +1
-0@@ -205,6 +206,7 @@ static struct powerdomain mpu_44xx_pwrdm = { ? ? ? ?.voltdm ? ? ? ? ? = { .name = "mpu" }, ? ? ? ?.prcm_offs ? ? ? ?= OMAP4430_PRM_MPU_INST, ? ? ? ?.prcm_partition ? = OMAP4430_PRM_PARTITION, + ? ? ? .context_offs ? ? = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET, ? ? ? ?.pwrsts ? ? ? ? ? = PWRSTS_RET_ON, ? ? ? ?.pwrsts_logic_ret = PWRSTS_OFF_RET, ? ? ? ?.banks ? ? ? ? ? ?= 3,
Why are we not populating the rest of the CONTEXT_OFFSET registers?
Quoted 13 lines
arch/arm/mach-omap2/prm44xx.c +5
-0@@ -289,6 +289,21 @@ static void __init omap44xx_prm_enable_io_wakeup(void) ? ? ? ? ? ? ? ? ? ? ? ?OMAP4_PRM_IO_PMCTRL_OFFSET); ?} +bool omap4_pwrdm_lost_context_rff (s16 inst,s16 offset) +{ + ? ? ? u32 val; + + ? ? ? val = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst, offset);
arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 306
Quoted 10 lines
arch/arm/mach-omap2/prm44xx.c +10
-0+ + ? ? ? if (val & OMAP4430_LOSTCONTEXT_RFF_MASK) { + ? ? ? ? ? ? ? omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, inst, + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?offset); + ? ? ? ? ? ? ? return true; + ? ? ? } + + ? ? ? return false; +} +
could move to powerdomain4xx.c?
arch/arm/mach-omap2/prm44xx.h extern void omap44xx_prm_ocp_barrier(void); · line 774
Quoted 12 lines
?/**
?*omap4_device_set_state_off()- setup device off state ?* @enable: ? ?set to off or not.arch/arm/mach-omap2/prm44xx.h +1
-0@@ -771,6 +771,8 @@ extern void omap44xx_prm_ocp_barrier(void); ?extern void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask); ?extern void omap44xx_prm_restore_irqen(u32 *saved_mask); +extern bool omap4_pwrdm_lost_context_rff (s16 inst,s16 offset);
we dont need to do this if we use arch_pwrdm->
Quoted 4 lines
arch/arm/mach-omap2/prm44xx.h +1
-0+?# endif
?#endif
---
Regards,
Nishanth Menon
PATCH v2 19/19 ARM: OMAP4: powerdomain: update mpu / core off counters during device off
Quoted 21 lines · Nishanth
Quoted 20 lines · Tero Kristo
Currently device off does not have any counters / timers of its own and it is impossible to track the time spent in this state. In device off, MPU / CORE powerdomains enter OSWR, so normally the RETENTION state times / counts are increased during device off.
This patch adds a new field to the powerdomain struct for context loss register, which is checked during
pwrdm_post_transitionto see if a device off type context loss has happened. If this is the case, the counters + timers for OFF state are touched instead of RETENTION.Signed-off-by Tero Kristo <[email protected]>--- arch/arm/mach-omap2/omap-mpuss-lowpower.c | 1 - arch/arm/mach-omap2/powerdomain.c | 9 +++++++++ arch/arm/mach-omap2/powerdomain.h | 2 ++ arch/arm/mach-omap2/powerdomains44xx_data.c | 2 ++ arch/arm/mach-omap2/prm44xx.c | 15 +++++++++++++++ arch/arm/mach-omap2/prm44xx.h | 2 ++ 6 files changed, 30 insertions(+), 1 deletions(-)
Quoted 13 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) · line 407
Quoted 9 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-1@@ -404,7 +404,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)if (omap4_device_prev_state_off ()) {omap4_dpll_resume_off ();omap4_cm_resume_off (); -omap4_device_clear_prev_off_state ();We should probably delete the function in it's entirety - not just the call - the original implementation just clears L3 and this implementation seems superior.
Yeah, that can be done, I don't think it is used anymore after this change.
Quoted 17 lines
Quoted 17 lines
arch/arm/mach-omap2/omap-mpuss-lowpower.c +0
-0} sar_save_failed:arch/arm/mach-omap2/powerdomain.c +5
-0@@ -156,6 +156,15 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)break ;case PWRDM_STATE_PREV : prev =pwrdm_read_prev_pwrst (pwrdm); + +/* +* If powerdomain has context offset defined, check if +* the domain has lost context (i.e. entered off) +*/
Quoted 8 lines
arch/arm/mach-omap2/powerdomain.c static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag) · line 166
Quoted 3 lines
arch/arm/mach-omap2/powerdomain.c +3
-0+if (pwrdm->context_offs) +if (omap4_pwrdm_lost_context_rff (pwrdm->prcm_offs, + pwrdm->context_offs))We should wrap this under
pwrdm_lost_context(pwrdm)pwrdm_lost_contextshould call thearch_pwrdm->lost_context_rffas needed? the rest of thepowerdomain.cdoes not use OMAP4 specific APIs.
Yes, that sounds like a good change, I'll change this.
Quoted 40 lines
Quoted 40 lines
arch/arm/mach-omap2/powerdomain.c +1
-0+ prev =PWRDM_POWER_OFF ;if (pwrdm->state != prev) pwrdm->state_counter[prev]++;if (prev ==PWRDM_POWER_RET )arch/arm/mach-omap2/powerdomain.h +2
-0@@ -82,6 +82,7 @@ struct powerdomain;* @name: Powerdomain name * @voltdm: voltagedomain containing this powerdomain * @prcm_offs: the address offset from CM_BASE/PRM_BASE +* @context_offs: the address offset for the CONTEXT register * @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs * @pwrsts: Possible powerdomain power states * @pwrsts_logic_ret: Possible logic power states when pwrdm in RETENTION @@ -106,6 +107,7 @@ struct powerdomain {struct voltagedomain *ptr; } voltdm;const s16 prcm_offs; +const s16 context_offs;const u8 pwrsts;const u8 pwrsts_logic_ret;const u8 flags;arch/arm/mach-omap2/powerdomains44xx_data.c +1
-0@@ -36,6 +36,7 @@ static struct powerdomain core_44xx_pwrdm = { .voltdm = { .name = "core" }, .prcm_offs = OMAP4430_PRM_CORE_INST, .prcm_partition = OMAP4430_PRM_PARTITION, + .context_offs = OMAP4_RM_L3_1_L3_1_CONTEXT_OFFSET, .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 5,@@ -205,6 +206,7 @@ static struct powerdomain mpu_44xx_pwrdm = { .voltdm = { .name = "mpu" },
Quoted 8 lines
arch/arm/mach-omap2/powerdomains44xx_data.c static struct powerdomain mpu_44xx_pwrdm = { · line 212
Quoted 6 lines
arch/arm/mach-omap2/powerdomains44xx_data.c +1
-0.prcm_offs = OMAP4430_PRM_MPU_INST, .prcm_partition = OMAP4430_PRM_PARTITION, + .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET, .pwrsts = PWRSTS_RET_ON, .pwrsts_logic_ret = PWRSTS_OFF_RET, .banks = 3,Why are we not populating the rest of the
CONTEXT_OFFSETregisters?
Well, the thing is, other domains don't have any 'spare' context registers that are not needed by anything else. Like, all the per domain context registers are used by some hwmod. If we grab the register for this use, then the context lost count for that hwmod will break.
For PER domain, it might be possible to use RM_L4PER_L4_PER_CONTEXT though (it has two bit positions), but that is the only one missing... Other domains do go to OFF. L3_init domain doesn't have anything.
Quoted 18 lines
Quoted 18 lines
arch/arm/mach-omap2/prm44xx.c +9
-0@@ -289,6 +289,21 @@ static void __init omap44xx_prm_enable_io_wakeup(void) OMAP4_PRM_IO_PMCTRL_OFFSET); } +bool omap4_pwrdm_lost_context_rff (s16 inst,s16 offset) +{ +u32 val; + + val =omap4_prminst_read_inst_reg (OMAP4430_PRM_PARTITION , inst, offset); + +if (val &OMAP4430_LOSTCONTEXT_RFF_MASK ) { +omap4_prminst_write_inst_reg (val,OMAP4430_PRM_PARTITION , inst, + offset);
Quoted 8 lines
arch/arm/mach-omap2/prm44xx.c static void __init omap44xx_prm_enable_io_wakeup(void) · line 306
Quoted 6 lines
arch/arm/mach-omap2/prm44xx.c +6
-0+return true; + } + +return false; +} +could move to
powerdomain4xx.c?
Yes, I'll do that.
-Tero
Quoted 22 lines
arch/arm/mach-omap2/prm44xx.h extern void omap44xx_prm_ocp_barrier(void); · line 774
Quoted 13 lines
arch/arm/mach-omap2/prm44xx.c +0
-0/** * omap4_device_set_state_off() - setup device off state * @enable: set to off or not. arch/arm/mach-omap2/prm44xx.h +1
-0@@ -771,6 +771,8 @@ extern void omap44xx_prm_ocp_barrier(void);extern void omap44xx_prm_save_and_clear_irqen (u32 *saved_mask);extern void omap44xx_prm_restore_irqen (u32 *saved_mask); +extern bool omap4_pwrdm_lost_context_rff (s16 inst,s16 offset);we dont need to do this if we use arch_pwrdm->
arch/arm/mach-omap2/prm44xx.h extern void omap44xx_prm_ocp_barrier(void); · line 778
Quoted 4 lines
arch/arm/mach-omap2/prm44xx.h +1
-0+# endif #endif ---
Regards,
Nishanth Menon