1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * linux/arch/arm/mach-omap1/sleep.S 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Low-level OMAP7XX/1510/1610 sleep/wakeUp support 5*4882a593Smuzhiyun * 6*4882a593Smuzhiyun * Initial SA1110 code: 7*4882a593Smuzhiyun * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * Adapted for PXA by Nicolas Pitre: 10*4882a593Smuzhiyun * Copyright (c) 2002 Monta Vista Software, Inc. 11*4882a593Smuzhiyun * 12*4882a593Smuzhiyun * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> 13*4882a593Smuzhiyun * 14*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify it 15*4882a593Smuzhiyun * under the terms of the GNU General Public License as published by the 16*4882a593Smuzhiyun * Free Software Foundation; either version 2 of the License, or (at your 17*4882a593Smuzhiyun * option) any later version. 18*4882a593Smuzhiyun * 19*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 20*4882a593Smuzhiyun * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21*4882a593Smuzhiyun * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 22*4882a593Smuzhiyun * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23*4882a593Smuzhiyun * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24*4882a593Smuzhiyun * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 25*4882a593Smuzhiyun * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26*4882a593Smuzhiyun * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27*4882a593Smuzhiyun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28*4882a593Smuzhiyun * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29*4882a593Smuzhiyun * 30*4882a593Smuzhiyun * You should have received a copy of the GNU General Public License along 31*4882a593Smuzhiyun * with this program; if not, write to the Free Software Foundation, Inc., 32*4882a593Smuzhiyun * 675 Mass Ave, Cambridge, MA 02139, USA. 33*4882a593Smuzhiyun */ 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun#include <linux/linkage.h> 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun#include <asm/assembler.h> 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun#include <mach/hardware.h> 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun#include "iomap.h" 42*4882a593Smuzhiyun#include "pm.h" 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun .text 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun/* 48*4882a593Smuzhiyun * Forces OMAP into deep sleep state 49*4882a593Smuzhiyun * 50*4882a593Smuzhiyun * omapXXXX_cpu_suspend() 51*4882a593Smuzhiyun * 52*4882a593Smuzhiyun * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed 53*4882a593Smuzhiyun * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1 54*4882a593Smuzhiyun * in register r1. 55*4882a593Smuzhiyun * 56*4882a593Smuzhiyun * Note: This code get's copied to internal SRAM at boot. When the OMAP 57*4882a593Smuzhiyun * wakes up it continues execution at the point it went to sleep. 58*4882a593Smuzhiyun * 59*4882a593Smuzhiyun * Note: Because of errata work arounds we have processor specific functions 60*4882a593Smuzhiyun * here. They are mostly the same, but slightly different. 61*4882a593Smuzhiyun * 62*4882a593Smuzhiyun */ 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) 65*4882a593Smuzhiyun .align 3 66*4882a593SmuzhiyunENTRY(omap7xx_cpu_suspend) 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun @ save registers on stack 69*4882a593Smuzhiyun stmfd sp!, {r0 - r12, lr} 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun @ Drain write cache 72*4882a593Smuzhiyun mov r4, #0 73*4882a593Smuzhiyun mcr p15, 0, r0, c7, c10, 4 74*4882a593Smuzhiyun nop 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun @ load base address of Traffic Controller 77*4882a593Smuzhiyun mov r6, #TCMIF_ASM_BASE & 0xff000000 78*4882a593Smuzhiyun orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 79*4882a593Smuzhiyun orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun @ prepare to put SDRAM into self-refresh manually 82*4882a593Smuzhiyun ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 83*4882a593Smuzhiyun orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 84*4882a593Smuzhiyun orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff 85*4882a593Smuzhiyun str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun @ prepare to put EMIFS to Sleep 88*4882a593Smuzhiyun ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 89*4882a593Smuzhiyun orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff 90*4882a593Smuzhiyun str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun @ load base address of ARM_IDLECT1 and ARM_IDLECT2 93*4882a593Smuzhiyun mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 94*4882a593Smuzhiyun orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 95*4882a593Smuzhiyun orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun @ turn off clock domains 98*4882a593Smuzhiyun @ do not disable PERCK (0x04) 99*4882a593Smuzhiyun mov r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff 100*4882a593Smuzhiyun orr r5, r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff00 101*4882a593Smuzhiyun strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun @ request ARM idle 104*4882a593Smuzhiyun mov r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff 105*4882a593Smuzhiyun orr r3, r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff00 106*4882a593Smuzhiyun strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 107*4882a593Smuzhiyun 108*4882a593Smuzhiyun @ disable instruction cache 109*4882a593Smuzhiyun mrc p15, 0, r9, c1, c0, 0 110*4882a593Smuzhiyun bic r2, r9, #0x1000 111*4882a593Smuzhiyun mcr p15, 0, r2, c1, c0, 0 112*4882a593Smuzhiyun nop 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun/* 115*4882a593Smuzhiyun * Let's wait for the next wake up event to wake us up. r0 can't be 116*4882a593Smuzhiyun * used here because r0 holds ARM_IDLECT1 117*4882a593Smuzhiyun */ 118*4882a593Smuzhiyun mov r2, #0 119*4882a593Smuzhiyun mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt 120*4882a593Smuzhiyun/* 121*4882a593Smuzhiyun * omap7xx_cpu_suspend()'s resume point. 122*4882a593Smuzhiyun * 123*4882a593Smuzhiyun * It will just start executing here, so we'll restore stuff from the 124*4882a593Smuzhiyun * stack. 125*4882a593Smuzhiyun */ 126*4882a593Smuzhiyun @ re-enable Icache 127*4882a593Smuzhiyun mcr p15, 0, r9, c1, c0, 0 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun @ reset the ARM_IDLECT1 and ARM_IDLECT2. 130*4882a593Smuzhiyun strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 131*4882a593Smuzhiyun strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun @ Restore EMIFF controls 134*4882a593Smuzhiyun str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 135*4882a593Smuzhiyun str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun @ restore regs and return 138*4882a593Smuzhiyun ldmfd sp!, {r0 - r12, pc} 139*4882a593Smuzhiyun 140*4882a593SmuzhiyunENTRY(omap7xx_cpu_suspend_sz) 141*4882a593Smuzhiyun .word . - omap7xx_cpu_suspend 142*4882a593Smuzhiyun#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */ 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun#ifdef CONFIG_ARCH_OMAP15XX 145*4882a593Smuzhiyun .align 3 146*4882a593SmuzhiyunENTRY(omap1510_cpu_suspend) 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun @ save registers on stack 149*4882a593Smuzhiyun stmfd sp!, {r0 - r12, lr} 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun @ load base address of Traffic Controller 152*4882a593Smuzhiyun mov r4, #TCMIF_ASM_BASE & 0xff000000 153*4882a593Smuzhiyun orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000 154*4882a593Smuzhiyun orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun @ work around errata of OMAP1510 PDE bit for TC shut down 157*4882a593Smuzhiyun @ clear PDE bit 158*4882a593Smuzhiyun ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 159*4882a593Smuzhiyun bic r5, r5, #PDE_BIT & 0xff 160*4882a593Smuzhiyun str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun @ set PWD_EN bit 163*4882a593Smuzhiyun and r5, r5, #PWD_EN_BIT & 0xff 164*4882a593Smuzhiyun str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun @ prepare to put SDRAM into self-refresh manually 167*4882a593Smuzhiyun ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 168*4882a593Smuzhiyun orr r5, r5, #SELF_REFRESH_MODE & 0xff000000 169*4882a593Smuzhiyun orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff 170*4882a593Smuzhiyun str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun @ prepare to put EMIFS to Sleep 173*4882a593Smuzhiyun ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 174*4882a593Smuzhiyun orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff 175*4882a593Smuzhiyun str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun @ load base address of ARM_IDLECT1 and ARM_IDLECT2 178*4882a593Smuzhiyun mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 179*4882a593Smuzhiyun orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 180*4882a593Smuzhiyun orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun @ turn off clock domains 183*4882a593Smuzhiyun mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff 184*4882a593Smuzhiyun orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 185*4882a593Smuzhiyun strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun @ request ARM idle 188*4882a593Smuzhiyun mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff 189*4882a593Smuzhiyun orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00 190*4882a593Smuzhiyun strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun mov r5, #IDLE_WAIT_CYCLES & 0xff 193*4882a593Smuzhiyun orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 194*4882a593Smuzhiyunl_1510_2: 195*4882a593Smuzhiyun subs r5, r5, #1 196*4882a593Smuzhiyun bne l_1510_2 197*4882a593Smuzhiyun/* 198*4882a593Smuzhiyun * Let's wait for the next wake up event to wake us up. r0 can't be 199*4882a593Smuzhiyun * used here because r0 holds ARM_IDLECT1 200*4882a593Smuzhiyun */ 201*4882a593Smuzhiyun mov r2, #0 202*4882a593Smuzhiyun mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt 203*4882a593Smuzhiyun/* 204*4882a593Smuzhiyun * omap1510_cpu_suspend()'s resume point. 205*4882a593Smuzhiyun * 206*4882a593Smuzhiyun * It will just start executing here, so we'll restore stuff from the 207*4882a593Smuzhiyun * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. 208*4882a593Smuzhiyun */ 209*4882a593Smuzhiyun strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 210*4882a593Smuzhiyun strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun @ restore regs and return 213*4882a593Smuzhiyun ldmfd sp!, {r0 - r12, pc} 214*4882a593Smuzhiyun 215*4882a593SmuzhiyunENTRY(omap1510_cpu_suspend_sz) 216*4882a593Smuzhiyun .word . - omap1510_cpu_suspend 217*4882a593Smuzhiyun#endif /* CONFIG_ARCH_OMAP15XX */ 218*4882a593Smuzhiyun 219*4882a593Smuzhiyun#if defined(CONFIG_ARCH_OMAP16XX) 220*4882a593Smuzhiyun .align 3 221*4882a593SmuzhiyunENTRY(omap1610_cpu_suspend) 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun @ save registers on stack 224*4882a593Smuzhiyun stmfd sp!, {r0 - r12, lr} 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun @ Drain write cache 227*4882a593Smuzhiyun mov r4, #0 228*4882a593Smuzhiyun mcr p15, 0, r0, c7, c10, 4 229*4882a593Smuzhiyun nop 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun @ Load base address of Traffic Controller 232*4882a593Smuzhiyun mov r6, #TCMIF_ASM_BASE & 0xff000000 233*4882a593Smuzhiyun orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 234*4882a593Smuzhiyun orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun @ Prepare to put SDRAM into self-refresh manually 237*4882a593Smuzhiyun ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 238*4882a593Smuzhiyun orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 239*4882a593Smuzhiyun orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff 240*4882a593Smuzhiyun str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 241*4882a593Smuzhiyun 242*4882a593Smuzhiyun @ Prepare to put EMIFS to Sleep 243*4882a593Smuzhiyun ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 244*4882a593Smuzhiyun orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff 245*4882a593Smuzhiyun str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun @ Load base address of ARM_IDLECT1 and ARM_IDLECT2 248*4882a593Smuzhiyun mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 249*4882a593Smuzhiyun orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 250*4882a593Smuzhiyun orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 251*4882a593Smuzhiyun 252*4882a593Smuzhiyun @ Turn off clock domains 253*4882a593Smuzhiyun @ Do not disable PERCK (0x04) 254*4882a593Smuzhiyun mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff 255*4882a593Smuzhiyun orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 256*4882a593Smuzhiyun strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 257*4882a593Smuzhiyun 258*4882a593Smuzhiyun @ Request ARM idle 259*4882a593Smuzhiyun mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff 260*4882a593Smuzhiyun orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00 261*4882a593Smuzhiyun strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun/* 264*4882a593Smuzhiyun * Let's wait for the next wake up event to wake us up. r0 can't be 265*4882a593Smuzhiyun * used here because r0 holds ARM_IDLECT1 266*4882a593Smuzhiyun */ 267*4882a593Smuzhiyun mov r2, #0 268*4882a593Smuzhiyun mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt 269*4882a593Smuzhiyun 270*4882a593Smuzhiyun @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions 271*4882a593Smuzhiyun @ according to this formula: 272*4882a593Smuzhiyun @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV 273*4882a593Smuzhiyun @ Max DPLL_MULT = 18 274*4882a593Smuzhiyun @ DPLL_DIV = 1 275*4882a593Smuzhiyun @ ARMDIV = 1 276*4882a593Smuzhiyun @ => 74 nop-instructions 277*4882a593Smuzhiyun nop 278*4882a593Smuzhiyun nop 279*4882a593Smuzhiyun nop 280*4882a593Smuzhiyun nop 281*4882a593Smuzhiyun nop 282*4882a593Smuzhiyun nop 283*4882a593Smuzhiyun nop 284*4882a593Smuzhiyun nop 285*4882a593Smuzhiyun nop 286*4882a593Smuzhiyun nop @10 287*4882a593Smuzhiyun nop 288*4882a593Smuzhiyun nop 289*4882a593Smuzhiyun nop 290*4882a593Smuzhiyun nop 291*4882a593Smuzhiyun nop 292*4882a593Smuzhiyun nop 293*4882a593Smuzhiyun nop 294*4882a593Smuzhiyun nop 295*4882a593Smuzhiyun nop 296*4882a593Smuzhiyun nop @20 297*4882a593Smuzhiyun nop 298*4882a593Smuzhiyun nop 299*4882a593Smuzhiyun nop 300*4882a593Smuzhiyun nop 301*4882a593Smuzhiyun nop 302*4882a593Smuzhiyun nop 303*4882a593Smuzhiyun nop 304*4882a593Smuzhiyun nop 305*4882a593Smuzhiyun nop 306*4882a593Smuzhiyun nop @30 307*4882a593Smuzhiyun nop 308*4882a593Smuzhiyun nop 309*4882a593Smuzhiyun nop 310*4882a593Smuzhiyun nop 311*4882a593Smuzhiyun nop 312*4882a593Smuzhiyun nop 313*4882a593Smuzhiyun nop 314*4882a593Smuzhiyun nop 315*4882a593Smuzhiyun nop 316*4882a593Smuzhiyun nop @40 317*4882a593Smuzhiyun nop 318*4882a593Smuzhiyun nop 319*4882a593Smuzhiyun nop 320*4882a593Smuzhiyun nop 321*4882a593Smuzhiyun nop 322*4882a593Smuzhiyun nop 323*4882a593Smuzhiyun nop 324*4882a593Smuzhiyun nop 325*4882a593Smuzhiyun nop 326*4882a593Smuzhiyun nop @50 327*4882a593Smuzhiyun nop 328*4882a593Smuzhiyun nop 329*4882a593Smuzhiyun nop 330*4882a593Smuzhiyun nop 331*4882a593Smuzhiyun nop 332*4882a593Smuzhiyun nop 333*4882a593Smuzhiyun nop 334*4882a593Smuzhiyun nop 335*4882a593Smuzhiyun nop 336*4882a593Smuzhiyun nop @60 337*4882a593Smuzhiyun nop 338*4882a593Smuzhiyun nop 339*4882a593Smuzhiyun nop 340*4882a593Smuzhiyun nop 341*4882a593Smuzhiyun nop 342*4882a593Smuzhiyun nop 343*4882a593Smuzhiyun nop 344*4882a593Smuzhiyun nop 345*4882a593Smuzhiyun nop 346*4882a593Smuzhiyun nop @70 347*4882a593Smuzhiyun nop 348*4882a593Smuzhiyun nop 349*4882a593Smuzhiyun nop 350*4882a593Smuzhiyun nop @74 351*4882a593Smuzhiyun/* 352*4882a593Smuzhiyun * omap1610_cpu_suspend()'s resume point. 353*4882a593Smuzhiyun * 354*4882a593Smuzhiyun * It will just start executing here, so we'll restore stuff from the 355*4882a593Smuzhiyun * stack. 356*4882a593Smuzhiyun */ 357*4882a593Smuzhiyun @ Restore the ARM_IDLECT1 and ARM_IDLECT2. 358*4882a593Smuzhiyun strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] 359*4882a593Smuzhiyun strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] 360*4882a593Smuzhiyun 361*4882a593Smuzhiyun @ Restore EMIFF controls 362*4882a593Smuzhiyun str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] 363*4882a593Smuzhiyun str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] 364*4882a593Smuzhiyun 365*4882a593Smuzhiyun @ Restore regs and return 366*4882a593Smuzhiyun ldmfd sp!, {r0 - r12, pc} 367*4882a593Smuzhiyun 368*4882a593SmuzhiyunENTRY(omap1610_cpu_suspend_sz) 369*4882a593Smuzhiyun .word . - omap1610_cpu_suspend 370*4882a593Smuzhiyun#endif /* CONFIG_ARCH_OMAP16XX */ 371