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