sleep.S revision 1a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8
15e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
25e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * linux/arch/arm/plat-omap/sleep.S
35e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
41a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * Low-level OMAP730/1510/1610 sleep/wakeUp support
55e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
65e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Initial SA1110 code:
75e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
85e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
95e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Adapted for PXA by Nicolas Pitre:
105e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Copyright (c) 2002 Monta Vista Software, Inc.
115e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
125e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
135e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
145e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * This program is free software; you can redistribute it and/or modify it
155e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * under the terms of the GNU General Public License as published by the
165e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Free Software Foundation; either version 2 of the License, or (at your
175e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * option) any later version.
185e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
195e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
205e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
215e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
225e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
235e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
245e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
255e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
265e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
285e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
305e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * You should have received a copy of the GNU General Public License along
315e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * with this program; if not, write to the Free Software Foundation, Inc.,
325e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * 675 Mass Ave, Cambridge, MA 02139, USA.
335e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
345e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
355e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#include <linux/config.h>
365e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#include <linux/linkage.h>
375e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#include <asm/assembler.h>
385e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#include <asm/arch/io.h>
395e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#include <asm/arch/pm.h>
405e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
415e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren		.text
425e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
435e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
445e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Forces OMAP into idle state
455e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
465e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * omapXXXX_idle_loop_suspend()
475e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
485e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Note: This code get's copied to internal SRAM at boot. When the OMAP
495e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *	 wakes up it continues execution at the point it went to sleep.
505e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
515e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Note: Because of slightly different configuration values we have
525e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *       processor specific functions here.
535e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
545e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
551a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren#if defined(CONFIG_ARCH_OMAP730)
561a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony LindgrenENTRY(omap730_idle_loop_suspend)
571a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
581a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
591a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
601a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
611a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
621a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
631a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
641a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
651a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ turn off clock domains
661a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ get ARM_IDLECT2 into r2
671a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
681a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
691a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
701a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
711a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
721a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ request ARM idle
731a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ get ARM_IDLECT1 into r1
741a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	ldrh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
751a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r3, r1, #OMAP730_IDLE_LOOP_REQUEST & 0xffff
761a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
771a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
781a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r5, #IDLE_WAIT_CYCLES & 0xff
791a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
801a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgrenl_730:	subs	r5, r5, #1
811a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	bne	l_730
821a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren/*
831a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * Let's wait for the next clock tick to wake us up.
841a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren */
851a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r0, #0
861a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
871a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren/*
881a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * omap730_idle_loop_suspend()'s resume point.
891a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren *
901a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * It will just start executing here, so we'll restore stuff from the
911a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
921a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren */
931a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
941a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
951a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
961a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
971a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
981a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
991a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	ldmfd	sp!, {r0 - r12, pc}		@ restore regs and return
1001a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
1011a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony LindgrenENTRY(omap730_idle_loop_suspend_sz)
1021a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	.word	. - omap730_idle_loop_suspend
1031a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren#endif /* CONFIG_ARCH_OMAP730 */
1041a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
1051a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren#ifdef CONFIG_ARCH_OMAP15XX
1065e1c5ff4783e0ddd241580c9996390508722190eTony LindgrenENTRY(omap1510_idle_loop_suspend)
1075e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1085e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
1095e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1105e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
1115e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
1125e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
1135e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
1145e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1155e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ turn off clock domains
1165e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ get ARM_IDLECT2 into r2
1175e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
1185e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
11992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
1205e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
1215e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1225e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ request ARM idle
1235e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ get ARM_IDLECT1 into r1
1245e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	ldrh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
1255e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r3, r1, #OMAP1510_IDLE_LOOP_REQUEST & 0xffff
1265e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
1275e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1285e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r5, #IDLE_WAIT_CYCLES & 0xff
12992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
1305e1c5ff4783e0ddd241580c9996390508722190eTony Lindgrenl_1510:	subs	r5, r5, #1
1315e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	bne	l_1510
1325e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
1335e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Let's wait for the next clock tick to wake us up.
1345e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
1355e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r0, #0
1365e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
1375e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
1385e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * omap1510_idle_loop_suspend()'s resume point.
1395e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
1405e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * It will just start executing here, so we'll restore stuff from the
1415e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
1425e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
1435e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1445e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
1455e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
1465e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
1475e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
1485e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
14992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	ldmfd	sp!, {r0 - r12, pc}		@ restore regs and return
1505e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1515e1c5ff4783e0ddd241580c9996390508722190eTony LindgrenENTRY(omap1510_idle_loop_suspend_sz)
1525e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	.word	. - omap1510_idle_loop_suspend
1531a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren#endif /* CONFIG_ARCH_OMAP15XX */
1545e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1555e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#if defined(CONFIG_ARCH_OMAP16XX)
1565e1c5ff4783e0ddd241580c9996390508722190eTony LindgrenENTRY(omap1610_idle_loop_suspend)
1575e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1585e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	stmfd	sp!, {r0 - r12, lr}		@ save registers on stack
1595e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1605e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
1615e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
1625e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
1635e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
1645e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1655e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ turn off clock domains
1665e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ get ARM_IDLECT2 into r2
1675e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	ldrh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
16892105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mov	r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
16992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
1705e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
1715e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1725e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ request ARM idle
1735e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ get ARM_IDLECT1 into r1
1745e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	ldrh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
1755e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r3, r1, #OMAP1610_IDLE_LOOP_REQUEST & 0xffff
1765e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
1775e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1785e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r5, #IDLE_WAIT_CYCLES & 0xff
17992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
1805e1c5ff4783e0ddd241580c9996390508722190eTony Lindgrenl_1610:	subs	r5, r5, #1
1815e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	bne	l_1610
1825e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
1835e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Let's wait for the next clock tick to wake us up.
1845e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
1855e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r0, #0
1865e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mcr	p15, 0, r0, c7, c0, 4		@ wait for interrupt
1875e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
1885e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * omap1610_idle_loop_suspend()'s resume point.
1895e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
1905e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * It will just start executing here, so we'll restore stuff from the
1915e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
1925e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
1935e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
1945e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ restore ARM_IDLECT1 and ARM_IDLECT2 and return
1955e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
1965e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
1975e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
1985e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
19992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	ldmfd	sp!, {r0 - r12, pc}		@ restore regs and return
2005e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
2015e1c5ff4783e0ddd241580c9996390508722190eTony LindgrenENTRY(omap1610_idle_loop_suspend_sz)
2025e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	.word	. - omap1610_idle_loop_suspend
2035e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#endif /* CONFIG_ARCH_OMAP16XX */
2045e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
2055e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
2065e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Forces OMAP into deep sleep state
2075e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
2085e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * omapXXXX_cpu_suspend()
2095e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
2105e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed
2115e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1
2125e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * in register r1.
2135e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
2145e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Note: This code get's copied to internal SRAM at boot. When the OMAP
2155e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *	 wakes up it continues execution at the point it went to sleep.
2165e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
2175e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Note: Because of errata work arounds we have processor specific functions
2185e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *       here. They are mostly the same, but slightly different.
2195e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
2205e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
2215e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
2221a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren#if defined(CONFIG_ARCH_OMAP730)
2231a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony LindgrenENTRY(omap730_cpu_suspend)
2241a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2251a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ save registers on stack
2261a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	stmfd	sp!, {r0 - r12, lr}
2271a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2281a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ Drain write cache
2291a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r4, #0
2301a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mcr	p15, 0, r0, c7, c10, 4
2311a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	nop
2321a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2331a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ load base address of Traffic Controller
2341a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r6, #TCMIF_ASM_BASE & 0xff000000
2351a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
2361a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
2371a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2381a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ prepare to put SDRAM into self-refresh manually
2391a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	ldr	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
2401a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r9, r7, #SELF_REFRESH_MODE & 0xff000000
2411a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r9, r9, #SELF_REFRESH_MODE & 0x000000ff
2421a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	str	r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
2431a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2441a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ prepare to put EMIFS to Sleep
2451a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	ldr	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
2461a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r9, r8, #IDLE_EMIFS_REQUEST & 0xff
2471a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	str	r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
2481a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2491a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
2501a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
2511a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
2521a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
2531a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2541a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ turn off clock domains
2551a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ do not disable PERCK (0x04)
2561a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff
2571a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r5, r5, #OMAP730_IDLECT2_SLEEP_VAL & 0xff00
2581a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
2591a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2601a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ request ARM idle
2611a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff
2621a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	orr	r3, r3, #OMAP730_IDLECT1_SLEEP_VAL & 0xff00
2631a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
2641a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2651a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ disable instruction cache
2661a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mrc	p15, 0, r9, c1, c0, 0
2671a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	bic	r2, r9, #0x1000
2681a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mcr	p15, 0, r2, c1, c0, 0
2691a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	nop
2701a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2711a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren/*
2721a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * Let's wait for the next wake up event to wake us up. r0 can't be
2731a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * used here because r0 holds ARM_IDLECT1
2741a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren */
2751a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mov	r2, #0
2761a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
2771a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren/*
2781a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * omap730_cpu_suspend()'s resume point.
2791a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren *
2801a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * It will just start executing here, so we'll restore stuff from the
2811a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren * stack.
2821a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren */
2831a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ re-enable Icache
2841a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	mcr	p15, 0, r9, c1, c0, 0
2851a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2861a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ reset the ARM_IDLECT1 and ARM_IDLECT2.
2871a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
2881a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
2891a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2901a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ Restore EMIFF controls
2911a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	str	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
2921a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	str	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
2931a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2941a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	@ restore regs and return
2951a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	ldmfd	sp!, {r0 - r12, pc}
2961a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
2971a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony LindgrenENTRY(omap730_cpu_suspend_sz)
2981a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren	.word	. - omap730_cpu_suspend
2991a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren#endif /* CONFIG_ARCH_OMAP730 */
3001a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren
3011a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren#ifdef CONFIG_ARCH_OMAP15XX
3025e1c5ff4783e0ddd241580c9996390508722190eTony LindgrenENTRY(omap1510_cpu_suspend)
3035e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3045e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ save registers on stack
3055e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	stmfd	sp!, {r0 - r12, lr}
3065e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3075e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ load base address of Traffic Controller
3085e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r4, #TCMIF_ASM_BASE & 0xff000000
3095e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
3105e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
3115e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3125e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ work around errata of OMAP1510 PDE bit for TC shut down
3135e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ clear PDE bit
3145e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
3155e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	bic	r5, r5, #PDE_BIT & 0xff
3165e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
3175e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3185e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ set PWD_EN bit
3195e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	and	r5, r5, #PWD_EN_BIT & 0xff
3205e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
3215e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3225e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ prepare to put SDRAM into self-refresh manually
3235e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	ldr	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
3245e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r5, r5, #SELF_REFRESH_MODE & 0xff000000
3255e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r5, r5, #SELF_REFRESH_MODE & 0x000000ff
3265e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	str	r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
3275e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3285e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ prepare to put EMIFS to Sleep
3295e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	ldr	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
3305e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r5, r5, #IDLE_EMIFS_REQUEST & 0xff
3315e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	str	r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
3325e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3335e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
3345e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
3355e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
3365e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
3375e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3385e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ turn off clock domains
3395e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
34092105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
3415e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
3425e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3435e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ request ARM idle
3445e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
3455e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
3465e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
3475e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3485e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r5, #IDLE_WAIT_CYCLES & 0xff
34992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r5, r5, #IDLE_WAIT_CYCLES & 0xff00
3505e1c5ff4783e0ddd241580c9996390508722190eTony Lindgrenl_1510_2:
3515e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	subs	r5, r5, #1
3525e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	bne	l_1510_2
3535e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
3545e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Let's wait for the next wake up event to wake us up. r0 can't be
3555e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * used here because r0 holds ARM_IDLECT1
3565e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
3575e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r2, #0
3585e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
3595e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
3605e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * omap1510_cpu_suspend()'s resume point.
3615e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
3625e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * It will just start executing here, so we'll restore stuff from the
3635e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
3645e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
3655e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
3665e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
3675e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3685e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ restore regs and return
36992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	ldmfd	sp!, {r0 - r12, pc}
3705e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3715e1c5ff4783e0ddd241580c9996390508722190eTony LindgrenENTRY(omap1510_cpu_suspend_sz)
3725e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	.word	. - omap1510_cpu_suspend
3731a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8Tony Lindgren#endif /* CONFIG_ARCH_OMAP15XX */
3745e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3755e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#if defined(CONFIG_ARCH_OMAP16XX)
3765e1c5ff4783e0ddd241580c9996390508722190eTony LindgrenENTRY(omap1610_cpu_suspend)
3775e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3785e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ save registers on stack
3795e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	stmfd	sp!, {r0 - r12, lr}
3805e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
38192105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	@ Drain write cache
38292105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mov	r4, #0
38392105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mcr	p15, 0, r0, c7, c10, 4
38492105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	nop
38592105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren
3865e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ load base address of Traffic Controller
38792105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mov	r6, #TCMIF_ASM_BASE & 0xff000000
38892105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r6, r6, #TCMIF_ASM_BASE & 0x00ff0000
38992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r6, r6, #TCMIF_ASM_BASE & 0x0000ff00
3905e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3915e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ prepare to put SDRAM into self-refresh manually
39292105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	ldr	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
39392105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r9, r7, #SELF_REFRESH_MODE & 0xff000000
39492105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r9, r9, #SELF_REFRESH_MODE & 0x000000ff
39592105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	str	r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
3965e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
3975e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ prepare to put EMIFS to Sleep
39892105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	ldr	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
39992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r9, r8, #IDLE_EMIFS_REQUEST & 0xff
40092105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	str	r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
4015e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
4025e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ load base address of ARM_IDLECT1 and ARM_IDLECT2
4035e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r4, #CLKGEN_REG_ASM_BASE & 0xff000000
4045e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
4055e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	orr	r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
4065e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
4075e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ turn off clock domains
40892105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	@ do not disable PERCK (0x04)
40992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mov	r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff
41092105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00
4115e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
4125e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
4135e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ request ARM idle
41492105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mov	r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff
41592105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	orr	r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00
4165e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
4175e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
41892105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	@ disable instruction cache
41992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mrc	p15, 0, r9, c1, c0, 0
42092105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	bic	r2, r9, #0x1000
42192105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mcr	p15, 0, r2, c1, c0, 0
42292105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	nop
42392105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren
4245e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
4255e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * Let's wait for the next wake up event to wake us up. r0 can't be
4265e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * used here because r0 holds ARM_IDLECT1
4275e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
4285e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mov	r2, #0
4295e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	mcr	p15, 0, r2, c7, c0, 4		@ wait for interrupt
4305e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren/*
4315e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * omap1610_cpu_suspend()'s resume point.
4325e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren *
4335e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren * It will just start executing here, so we'll restore stuff from the
43492105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren * stack.
4355e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren */
43692105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	@ re-enable Icache
43792105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	mcr	p15, 0, r9, c1, c0, 0
43892105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren
43992105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	@ reset the ARM_IDLECT1 and ARM_IDLECT2.
4405e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
4415e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	strh	r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
4425e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
44392105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	@ Restore EMIFF controls
44492105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	str	r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
44592105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	str	r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
44692105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren
4475e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	@ restore regs and return
44892105bb70634abacc08bbe12bf6f888fbd7dad38Tony Lindgren	ldmfd	sp!, {r0 - r12, pc}
4495e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren
4505e1c5ff4783e0ddd241580c9996390508722190eTony LindgrenENTRY(omap1610_cpu_suspend_sz)
4515e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren	.word	. - omap1610_cpu_suspend
4525e1c5ff4783e0ddd241580c9996390508722190eTony Lindgren#endif /* CONFIG_ARCH_OMAP16XX */
453