xref: /linux/arch/arm/mach-exynos/sleep.S (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1/*
2 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
3 *		http://www.samsung.com
4 *
5 * Exynos low-level resume code
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/linkage.h>
19#include <asm/asm-offsets.h>
20#include <asm/hardware/cache-l2x0.h>
21#include "smc.h"
22
23#define CPU_MASK	0xff0ffff0
24#define CPU_CORTEX_A9	0x410fc090
25
26	.text
27	.align
28
29	/*
30	 * sleep magic, to allow the bootloader to check for an valid
31	 * image to resume to. Must be the first word before the
32	 * exynos_cpu_resume entry.
33	 */
34
35	.word	0x2bedf00d
36
37	/*
38	 * exynos_cpu_resume
39	 *
40	 * resume code entry for bootloader to call
41	 */
42
43ENTRY(exynos_cpu_resume)
44#ifdef CONFIG_CACHE_L2X0
45	mrc	p15, 0, r0, c0, c0, 0
46	ldr	r1, =CPU_MASK
47	and	r0, r0, r1
48	ldr	r1, =CPU_CORTEX_A9
49	cmp	r0, r1
50	bleq	l2c310_early_resume
51#endif
52	b	cpu_resume
53ENDPROC(exynos_cpu_resume)
54
55	.align
56
57ENTRY(exynos_cpu_resume_ns)
58	mrc	p15, 0, r0, c0, c0, 0
59	ldr	r1, =CPU_MASK
60	and	r0, r0, r1
61	ldr	r1, =CPU_CORTEX_A9
62	cmp	r0, r1
63	bne	skip_cp15
64
65	adr	r0, _cp15_save_power
66	ldr	r1, [r0]
67	ldr	r1, [r0, r1]
68	adr	r0, _cp15_save_diag
69	ldr	r2, [r0]
70	ldr	r2, [r0, r2]
71	mov	r0, #SMC_CMD_C15RESUME
72	dsb
73	smc	#0
74#ifdef CONFIG_CACHE_L2X0
75	adr	r0, 1f
76	ldr	r2, [r0]
77	add	r0, r2, r0
78
79	/* Check that the address has been initialised. */
80	ldr	r1, [r0, #L2X0_R_PHY_BASE]
81	teq	r1, #0
82	beq	skip_l2x0
83
84	/* Check if controller has been enabled. */
85	ldr	r2, [r1, #L2X0_CTRL]
86	tst	r2, #0x1
87	bne	skip_l2x0
88
89	ldr	r1, [r0, #L2X0_R_TAG_LATENCY]
90	ldr	r2, [r0, #L2X0_R_DATA_LATENCY]
91	ldr	r3, [r0, #L2X0_R_PREFETCH_CTRL]
92	mov	r0, #SMC_CMD_L2X0SETUP1
93	smc	#0
94
95	/* Reload saved regs pointer because smc corrupts registers. */
96	adr	r0, 1f
97	ldr	r2, [r0]
98	add	r0, r2, r0
99
100	ldr	r1, [r0, #L2X0_R_PWR_CTRL]
101	ldr	r2, [r0, #L2X0_R_AUX_CTRL]
102	mov	r0, #SMC_CMD_L2X0SETUP2
103	smc	#0
104
105	mov	r0, #SMC_CMD_L2X0INVALL
106	smc	#0
107
108	mov	r1, #1
109	mov	r0, #SMC_CMD_L2X0CTRL
110	smc	#0
111skip_l2x0:
112#endif /* CONFIG_CACHE_L2X0 */
113skip_cp15:
114	b	cpu_resume
115ENDPROC(exynos_cpu_resume_ns)
116
117	.align
118_cp15_save_power:
119	.long	cp15_save_power - .
120_cp15_save_diag:
121	.long	cp15_save_diag - .
122#ifdef CONFIG_CACHE_L2X0
1231:	.long	l2x0_saved_regs - .
124#endif /* CONFIG_CACHE_L2X0 */
125
126	.data
127	.globl cp15_save_diag
128cp15_save_diag:
129	.long	0	@ cp15 diagnostic
130	.globl cp15_save_power
131cp15_save_power:
132	.long	0	@ cp15 power control
133