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