xref: /rk3399_ARM-atf/plat/nvidia/tegra/soc/t186/plat_trampoline.S (revision 539c62d7b3d31612e4c6a4a9a1ba8fc80b3874c9)
168c7de6fSVarun Wadekar/*
268c7de6fSVarun Wadekar * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
368c7de6fSVarun Wadekar *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
568c7de6fSVarun Wadekar */
668c7de6fSVarun Wadekar
768c7de6fSVarun Wadekar#include <arch.h>
868c7de6fSVarun Wadekar#include <asm_macros.S>
968c7de6fSVarun Wadekar#include <memctrl_v2.h>
1009d40e0eSAntonio Nino Diaz#include <plat/common/common_def.h>
1168c7de6fSVarun Wadekar#include <tegra_def.h>
1268c7de6fSVarun Wadekar
13*539c62d7SVarun Wadekar#define TEGRA186_STATE_SYSTEM_SUSPEND	0x5C7
14*539c62d7SVarun Wadekar#define TEGRA186_STATE_SYSTEM_RESUME	0x600D
1568c7de6fSVarun Wadekar#define TEGRA186_SMMU_CTX_SIZE		0x420
1668c7de6fSVarun Wadekar
1768c7de6fSVarun Wadekar	.globl	tegra186_cpu_reset_handler
1868c7de6fSVarun Wadekar
1968c7de6fSVarun Wadekar/* CPU reset handler routine */
2064726e6dSJulius Wernerfunc tegra186_cpu_reset_handler _align=4
21*539c62d7SVarun Wadekar	/* check if we are exiting system suspend state */
22*539c62d7SVarun Wadekar	adr	x0, __tegra186_system_suspend_state
23*539c62d7SVarun Wadekar	ldr	x1, [x0]
24*539c62d7SVarun Wadekar	mov	x2, #TEGRA186_STATE_SYSTEM_SUSPEND
25*539c62d7SVarun Wadekar	lsl	x2, x2, #16
26*539c62d7SVarun Wadekar	add	x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND
27*539c62d7SVarun Wadekar	cmp	x1, x2
28*539c62d7SVarun Wadekar	bne	boot_cpu
2968c7de6fSVarun Wadekar
30*539c62d7SVarun Wadekar	/* set system resume state */
31*539c62d7SVarun Wadekar	mov	x1, #TEGRA186_STATE_SYSTEM_RESUME
32*539c62d7SVarun Wadekar	lsl	x1, x1, #16
33*539c62d7SVarun Wadekar	mov	x2, #TEGRA186_STATE_SYSTEM_RESUME
34*539c62d7SVarun Wadekar	add	x1, x1, x2
35*539c62d7SVarun Wadekar	str	x1, [x0]
36*539c62d7SVarun Wadekar	dsb	sy
37*539c62d7SVarun Wadekar
38*539c62d7SVarun Wadekar	/* prepare to relocate to TZSRAM */
3968c7de6fSVarun Wadekar	mov	x0, #BL31_BASE
4068c7de6fSVarun Wadekar	adr	x1, __tegra186_cpu_reset_handler_end
4168c7de6fSVarun Wadekar	adr	x2, __tegra186_cpu_reset_handler_data
4268c7de6fSVarun Wadekar	ldr	x2, [x2, #8]
4368c7de6fSVarun Wadekar
4468c7de6fSVarun Wadekar	/* memcpy16 */
4568c7de6fSVarun Wadekarm_loop16:
4668c7de6fSVarun Wadekar	cmp	x2, #16
4768c7de6fSVarun Wadekar	b.lt	m_loop1
4868c7de6fSVarun Wadekar	ldp	x3, x4, [x1], #16
4968c7de6fSVarun Wadekar	stp	x3, x4, [x0], #16
5068c7de6fSVarun Wadekar	sub	x2, x2, #16
5168c7de6fSVarun Wadekar	b	m_loop16
5268c7de6fSVarun Wadekar	/* copy byte per byte */
5368c7de6fSVarun Wadekarm_loop1:
5468c7de6fSVarun Wadekar	cbz	x2, boot_cpu
5568c7de6fSVarun Wadekar	ldrb	w3, [x1], #1
5668c7de6fSVarun Wadekar	strb	w3, [x0], #1
5768c7de6fSVarun Wadekar	subs	x2, x2, #1
5868c7de6fSVarun Wadekar	b.ne	m_loop1
5968c7de6fSVarun Wadekar
6068c7de6fSVarun Wadekarboot_cpu:
6168c7de6fSVarun Wadekar	adr	x0, __tegra186_cpu_reset_handler_data
6268c7de6fSVarun Wadekar	ldr	x0, [x0]
6368c7de6fSVarun Wadekar	br	x0
6468c7de6fSVarun Wadekarendfunc tegra186_cpu_reset_handler
6568c7de6fSVarun Wadekar
6668c7de6fSVarun Wadekar	/*
6768c7de6fSVarun Wadekar	 * Tegra186 reset data (offset 0x0 - 0x430)
6868c7de6fSVarun Wadekar	 *
6968c7de6fSVarun Wadekar	 * 0x000: secure world's entrypoint
7068c7de6fSVarun Wadekar	 * 0x008: BL31 size (RO + RW)
7168c7de6fSVarun Wadekar	 * 0x00C: SMMU context start
7268c7de6fSVarun Wadekar	 * 0x42C: SMMU context end
7368c7de6fSVarun Wadekar	 */
7468c7de6fSVarun Wadekar
7568c7de6fSVarun Wadekar	.align 4
7668c7de6fSVarun Wadekar	.type	__tegra186_cpu_reset_handler_data, %object
7768c7de6fSVarun Wadekar	.globl	__tegra186_cpu_reset_handler_data
7868c7de6fSVarun Wadekar__tegra186_cpu_reset_handler_data:
7968c7de6fSVarun Wadekar	.quad	tegra_secure_entrypoint
8068c7de6fSVarun Wadekar	.quad	__BL31_END__ - BL31_BASE
81889c07c7SVarun Wadekar
82*539c62d7SVarun Wadekar	.globl	__tegra186_system_suspend_state
83*539c62d7SVarun Wadekar__tegra186_system_suspend_state:
84*539c62d7SVarun Wadekar	.quad	0
85*539c62d7SVarun Wadekar
86889c07c7SVarun Wadekar	.align 4
8763ac1a2aSVarun Wadekar	.globl	__tegra186_smmu_context
8863ac1a2aSVarun Wadekar__tegra186_smmu_context:
8968c7de6fSVarun Wadekar	.rept	TEGRA186_SMMU_CTX_SIZE
9068c7de6fSVarun Wadekar	.quad	0
9168c7de6fSVarun Wadekar	.endr
9268c7de6fSVarun Wadekar	.size	__tegra186_cpu_reset_handler_data, \
9368c7de6fSVarun Wadekar		. - __tegra186_cpu_reset_handler_data
9468c7de6fSVarun Wadekar
9568c7de6fSVarun Wadekar	.align 4
9668c7de6fSVarun Wadekar	.globl	__tegra186_cpu_reset_handler_end
9768c7de6fSVarun Wadekar__tegra186_cpu_reset_handler_end:
987191566cSVarun Wadekar
997191566cSVarun Wadekar	.globl tegra186_get_cpu_reset_handler_size
1007191566cSVarun Wadekar	.globl tegra186_get_cpu_reset_handler_base
101889c07c7SVarun Wadekar	.globl tegra186_get_smmu_ctx_offset
102*539c62d7SVarun Wadekar	.globl tegra186_set_system_suspend_entry
1037191566cSVarun Wadekar
1047191566cSVarun Wadekar/* return size of the CPU reset handler */
1057191566cSVarun Wadekarfunc tegra186_get_cpu_reset_handler_size
1067191566cSVarun Wadekar	adr	x0, __tegra186_cpu_reset_handler_end
1077191566cSVarun Wadekar	adr	x1, tegra186_cpu_reset_handler
1087191566cSVarun Wadekar	sub	x0, x0, x1
1097191566cSVarun Wadekar	ret
1107191566cSVarun Wadekarendfunc tegra186_get_cpu_reset_handler_size
1117191566cSVarun Wadekar
1127191566cSVarun Wadekar/* return the start address of the CPU reset handler */
1137191566cSVarun Wadekarfunc tegra186_get_cpu_reset_handler_base
1147191566cSVarun Wadekar	adr	x0, tegra186_cpu_reset_handler
1157191566cSVarun Wadekar	ret
1167191566cSVarun Wadekarendfunc tegra186_get_cpu_reset_handler_base
117889c07c7SVarun Wadekar
118889c07c7SVarun Wadekar/* return the size of the SMMU context */
119889c07c7SVarun Wadekarfunc tegra186_get_smmu_ctx_offset
120889c07c7SVarun Wadekar	adr	x0, __tegra186_smmu_context
121889c07c7SVarun Wadekar	adr	x1, tegra186_cpu_reset_handler
122889c07c7SVarun Wadekar	sub	x0, x0, x1
123889c07c7SVarun Wadekar	ret
124889c07c7SVarun Wadekarendfunc tegra186_get_smmu_ctx_offset
125*539c62d7SVarun Wadekar
126*539c62d7SVarun Wadekar/* set system suspend state before SC7 entry */
127*539c62d7SVarun Wadekarfunc tegra186_set_system_suspend_entry
128*539c62d7SVarun Wadekar	mov	x0, #TEGRA_MC_BASE
129*539c62d7SVarun Wadekar	mov	x3, #MC_SECURITY_CFG3_0
130*539c62d7SVarun Wadekar	ldr	w1, [x0, x3]
131*539c62d7SVarun Wadekar	lsl	x1, x1, #32
132*539c62d7SVarun Wadekar	mov	x3, #MC_SECURITY_CFG0_0
133*539c62d7SVarun Wadekar	ldr	w2, [x0, x3]
134*539c62d7SVarun Wadekar	orr	x3, x1, x2			/* TZDRAM base */
135*539c62d7SVarun Wadekar	adr	x0, __tegra186_system_suspend_state
136*539c62d7SVarun Wadekar	adr	x1, tegra186_cpu_reset_handler
137*539c62d7SVarun Wadekar	sub	x2, x0, x1			/* offset in TZDRAM */
138*539c62d7SVarun Wadekar	mov	x0, #TEGRA186_STATE_SYSTEM_SUSPEND
139*539c62d7SVarun Wadekar	lsl	x0, x0, #16
140*539c62d7SVarun Wadekar	add	x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND
141*539c62d7SVarun Wadekar	str	x0, [x3, x2]			/* set value in TZDRAM */
142*539c62d7SVarun Wadekar	dsb	sy
143*539c62d7SVarun Wadekar	ret
144*539c62d7SVarun Wadekarendfunc tegra186_set_system_suspend_entry
145