xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t186/plat_trampoline.S (revision 7f164a83a9d9cade9917f448c629d85913ff10c6)
1/*
2 * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
3 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <arch.h>
9#include <asm_macros.S>
10#include <common/bl_common.h>
11#include <memctrl_v2.h>
12#include <plat/common/common_def.h>
13#include <tegra_def.h>
14
15#define TEGRA186_STATE_SYSTEM_SUSPEND	0x5C7
16#define TEGRA186_STATE_SYSTEM_RESUME	0x600D
17#define TEGRA186_MC_CTX_SIZE		0x93
18
19	.globl	tegra186_cpu_reset_handler
20
21/* CPU reset handler routine */
22func tegra186_cpu_reset_handler _align=4
23	/* check if we are exiting system suspend state */
24	adr	x0, __tegra186_system_suspend_state
25	ldr	x1, [x0]
26	mov	x2, #TEGRA186_STATE_SYSTEM_SUSPEND
27	lsl	x2, x2, #16
28	add	x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND
29	cmp	x1, x2
30	bne	boot_cpu
31
32	/* set system resume state */
33	mov	x1, #TEGRA186_STATE_SYSTEM_RESUME
34	lsl	x1, x1, #16
35	mov	x2, #TEGRA186_STATE_SYSTEM_RESUME
36	add	x1, x1, x2
37	str	x1, [x0]
38	dsb	sy
39
40	/* prepare to relocate to TZSRAM */
41	mov	x0, #BL31_BASE
42	adr	x1, __tegra186_cpu_reset_handler_end
43	adr	x2, __tegra186_cpu_reset_handler_data
44	ldr	x2, [x2, #8]
45
46	/* memcpy16 */
47m_loop16:
48	cmp	x2, #16
49	b.lt	m_loop1
50	ldp	x3, x4, [x1], #16
51	stp	x3, x4, [x0], #16
52	sub	x2, x2, #16
53	b	m_loop16
54	/* copy byte per byte */
55m_loop1:
56	cbz	x2, boot_cpu
57	ldrb	w3, [x1], #1
58	strb	w3, [x0], #1
59	subs	x2, x2, #1
60	b.ne	m_loop1
61
62boot_cpu:
63	adr	x0, __tegra186_cpu_reset_handler_data
64	ldr	x0, [x0]
65	br	x0
66endfunc tegra186_cpu_reset_handler
67
68	/*
69	 * Tegra186 reset data (offset 0x0 - 0x430)
70	 *
71	 * 0x000: secure world's entrypoint
72	 * 0x008: BL31 size (RO + RW)
73	 * 0x00C: MC context start
74	 * 0x42C: MC context end
75	 */
76
77	.align 4
78	.type	__tegra186_cpu_reset_handler_data, %object
79	.globl	__tegra186_cpu_reset_handler_data
80__tegra186_cpu_reset_handler_data:
81	.quad	tegra_secure_entrypoint
82	.quad	__BL31_END__ - BL31_BASE
83
84	.globl	__tegra186_system_suspend_state
85__tegra186_system_suspend_state:
86	.quad	0
87
88	.align 4
89	.globl	__tegra186_mc_context
90__tegra186_mc_context:
91	.rept	TEGRA186_MC_CTX_SIZE
92	.quad	0
93	.endr
94	.size	__tegra186_cpu_reset_handler_data, \
95		. - __tegra186_cpu_reset_handler_data
96
97	.align 4
98	.globl	__tegra186_cpu_reset_handler_end
99__tegra186_cpu_reset_handler_end:
100
101	.globl tegra186_get_cpu_reset_handler_size
102	.globl tegra186_get_cpu_reset_handler_base
103	.globl tegra186_get_mc_ctx_offset
104	.globl tegra186_set_system_suspend_entry
105
106/* return size of the CPU reset handler */
107func tegra186_get_cpu_reset_handler_size
108	adr	x0, __tegra186_cpu_reset_handler_end
109	adr	x1, tegra186_cpu_reset_handler
110	sub	x0, x0, x1
111	ret
112endfunc tegra186_get_cpu_reset_handler_size
113
114/* return the start address of the CPU reset handler */
115func tegra186_get_cpu_reset_handler_base
116	adr	x0, tegra186_cpu_reset_handler
117	ret
118endfunc tegra186_get_cpu_reset_handler_base
119
120/* return the size of the MC context */
121func tegra186_get_mc_ctx_offset
122	adr	x0, __tegra186_mc_context
123	adr	x1, tegra186_cpu_reset_handler
124	sub	x0, x0, x1
125	ret
126endfunc tegra186_get_mc_ctx_offset
127
128/* set system suspend state before SC7 entry */
129func tegra186_set_system_suspend_entry
130	mov	x0, #TEGRA_MC_BASE
131	mov	x3, #MC_SECURITY_CFG3_0
132	ldr	w1, [x0, x3]
133	lsl	x1, x1, #32
134	mov	x3, #MC_SECURITY_CFG0_0
135	ldr	w2, [x0, x3]
136	orr	x3, x1, x2			/* TZDRAM base */
137	adr	x0, __tegra186_system_suspend_state
138	adr	x1, tegra186_cpu_reset_handler
139	sub	x2, x0, x1			/* offset in TZDRAM */
140	mov	x0, #TEGRA186_STATE_SYSTEM_SUSPEND
141	lsl	x0, x0, #16
142	add	x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND
143	str	x0, [x3, x2]			/* set value in TZDRAM */
144	dsb	sy
145	ret
146endfunc tegra186_set_system_suspend_entry
147