aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/pm34xx.c
diff options
context:
space:
mode:
authorTero Kristo <tero.kristo@nokia.com>2008-10-13 06:15:00 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-11-11 17:42:25 -0500
commit27d59a4a2def42307349079f2e3538d96934c379 (patch)
treed581f0960d280dbe0f8c8ee03e111cadbfcf59db /arch/arm/mach-omap2/pm34xx.c
parentf2d1185824fd3ed631f3164daeff59d0b4e55d79 (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.c43
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
64static void (*_omap_sram_idle)(u32 *addr, int save_state); 64static void (*_omap_sram_idle)(u32 *addr, int save_state);
65 65
66static int (*_omap_save_secure_sram)(u32 *addr);
67
66static struct powerdomain *mpu_pwrdm, *neon_pwrdm; 68static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
67static struct powerdomain *core_pwrdm, *per_pwrdm; 69static 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
115static 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
906static int __init omap3_pm_init(void) 939static 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
964err1: 1005err1:
965 return ret; 1006 return ret;
966err2: 1007err2: