1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 *		http://www.samsung.com
5 *
6 * Exynos low-level resume code
7 */
8
9#include <linux/linkage.h>
10#include <asm/asm-offsets.h>
11#include <asm/hardware/cache-l2x0.h>
12#include "smc.h"
13
14#define CPU_MASK	0xff0ffff0
15#define CPU_CORTEX_A9	0x410fc090
16
17	.text
18	.align
19
20	/*
21	 * sleep magic, to allow the bootloader to check for an valid
22	 * image to resume to. Must be the first word before the
23	 * exynos_cpu_resume entry.
24	 */
25
26	.word	0x2bedf00d
27
28	/*
29	 * exynos_cpu_resume
30	 *
31	 * resume code entry for bootloader to call
32	 */
33
34ENTRY(exynos_cpu_resume)
35#ifdef CONFIG_CACHE_L2X0
36	mrc	p15, 0, r0, c0, c0, 0
37	ldr	r1, =CPU_MASK
38	and	r0, r0, r1
39	ldr	r1, =CPU_CORTEX_A9
40	cmp	r0, r1
41	bleq	l2c310_early_resume
42#endif
43	b	cpu_resume
44ENDPROC(exynos_cpu_resume)
45
46	.align
47	.arch armv7-a
48	.arch_extension sec
49ENTRY(exynos_cpu_resume_ns)
50	mrc	p15, 0, r0, c0, c0, 0
51	ldr	r1, =CPU_MASK
52	and	r0, r0, r1
53	ldr	r1, =CPU_CORTEX_A9
54	cmp	r0, r1
55	bne	skip_cp15
56
57	adr	r0, _cp15_save_power
58	ldr	r1, [r0]
59	ldr	r1, [r0, r1]
60	adr	r0, _cp15_save_diag
61	ldr	r2, [r0]
62	ldr	r2, [r0, r2]
63	mov	r0, #SMC_CMD_C15RESUME
64	dsb
65	smc	#0
66#ifdef CONFIG_CACHE_L2X0
67	adr	r0, 1f
68	ldr	r2, [r0]
69	add	r0, r2, r0
70
71	/* Check that the address has been initialised. */
72	ldr	r1, [r0, #L2X0_R_PHY_BASE]
73	teq	r1, #0
74	beq	skip_l2x0
75
76	/* Check if controller has been enabled. */
77	ldr	r2, [r1, #L2X0_CTRL]
78	tst	r2, #0x1
79	bne	skip_l2x0
80
81	ldr	r1, [r0, #L2X0_R_TAG_LATENCY]
82	ldr	r2, [r0, #L2X0_R_DATA_LATENCY]
83	ldr	r3, [r0, #L2X0_R_PREFETCH_CTRL]
84	mov	r0, #SMC_CMD_L2X0SETUP1
85	smc	#0
86
87	/* Reload saved regs pointer because smc corrupts registers. */
88	adr	r0, 1f
89	ldr	r2, [r0]
90	add	r0, r2, r0
91
92	ldr	r1, [r0, #L2X0_R_PWR_CTRL]
93	ldr	r2, [r0, #L2X0_R_AUX_CTRL]
94	mov	r0, #SMC_CMD_L2X0SETUP2
95	smc	#0
96
97	mov	r0, #SMC_CMD_L2X0INVALL
98	smc	#0
99
100	mov	r1, #1
101	mov	r0, #SMC_CMD_L2X0CTRL
102	smc	#0
103skip_l2x0:
104#endif /* CONFIG_CACHE_L2X0 */
105skip_cp15:
106	b	cpu_resume
107ENDPROC(exynos_cpu_resume_ns)
108
109	.align
110_cp15_save_power:
111	.long	cp15_save_power - .
112_cp15_save_diag:
113	.long	cp15_save_diag - .
114#ifdef CONFIG_CACHE_L2X0
1151:	.long	l2x0_saved_regs - .
116#endif /* CONFIG_CACHE_L2X0 */
117
118	.data
119	.align	2
120	.globl cp15_save_diag
121cp15_save_diag:
122	.long	0	@ cp15 diagnostic
123	.globl cp15_save_power
124cp15_save_power:
125	.long	0	@ cp15 power control
126