xref: /OK3568_Linux_fs/kernel/arch/arm/mach-tegra/sleep.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #ifndef __MACH_TEGRA_SLEEP_H
7*4882a593Smuzhiyun #define __MACH_TEGRA_SLEEP_H
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include "iomap.h"
10*4882a593Smuzhiyun #include "irammap.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #define TEGRA_ARM_PERIF_VIRT (TEGRA_ARM_PERIF_BASE - IO_CPU_PHYS \
13*4882a593Smuzhiyun 					+ IO_CPU_VIRT)
14*4882a593Smuzhiyun #define TEGRA_FLOW_CTRL_VIRT (TEGRA_FLOW_CTRL_BASE - IO_PPSB_PHYS \
15*4882a593Smuzhiyun 					+ IO_PPSB_VIRT)
16*4882a593Smuzhiyun #define TEGRA_CLK_RESET_VIRT (TEGRA_CLK_RESET_BASE - IO_PPSB_PHYS \
17*4882a593Smuzhiyun 					+ IO_PPSB_VIRT)
18*4882a593Smuzhiyun #define TEGRA_APB_MISC_VIRT (TEGRA_APB_MISC_BASE - IO_APB_PHYS \
19*4882a593Smuzhiyun 					+ IO_APB_VIRT)
20*4882a593Smuzhiyun #define TEGRA_PMC_VIRT	(TEGRA_PMC_BASE - IO_APB_PHYS + IO_APB_VIRT)
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define TEGRA_IRAM_RESET_BASE_VIRT (IO_IRAM_VIRT + \
23*4882a593Smuzhiyun 				TEGRA_IRAM_RESET_HANDLER_OFFSET)
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /* PMC_SCRATCH37-39 and 41 are used for tegra_pen_lock and idle */
26*4882a593Smuzhiyun #define PMC_SCRATCH37	0x130
27*4882a593Smuzhiyun #define PMC_SCRATCH38	0x134
28*4882a593Smuzhiyun #define PMC_SCRATCH39	0x138
29*4882a593Smuzhiyun #define PMC_SCRATCH41	0x140
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #ifdef CONFIG_ARCH_TEGRA_2x_SOC
32*4882a593Smuzhiyun #define CPU_RESETTABLE		2
33*4882a593Smuzhiyun #define CPU_RESETTABLE_SOON	1
34*4882a593Smuzhiyun #define CPU_NOT_RESETTABLE	0
35*4882a593Smuzhiyun #endif
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun /* flag of tegra_disable_clean_inv_dcache to do LoUIS or all */
38*4882a593Smuzhiyun #define TEGRA_FLUSH_CACHE_LOUIS	0
39*4882a593Smuzhiyun #define TEGRA_FLUSH_CACHE_ALL	1
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #ifdef __ASSEMBLY__
42*4882a593Smuzhiyun /* waits until the microsecond counter (base) is > rn */
43*4882a593Smuzhiyun .macro wait_until, rn, base, tmp
44*4882a593Smuzhiyun 	add	\rn, \rn, #1
45*4882a593Smuzhiyun 1001:	ldr	\tmp, [\base]
46*4882a593Smuzhiyun 	cmp	\tmp, \rn
47*4882a593Smuzhiyun 	bmi	1001b
48*4882a593Smuzhiyun .endm
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /* returns the offset of the flow controller halt register for a cpu */
51*4882a593Smuzhiyun .macro cpu_to_halt_reg rd, rcpu
52*4882a593Smuzhiyun 	cmp	\rcpu, #0
53*4882a593Smuzhiyun 	subne	\rd, \rcpu, #1
54*4882a593Smuzhiyun 	movne	\rd, \rd, lsl #3
55*4882a593Smuzhiyun 	addne	\rd, \rd, #0x14
56*4882a593Smuzhiyun 	moveq	\rd, #0
57*4882a593Smuzhiyun .endm
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /* returns the offset of the flow controller csr register for a cpu */
60*4882a593Smuzhiyun .macro cpu_to_csr_reg rd, rcpu
61*4882a593Smuzhiyun 	cmp	\rcpu, #0
62*4882a593Smuzhiyun 	subne	\rd, \rcpu, #1
63*4882a593Smuzhiyun 	movne	\rd, \rd, lsl #3
64*4882a593Smuzhiyun 	addne	\rd, \rd, #0x18
65*4882a593Smuzhiyun 	moveq	\rd, #8
66*4882a593Smuzhiyun .endm
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun /* returns the ID of the current processor */
69*4882a593Smuzhiyun .macro cpu_id, rd
70*4882a593Smuzhiyun 	mrc	p15, 0, \rd, c0, c0, 5
71*4882a593Smuzhiyun 	and	\rd, \rd, #0xF
72*4882a593Smuzhiyun .endm
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun /* loads a 32-bit value into a register without a data access */
75*4882a593Smuzhiyun .macro mov32, reg, val
76*4882a593Smuzhiyun 	movw	\reg, #:lower16:\val
77*4882a593Smuzhiyun 	movt	\reg, #:upper16:\val
78*4882a593Smuzhiyun .endm
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /* Marco to check CPU part num */
81*4882a593Smuzhiyun .macro check_cpu_part_num part_num, tmp1, tmp2
82*4882a593Smuzhiyun 	mrc	p15, 0, \tmp1, c0, c0, 0
83*4882a593Smuzhiyun 	ubfx	\tmp1, \tmp1, #4, #12
84*4882a593Smuzhiyun 	mov32	\tmp2, \part_num
85*4882a593Smuzhiyun 	cmp	\tmp1, \tmp2
86*4882a593Smuzhiyun .endm
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /* Macro to exit SMP coherency. */
89*4882a593Smuzhiyun .macro exit_smp, tmp1, tmp2
90*4882a593Smuzhiyun 	mrc	p15, 0, \tmp1, c1, c0, 1	@ ACTLR
91*4882a593Smuzhiyun 	bic	\tmp1, \tmp1, #(1<<6) | (1<<0)	@ clear ACTLR.SMP | ACTLR.FW
92*4882a593Smuzhiyun 	mcr	p15, 0, \tmp1, c1, c0, 1	@ ACTLR
93*4882a593Smuzhiyun 	isb
94*4882a593Smuzhiyun #ifdef CONFIG_HAVE_ARM_SCU
95*4882a593Smuzhiyun 	check_cpu_part_num 0xc09, \tmp1, \tmp2
96*4882a593Smuzhiyun 	mrceq	p15, 0, \tmp1, c0, c0, 5
97*4882a593Smuzhiyun 	andeq	\tmp1, \tmp1, #0xF
98*4882a593Smuzhiyun 	moveq	\tmp1, \tmp1, lsl #2
99*4882a593Smuzhiyun 	moveq	\tmp2, #0xf
100*4882a593Smuzhiyun 	moveq	\tmp2, \tmp2, lsl \tmp1
101*4882a593Smuzhiyun 	ldreq	\tmp1, =(TEGRA_ARM_PERIF_VIRT + 0xC)
102*4882a593Smuzhiyun 	streq	\tmp2, [\tmp1]			@ invalidate SCU tags for CPU
103*4882a593Smuzhiyun 	dsb
104*4882a593Smuzhiyun #endif
105*4882a593Smuzhiyun .endm
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /* Macro to check Tegra revision */
108*4882a593Smuzhiyun #define APB_MISC_GP_HIDREV	0x804
109*4882a593Smuzhiyun .macro tegra_get_soc_id base, tmp1
110*4882a593Smuzhiyun 	mov32	\tmp1, \base
111*4882a593Smuzhiyun 	ldr	\tmp1, [\tmp1, #APB_MISC_GP_HIDREV]
112*4882a593Smuzhiyun 	and	\tmp1, \tmp1, #0xff00
113*4882a593Smuzhiyun 	mov	\tmp1, \tmp1, lsr #8
114*4882a593Smuzhiyun .endm
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun #else
117*4882a593Smuzhiyun void tegra_resume(void);
118*4882a593Smuzhiyun int tegra_sleep_cpu_finish(unsigned long);
119*4882a593Smuzhiyun void tegra_disable_clean_inv_dcache(u32 flag);
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun void tegra20_hotplug_shutdown(void);
122*4882a593Smuzhiyun void tegra30_hotplug_shutdown(void);
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun void tegra20_tear_down_cpu(void);
125*4882a593Smuzhiyun void tegra30_tear_down_cpu(void);
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun #endif
128*4882a593Smuzhiyun #endif
129