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 
34 ENTRY(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
44 ENDPROC(exynos_cpu_resume)
45 
46 	.align
47 	.arch armv7-a
48 	.arch_extension sec
49 ENTRY(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
103 skip_l2x0:
104 #endif /* CONFIG_CACHE_L2X0 */
105 skip_cp15:
106 	b	cpu_resume
107 ENDPROC(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
115 1:	.long	l2x0_saved_regs - .
116 #endif /* CONFIG_CACHE_L2X0 */
117 
118 	.data
119 	.align	2
120 	.globl cp15_save_diag
121 cp15_save_diag:
122 	.long	0	@ cp15 diagnostic
123 	.globl cp15_save_power
124 cp15_save_power:
125 	.long	0	@ cp15 power control
126