1/* 2 * OMAP44xx sleep code. 3 * 4 * Copyright (C) 2011 Texas Instruments, Inc. 5 * Santosh Shilimkar <santosh.shilimkar@ti.com> 6 * 7 * This program is free software,you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12#include <linux/linkage.h> 13#include <asm/smp_scu.h> 14#include <asm/memory.h> 15#include <asm/hardware/cache-l2x0.h> 16 17#include "omap-secure.h" 18 19#include "common.h" 20#include "omap44xx.h" 21#include "omap4-sar-layout.h" 22 23#if defined(CONFIG_SMP) && defined(CONFIG_PM) 24 25.macro DO_SMC 26 dsb 27 smc #0 28 dsb 29.endm 30 31ppa_zero_params: 32 .word 0x0 33 34ppa_por_params: 35 .word 1, 0 36 37#ifdef CONFIG_ARCH_OMAP4 38 39/* 40 * ============================= 41 * == CPU suspend finisher == 42 * ============================= 43 * 44 * void omap4_finish_suspend(unsigned long cpu_state) 45 * 46 * This function code saves the CPU context and performs the CPU 47 * power down sequence. Calling WFI effectively changes the CPU 48 * power domains states to the desired target power state. 49 * 50 * @cpu_state : contains context save state (r0) 51 * 0 - No context lost 52 * 1 - CPUx L1 and logic lost: MPUSS CSWR 53 * 2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR 54 * 3 - CPUx L1 and logic lost + GIC + L2 lost: MPUSS OFF 55 * @return: This function never returns for CPU OFF and DORMANT power states. 56 * Post WFI, CPU transitions to DORMANT or OFF power state and on wake-up 57 * from this follows a full CPU reset path via ROM code to CPU restore code. 58 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. 59 * It returns to the caller for CPU INACTIVE and ON power states or in case 60 * CPU failed to transition to targeted OFF/DORMANT state. 61 * 62 * omap4_finish_suspend() calls v7_flush_dcache_all() which doesn't save 63 * stack frame and it expects the caller to take care of it. Hence the entire 64 * stack frame is saved to avoid possible stack corruption. 65 */ 66ENTRY(omap4_finish_suspend) 67 stmfd sp!, {r4-r12, lr} 68 cmp r0, #0x0 69 beq do_WFI @ No lowpower state, jump to WFI 70 71 /* 72 * Flush all data from the L1 data cache before disabling 73 * SCTLR.C bit. 74 */ 75 bl omap4_get_sar_ram_base 76 ldr r9, [r0, #OMAP_TYPE_OFFSET] 77 cmp r9, #0x1 @ Check for HS device 78 bne skip_secure_l1_clean 79 mov r0, #SCU_PM_NORMAL 80 mov r1, #0xFF @ clean seucre L1 81 stmfd r13!, {r4-r12, r14} 82 ldr r12, =OMAP4_MON_SCU_PWR_INDEX 83 DO_SMC 84 ldmfd r13!, {r4-r12, r14} 85skip_secure_l1_clean: 86 bl v7_flush_dcache_all 87 88 /* 89 * Clear the SCTLR.C bit to prevent further data cache 90 * allocation. Clearing SCTLR.C would make all the data accesses 91 * strongly ordered and would not hit the cache. 92 */ 93 mrc p15, 0, r0, c1, c0, 0 94 bic r0, r0, #(1 << 2) @ Disable the C bit 95 mcr p15, 0, r0, c1, c0, 0 96 isb 97 98 /* 99 * Invalidate L1 data cache. Even though only invalidate is 100 * necessary exported flush API is used here. Doing clean 101 * on already clean cache would be almost NOP. 102 */ 103 bl v7_flush_dcache_all 104 105 /* 106 * Switch the CPU from Symmetric Multiprocessing (SMP) mode 107 * to AsymmetricMultiprocessing (AMP) mode by programming 108 * the SCU power status to DORMANT or OFF mode. 109 * This enables the CPU to be taken out of coherency by 110 * preventing the CPU from receiving cache, TLB, or BTB 111 * maintenance operations broadcast by other CPUs in the cluster. 112 */ 113 bl omap4_get_sar_ram_base 114 mov r8, r0 115 ldr r9, [r8, #OMAP_TYPE_OFFSET] 116 cmp r9, #0x1 @ Check for HS device 117 bne scu_gp_set 118 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR 119 ands r0, r0, #0x0f 120 ldreq r0, [r8, #SCU_OFFSET0] 121 ldrne r0, [r8, #SCU_OFFSET1] 122 mov r1, #0x00 123 stmfd r13!, {r4-r12, r14} 124 ldr r12, =OMAP4_MON_SCU_PWR_INDEX 125 DO_SMC 126 ldmfd r13!, {r4-r12, r14} 127 b skip_scu_gp_set 128scu_gp_set: 129 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR 130 ands r0, r0, #0x0f 131 ldreq r1, [r8, #SCU_OFFSET0] 132 ldrne r1, [r8, #SCU_OFFSET1] 133 bl omap4_get_scu_base 134 bl scu_power_mode 135skip_scu_gp_set: 136 mrc p15, 0, r0, c1, c1, 2 @ Read NSACR data 137 tst r0, #(1 << 18) 138 mrcne p15, 0, r0, c1, c0, 1 139 bicne r0, r0, #(1 << 6) @ Disable SMP bit 140 mcrne p15, 0, r0, c1, c0, 1 141 isb 142 dsb 143#ifdef CONFIG_CACHE_L2X0 144 /* 145 * Clean and invalidate the L2 cache. 146 * Common cache-l2x0.c functions can't be used here since it 147 * uses spinlocks. We are out of coherency here with data cache 148 * disabled. The spinlock implementation uses exclusive load/store 149 * instruction which can fail without data cache being enabled. 150 * OMAP4 hardware doesn't support exclusive monitor which can 151 * overcome exclusive access issue. Because of this, CPU can 152 * lead to deadlock. 153 */ 154 bl omap4_get_sar_ram_base 155 mov r8, r0 156 mrc p15, 0, r5, c0, c0, 5 @ Read MPIDR 157 ands r5, r5, #0x0f 158 ldreq r0, [r8, #L2X0_SAVE_OFFSET0] @ Retrieve L2 state from SAR 159 ldrne r0, [r8, #L2X0_SAVE_OFFSET1] @ memory. 160 cmp r0, #3 161 bne do_WFI 162#ifdef CONFIG_PL310_ERRATA_727915 163 mov r0, #0x03 164 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX 165 DO_SMC 166#endif 167 bl omap4_get_l2cache_base 168 mov r2, r0 169 ldr r0, =0xffff 170 str r0, [r2, #L2X0_CLEAN_INV_WAY] 171wait: 172 ldr r0, [r2, #L2X0_CLEAN_INV_WAY] 173 ldr r1, =0xffff 174 ands r0, r0, r1 175 bne wait 176#ifdef CONFIG_PL310_ERRATA_727915 177 mov r0, #0x00 178 mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX 179 DO_SMC 180#endif 181l2x_sync: 182 bl omap4_get_l2cache_base 183 mov r2, r0 184 mov r0, #0x0 185 str r0, [r2, #L2X0_CACHE_SYNC] 186sync: 187 ldr r0, [r2, #L2X0_CACHE_SYNC] 188 ands r0, r0, #0x1 189 bne sync 190#endif 191 192do_WFI: 193 bl omap_do_wfi 194 195 /* 196 * CPU is here when it failed to enter OFF/DORMANT or 197 * no low power state was attempted. 198 */ 199 mrc p15, 0, r0, c1, c0, 0 200 tst r0, #(1 << 2) @ Check C bit enabled? 201 orreq r0, r0, #(1 << 2) @ Enable the C bit 202 mcreq p15, 0, r0, c1, c0, 0 203 isb 204 205 /* 206 * Ensure the CPU power state is set to NORMAL in 207 * SCU power state so that CPU is back in coherency. 208 * In non-coherent mode CPU can lock-up and lead to 209 * system deadlock. 210 */ 211 mrc p15, 0, r0, c1, c0, 1 212 tst r0, #(1 << 6) @ Check SMP bit enabled? 213 orreq r0, r0, #(1 << 6) 214 mcreq p15, 0, r0, c1, c0, 1 215 isb 216 bl omap4_get_sar_ram_base 217 mov r8, r0 218 ldr r9, [r8, #OMAP_TYPE_OFFSET] 219 cmp r9, #0x1 @ Check for HS device 220 bne scu_gp_clear 221 mov r0, #SCU_PM_NORMAL 222 mov r1, #0x00 223 stmfd r13!, {r4-r12, r14} 224 ldr r12, =OMAP4_MON_SCU_PWR_INDEX 225 DO_SMC 226 ldmfd r13!, {r4-r12, r14} 227 b skip_scu_gp_clear 228scu_gp_clear: 229 bl omap4_get_scu_base 230 mov r1, #SCU_PM_NORMAL 231 bl scu_power_mode 232skip_scu_gp_clear: 233 isb 234 dsb 235 ldmfd sp!, {r4-r12, pc} 236ENDPROC(omap4_finish_suspend) 237 238/* 239 * ============================ 240 * == CPU resume entry point == 241 * ============================ 242 * 243 * void omap4_cpu_resume(void) 244 * 245 * ROM code jumps to this function while waking up from CPU 246 * OFF or DORMANT state. Physical address of the function is 247 * stored in the SAR RAM while entering to OFF or DORMANT mode. 248 * The restore function pointer is stored at CPUx_WAKEUP_NS_PA_ADDR_OFFSET. 249 */ 250ENTRY(omap4_cpu_resume) 251 /* 252 * Configure ACTRL and enable NS SMP bit access on CPU1 on HS device. 253 * OMAP44XX EMU/HS devices - CPU0 SMP bit access is enabled in PPA 254 * init and for CPU1, a secure PPA API provided. CPU0 must be ON 255 * while executing NS_SMP API on CPU1 and PPA version must be 1.4.0+. 256 * OMAP443X GP devices- SMP bit isn't accessible. 257 * OMAP446X GP devices - SMP bit access is enabled on both CPUs. 258 */ 259 ldr r8, =OMAP44XX_SAR_RAM_BASE 260 ldr r9, [r8, #OMAP_TYPE_OFFSET] 261 cmp r9, #0x1 @ Skip if GP device 262 bne skip_ns_smp_enable 263 mrc p15, 0, r0, c0, c0, 5 264 ands r0, r0, #0x0f 265 beq skip_ns_smp_enable 266ppa_actrl_retry: 267 mov r0, #OMAP4_PPA_CPU_ACTRL_SMP_INDEX 268 adr r3, ppa_zero_params @ Pointer to parameters 269 mov r1, #0x0 @ Process ID 270 mov r2, #0x4 @ Flag 271 mov r6, #0xff 272 mov r12, #0x00 @ Secure Service ID 273 DO_SMC 274 cmp r0, #0x0 @ API returns 0 on success. 275 beq enable_smp_bit 276 b ppa_actrl_retry 277enable_smp_bit: 278 mrc p15, 0, r0, c1, c0, 1 279 tst r0, #(1 << 6) @ Check SMP bit enabled? 280 orreq r0, r0, #(1 << 6) 281 mcreq p15, 0, r0, c1, c0, 1 282 isb 283skip_ns_smp_enable: 284#ifdef CONFIG_CACHE_L2X0 285 /* 286 * Restore the L2 AUXCTRL and enable the L2 cache. 287 * OMAP4_MON_L2X0_AUXCTRL_INDEX = Program the L2X0 AUXCTRL 288 * OMAP4_MON_L2X0_CTRL_INDEX = Enable the L2 using L2X0 CTRL 289 * register r0 contains value to be programmed. 290 * L2 cache is already invalidate by ROM code as part 291 * of MPUSS OFF wakeup path. 292 */ 293 ldr r2, =OMAP44XX_L2CACHE_BASE 294 ldr r0, [r2, #L2X0_CTRL] 295 and r0, #0x0f 296 cmp r0, #1 297 beq skip_l2en @ Skip if already enabled 298 ldr r3, =OMAP44XX_SAR_RAM_BASE 299 ldr r1, [r3, #OMAP_TYPE_OFFSET] 300 cmp r1, #0x1 @ Check for HS device 301 bne set_gp_por 302 ldr r0, =OMAP4_PPA_L2_POR_INDEX 303 ldr r1, =OMAP44XX_SAR_RAM_BASE 304 ldr r4, [r1, #L2X0_PREFETCH_CTRL_OFFSET] 305 adr r3, ppa_por_params 306 str r4, [r3, #0x04] 307 mov r1, #0x0 @ Process ID 308 mov r2, #0x4 @ Flag 309 mov r6, #0xff 310 mov r12, #0x00 @ Secure Service ID 311 DO_SMC 312 b set_aux_ctrl 313set_gp_por: 314 ldr r1, =OMAP44XX_SAR_RAM_BASE 315 ldr r0, [r1, #L2X0_PREFETCH_CTRL_OFFSET] 316 ldr r12, =OMAP4_MON_L2X0_PREFETCH_INDEX @ Setup L2 PREFETCH 317 DO_SMC 318set_aux_ctrl: 319 ldr r1, =OMAP44XX_SAR_RAM_BASE 320 ldr r0, [r1, #L2X0_AUXCTRL_OFFSET] 321 ldr r12, =OMAP4_MON_L2X0_AUXCTRL_INDEX @ Setup L2 AUXCTRL 322 DO_SMC 323 mov r0, #0x1 324 ldr r12, =OMAP4_MON_L2X0_CTRL_INDEX @ Enable L2 cache 325 DO_SMC 326skip_l2en: 327#endif 328 329 b cpu_resume @ Jump to generic resume 330ENDPROC(omap4_cpu_resume) 331#endif /* CONFIG_ARCH_OMAP4 */ 332 333#endif /* defined(CONFIG_SMP) && defined(CONFIG_PM) */ 334 335#ifndef CONFIG_OMAP4_ERRATA_I688 336ENTRY(omap_bus_sync) 337 mov pc, lr 338ENDPROC(omap_bus_sync) 339#endif 340 341ENTRY(omap_do_wfi) 342 stmfd sp!, {lr} 343 /* Drain interconnect write buffers. */ 344 bl omap_bus_sync 345 346 /* 347 * Execute an ISB instruction to ensure that all of the 348 * CP15 register changes have been committed. 349 */ 350 isb 351 352 /* 353 * Execute a barrier instruction to ensure that all cache, 354 * TLB and branch predictor maintenance operations issued 355 * by any CPU in the cluster have completed. 356 */ 357 dsb 358 dmb 359 360 /* 361 * Execute a WFI instruction and wait until the 362 * STANDBYWFI output is asserted to indicate that the 363 * CPU is in idle and low power state. CPU can specualatively 364 * prefetch the instructions so add NOPs after WFI. Sixteen 365 * NOPs as per Cortex-A9 pipeline. 366 */ 367 wfi @ Wait For Interrupt 368 nop 369 nop 370 nop 371 nop 372 nop 373 nop 374 nop 375 nop 376 nop 377 nop 378 nop 379 nop 380 nop 381 nop 382 nop 383 nop 384 385 ldmfd sp!, {pc} 386ENDPROC(omap_do_wfi) 387