xref: /openbmc/linux/arch/arm/mach-tegra/sleep.S (revision c76fcc8a)
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
73ENTRY(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
90ENDPROC(tegra_cpu_wfi)
91
92