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