aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/control.c8
-rw-r--r--arch/arm/mach-omap2/pm.h3
-rw-r--r--arch/arm/mach-omap2/pm34xx.c43
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S75
4 files changed, 126 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 3ea417d7a1b5..b84cff7087b0 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -85,6 +85,8 @@ struct omap3_scratchpad_sdrc_block {
85 u32 block_size; 85 u32 block_size;
86}; 86};
87 87
88void *omap3_secure_ram_storage;
89
88/* 90/*
89 * This is used to store ARM registers in SDRAM before attempting 91 * This is used to store ARM registers in SDRAM before attempting
90 * an MPU OFF. The save and restore happens from the SRAM sleep code. 92 * an MPU OFF. The save and restore happens from the SRAM sleep code.
@@ -209,7 +211,11 @@ void omap3_save_scratchpad_contents(void)
209 scratchpad_contents.boot_config_ptr = 0x0; 211 scratchpad_contents.boot_config_ptr = 0x0;
210 scratchpad_contents.public_restore_ptr = 212 scratchpad_contents.public_restore_ptr =
211 virt_to_phys(get_restore_pointer()); 213 virt_to_phys(get_restore_pointer());
212 scratchpad_contents.secure_ram_restore_ptr = 0x0; 214 if (omap_type() == OMAP2_DEVICE_TYPE_GP)
215 scratchpad_contents.secure_ram_restore_ptr = 0x0;
216 else
217 scratchpad_contents.secure_ram_restore_ptr =
218 (u32) __pa(omap3_secure_ram_storage);
213 scratchpad_contents.sdrc_module_semaphore = 0x0; 219 scratchpad_contents.sdrc_module_semaphore = 0x0;
214 scratchpad_contents.prcm_block_offset = 0x2C; 220 scratchpad_contents.prcm_block_offset = 0x2C;
215 scratchpad_contents.sdrc_block_offset = 0x64; 221 scratchpad_contents.sdrc_block_offset = 0x64;
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 85b6face5392..45cafac716d1 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -13,6 +13,8 @@
13 13
14#include <plat/powerdomain.h> 14#include <plat/powerdomain.h>
15 15
16extern void *omap3_secure_ram_storage;
17
16extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); 18extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
17extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); 19extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
18 20
@@ -36,6 +38,7 @@ extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
36 void __iomem *sdrc_power); 38 void __iomem *sdrc_power);
37extern void omap34xx_cpu_suspend(u32 *addr, int save_state); 39extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
38extern void save_secure_ram_context(u32 *addr); 40extern void save_secure_ram_context(u32 *addr);
41extern void omap3_save_scratchpad_contents(void);
39 42
40extern unsigned int omap24xx_idle_loop_suspend_sz; 43extern unsigned int omap24xx_idle_loop_suspend_sz;
41extern unsigned int omap34xx_suspend_sz; 44extern unsigned int omap34xx_suspend_sz;
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:
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index f8d3834bf681..db75167bc52d 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -37,6 +37,8 @@
37#define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \ 37#define PM_PREPWSTST_MPU_V OMAP34XX_PRM_REGADDR(MPU_MOD, \
38 OMAP3430_PM_PREPWSTST) 38 OMAP3430_PM_PREPWSTST)
39#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL 39#define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
40#define SRAM_BASE_P 0x40200000
41#define CONTROL_STAT 0x480022F0
40#define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is 42#define SCRATCHPAD_MEM_OFFS 0x310 /* Move this as correct place is
41 * available */ 43 * available */
42#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\ 44#define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\
@@ -51,6 +53,40 @@ ENTRY(get_restore_pointer)
51 ldmfd sp!, {pc} @ restore regs and return 53 ldmfd sp!, {pc} @ restore regs and return
52ENTRY(get_restore_pointer_sz) 54ENTRY(get_restore_pointer_sz)
53 .word . - get_restore_pointer_sz 55 .word . - get_restore_pointer_sz
56
57/* Function to call rom code to save secure ram context */
58ENTRY(save_secure_ram_context)
59 stmfd sp!, {r1-r12, lr} @ save registers on stack
60save_secure_ram_debug:
61 /* b save_secure_ram_debug */ @ enable to debug save code
62 adr r3, api_params @ r3 points to parameters
63 str r0, [r3,#0x4] @ r0 has sdram address
64 ldr r12, high_mask
65 and r3, r3, r12
66 ldr r12, sram_phy_addr_mask
67 orr r3, r3, r12
68 mov r0, #25 @ set service ID for PPA
69 mov r12, r0 @ copy secure service ID in r12
70 mov r1, #0 @ set task id for ROM code in r1
71 mov r2, #7 @ set some flags in r2, r6
72 mov r6, #0xff
73 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
74 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
75 .word 0xE1600071 @ call SMI monitor (smi #1)
76 nop
77 nop
78 nop
79 nop
80 ldmfd sp!, {r1-r12, pc}
81sram_phy_addr_mask:
82 .word SRAM_BASE_P
83high_mask:
84 .word 0xffff
85api_params:
86 .word 0x4, 0x0, 0x0, 0x1, 0x1
87ENTRY(save_secure_ram_context_sz)
88 .word . - save_secure_ram_context
89
54/* 90/*
55 * Forces OMAP into idle state 91 * Forces OMAP into idle state
56 * 92 *
@@ -107,9 +143,44 @@ restore:
107 moveq r9, #0x3 @ MPU OFF => L1 and L2 lost 143 moveq r9, #0x3 @ MPU OFF => L1 and L2 lost
108 movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation 144 movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation
109 bne logic_l1_restore 145 bne logic_l1_restore
146 ldr r0, control_stat
147 ldr r1, [r0]
148 and r1, #0x700
149 cmp r1, #0x300
150 beq l2_inv_gp
151 mov r0, #40 @ set service ID for PPA
152 mov r12, r0 @ copy secure Service ID in r12
153 mov r1, #0 @ set task id for ROM code in r1
154 mov r2, #4 @ set some flags in r2, r6
155 mov r6, #0xff
156 adr r3, l2_inv_api_params @ r3 points to dummy parameters
157 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
158 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
159 .word 0xE1600071 @ call SMI monitor (smi #1)
160 /* Write to Aux control register to set some bits */
161 mov r0, #42 @ set service ID for PPA
162 mov r12, r0 @ copy secure Service ID in r12
163 mov r1, #0 @ set task id for ROM code in r1
164 mov r2, #4 @ set some flags in r2, r6
165 mov r6, #0xff
166 adr r3, write_aux_control_params @ r3 points to parameters
167 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
168 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
169 .word 0xE1600071 @ call SMI monitor (smi #1)
170
171 b logic_l1_restore
172l2_inv_api_params:
173 .word 0x1, 0x00
174write_aux_control_params:
175 .word 0x1, 0x72
176l2_inv_gp:
110 /* Execute smi to invalidate L2 cache */ 177 /* Execute smi to invalidate L2 cache */
111 mov r12, #0x1 @ set up to invalide L2 178 mov r12, #0x1 @ set up to invalide L2
112smi: .word 0xE1600070 @ Call SMI monitor (smieq) 179smi: .word 0xE1600070 @ Call SMI monitor (smieq)
180 /* Write to Aux control register to set some bits */
181 mov r0, #0x72
182 mov r12, #0x3
183 .word 0xE1600070 @ Call SMI monitor (smieq)
113logic_l1_restore: 184logic_l1_restore:
114 mov r1, #0 185 mov r1, #0
115 /* Invalidate all instruction caches to PoU 186 /* Invalidate all instruction caches to PoU
@@ -429,5 +500,7 @@ table_entry:
429 .word 0x00000C02 500 .word 0x00000C02
430cache_pred_disable_mask: 501cache_pred_disable_mask:
431 .word 0xFFFFE7FB 502 .word 0xFFFFE7FB
503control_stat:
504 .word CONTROL_STAT
432ENTRY(omap34xx_cpu_suspend_sz) 505ENTRY(omap34xx_cpu_suspend_sz)
433 .word . - omap34xx_cpu_suspend 506 .word . - omap34xx_cpu_suspend