Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
[cascardo/linux.git] / arch / arm / mach-tegra / sleep.S
1 /*
2  * arch/arm/mach-tegra/sleep.S
3  *
4  * Copyright (c) 2010-2011, NVIDIA Corporation.
5  * Copyright (c) 2011, Google, Inc.
6  *
7  * Author: Colin Cross <ccross@android.com>
8  *         Gary King <gking@nvidia.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18  * more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #include <linux/linkage.h>
26 #include <mach/io.h>
27 #include <mach/iomap.h>
28
29 #include "flowctrl.h"
30
31 #define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
32                                         + IO_PPSB_VIRT)
33
34 /* returns the offset of the flow controller halt register for a cpu */
35 .macro cpu_to_halt_reg rd, rcpu
36         cmp     \rcpu, #0
37         subne   \rd, \rcpu, #1
38         movne   \rd, \rd, lsl #3
39         addne   \rd, \rd, #0x14
40         moveq   \rd, #0
41 .endm
42
43 /* returns the offset of the flow controller csr register for a cpu */
44 .macro cpu_to_csr_reg rd, rcpu
45         cmp     \rcpu, #0
46         subne   \rd, \rcpu, #1
47         movne   \rd, \rd, lsl #3
48         addne   \rd, \rd, #0x18
49         moveq   \rd, #8
50 .endm
51
52 /* returns the ID of the current processor */
53 .macro cpu_id, rd
54         mrc     p15, 0, \rd, c0, c0, 5
55         and     \rd, \rd, #0xF
56 .endm
57
58 /* loads a 32-bit value into a register without a data access */
59 .macro mov32, reg, val
60         movw    \reg, #:lower16:\val
61         movt    \reg, #:upper16:\val
62 .endm
63
64 /*
65  * tegra_cpu_wfi
66  *
67  * puts current CPU in clock-gated wfi using the flow controller
68  *
69  * corrupts r0-r3
70  * must be called with MMU on
71  */
72
73 ENTRY(tegra_cpu_wfi)
74         cpu_id  r0
75         cpu_to_halt_reg r1, r0
76         cpu_to_csr_reg r2, r0
77         mov32   r0, TEGRA_FLOW_CTRL_VIRT
78         mov     r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
79         str     r3, [r0, r2]    @ clear event & interrupt status
80         mov     r3, #FLOW_CTRL_WAIT_FOR_INTERRUPT | FLOW_CTRL_JTAG_RESUME
81         str     r3, [r0, r1]    @ put flow controller in wait irq mode
82         dsb
83         wfi
84         mov     r3, #0
85         str     r3, [r0, r1]    @ clear flow controller halt status
86         mov     r3, #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG
87         str     r3, [r0, r2]    @ clear event & interrupt status
88         dsb
89         mov     pc, lr
90 ENDPROC(tegra_cpu_wfi)
91