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