diff options
author | Tero Kristo <tero.kristo@nokia.com> | 2008-10-13 06:15:00 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-11-11 17:42:25 -0500 |
commit | 27d59a4a2def42307349079f2e3538d96934c379 (patch) | |
tree | d581f0960d280dbe0f8c8ee03e111cadbfcf59db /arch/arm/mach-omap2/pm34xx.c | |
parent | f2d1185824fd3ed631f3164daeff59d0b4e55d79 (diff) |
OMAP3 PM: off-mode support for HS/EMU devices
For HS/EMU devices, some additional resources need to be
saved/restored for off-mode support. Namely, saving the secure RAM
and a pointer to it in the scratchpad.
Signed-off-by: Tero Kristo <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-omap2/pm34xx.c')
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 54fea79b1720..ebb88f3aae31 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -63,6 +63,8 @@ static LIST_HEAD(pwrst_list); | |||
63 | 63 | ||
64 | static void (*_omap_sram_idle)(u32 *addr, int save_state); | 64 | static void (*_omap_sram_idle)(u32 *addr, int save_state); |
65 | 65 | ||
66 | static int (*_omap_save_secure_sram)(u32 *addr); | ||
67 | |||
66 | static struct powerdomain *mpu_pwrdm, *neon_pwrdm; | 68 | static struct powerdomain *mpu_pwrdm, *neon_pwrdm; |
67 | static struct powerdomain *core_pwrdm, *per_pwrdm; | 69 | static struct powerdomain *core_pwrdm, *per_pwrdm; |
68 | 70 | ||
@@ -110,6 +112,33 @@ static void omap3_core_restore_context(void) | |||
110 | omap_dma_global_context_restore(); | 112 | omap_dma_global_context_restore(); |
111 | } | 113 | } |
112 | 114 | ||
115 | static void omap3_save_secure_ram_context(u32 target_mpu_state) | ||
116 | { | ||
117 | u32 ret; | ||
118 | |||
119 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { | ||
120 | /* Disable dma irq before calling secure rom code API */ | ||
121 | omap_dma_disable_irq(0); | ||
122 | omap_dma_disable_irq(1); | ||
123 | /* | ||
124 | * MPU next state must be set to POWER_ON temporarily, | ||
125 | * otherwise the WFI executed inside the ROM code | ||
126 | * will hang the system. | ||
127 | */ | ||
128 | pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); | ||
129 | ret = _omap_save_secure_sram((u32 *) | ||
130 | __pa(omap3_secure_ram_storage)); | ||
131 | pwrdm_set_next_pwrst(mpu_pwrdm, target_mpu_state); | ||
132 | /* Following is for error tracking, it should not happen */ | ||
133 | if (ret) { | ||
134 | printk(KERN_ERR "save_secure_sram() returns %08x\n", | ||
135 | ret); | ||
136 | while (1) | ||
137 | ; | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | |||
113 | /* | 142 | /* |
114 | * PRCM Interrupt Handler Helper Function | 143 | * PRCM Interrupt Handler Helper Function |
115 | * | 144 | * |
@@ -308,6 +337,7 @@ static void omap_sram_idle(void) | |||
308 | if (core_next_state == PWRDM_POWER_OFF) { | 337 | if (core_next_state == PWRDM_POWER_OFF) { |
309 | omap3_core_save_context(); | 338 | omap3_core_save_context(); |
310 | omap3_prcm_save_context(); | 339 | omap3_prcm_save_context(); |
340 | omap3_save_secure_ram_context(mpu_next_state); | ||
311 | } | 341 | } |
312 | /* Enable IO-PAD wakeup */ | 342 | /* Enable IO-PAD wakeup */ |
313 | prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); | 343 | prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN); |
@@ -901,6 +931,9 @@ void omap_push_sram_idle(void) | |||
901 | { | 931 | { |
902 | _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, | 932 | _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, |
903 | omap34xx_cpu_suspend_sz); | 933 | omap34xx_cpu_suspend_sz); |
934 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) | ||
935 | _omap_save_secure_sram = omap_sram_push(save_secure_ram_context, | ||
936 | save_secure_ram_context_sz); | ||
904 | } | 937 | } |
905 | 938 | ||
906 | static int __init omap3_pm_init(void) | 939 | static int __init omap3_pm_init(void) |
@@ -916,7 +949,6 @@ static int __init omap3_pm_init(void) | |||
916 | /* XXX prcm_setup_regs needs to be before enabling hw | 949 | /* XXX prcm_setup_regs needs to be before enabling hw |
917 | * supervised mode for powerdomains */ | 950 | * supervised mode for powerdomains */ |
918 | prcm_setup_regs(); | 951 | prcm_setup_regs(); |
919 | omap3_save_scratchpad_contents(); | ||
920 | 952 | ||
921 | ret = request_irq(INT_34XX_PRCM_MPU_IRQ, | 953 | ret = request_irq(INT_34XX_PRCM_MPU_IRQ, |
922 | (irq_handler_t)prcm_interrupt_handler, | 954 | (irq_handler_t)prcm_interrupt_handler, |
@@ -961,6 +993,15 @@ static int __init omap3_pm_init(void) | |||
961 | */ | 993 | */ |
962 | pwrdm_add_wkdep(per_pwrdm, core_pwrdm); | 994 | pwrdm_add_wkdep(per_pwrdm, core_pwrdm); |
963 | 995 | ||
996 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { | ||
997 | omap3_secure_ram_storage = | ||
998 | kmalloc(0x803F, GFP_KERNEL); | ||
999 | if (!omap3_secure_ram_storage) | ||
1000 | printk(KERN_ERR "Memory allocation failed when" | ||
1001 | "allocating for secure sram context\n"); | ||
1002 | } | ||
1003 | omap3_save_scratchpad_contents(); | ||
1004 | |||
964 | err1: | 1005 | err1: |
965 | return ret; | 1006 | return ret; |
966 | err2: | 1007 | err2: |