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