xref: /arm-trusted-firmware/plat/nvidia/tegra/soc/t194/plat_secondary.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <string.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <arch_helpers.h>
11*91f16700Schasinglulu #include <common/debug.h>
12*91f16700Schasinglulu #include <lib/mmio.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu #include <mce.h>
15*91f16700Schasinglulu #include <tegra194_private.h>
16*91f16700Schasinglulu #include <tegra_def.h>
17*91f16700Schasinglulu #include <tegra_private.h>
18*91f16700Schasinglulu 
19*91f16700Schasinglulu extern uint64_t tegra_bl31_phys_base;
20*91f16700Schasinglulu 
21*91f16700Schasinglulu #define MISCREG_AA64_RST_LOW		0x2004U
22*91f16700Schasinglulu #define MISCREG_AA64_RST_HIGH		0x2008U
23*91f16700Schasinglulu 
24*91f16700Schasinglulu #define CPU_RESET_MODE_AA64		1U
25*91f16700Schasinglulu 
26*91f16700Schasinglulu /*******************************************************************************
27*91f16700Schasinglulu  * Setup secondary CPU vectors
28*91f16700Schasinglulu  ******************************************************************************/
29*91f16700Schasinglulu void plat_secondary_setup(void)
30*91f16700Schasinglulu {
31*91f16700Schasinglulu 	uint32_t addr_low, addr_high;
32*91f16700Schasinglulu 	plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
33*91f16700Schasinglulu 	uint64_t cpu_reset_handler_base, cpu_reset_handler_size, tzdram_addr;
34*91f16700Schasinglulu 	uint64_t src_len_bytes = BL_END - tegra_bl31_phys_base;
35*91f16700Schasinglulu 
36*91f16700Schasinglulu 	INFO("Setting up secondary CPU boot\n");
37*91f16700Schasinglulu 
38*91f16700Schasinglulu 	tzdram_addr = params_from_bl2->tzdram_base +
39*91f16700Schasinglulu 		      tegra194_get_cpu_reset_handler_size();
40*91f16700Schasinglulu 
41*91f16700Schasinglulu 	/*
42*91f16700Schasinglulu 	 * The BL31 code resides in the TZSRAM which loses state
43*91f16700Schasinglulu 	 * when we enter System Suspend. Copy the wakeup trampoline
44*91f16700Schasinglulu 	 * code to TZDRAM to help us exit from System Suspend.
45*91f16700Schasinglulu 	 */
46*91f16700Schasinglulu 	cpu_reset_handler_base = tegra194_get_cpu_reset_handler_base();
47*91f16700Schasinglulu 	cpu_reset_handler_size = tegra194_get_cpu_reset_handler_size();
48*91f16700Schasinglulu 	memcpy((void *)((uintptr_t)params_from_bl2->tzdram_base),
49*91f16700Schasinglulu 		(void *)((uintptr_t)cpu_reset_handler_base),
50*91f16700Schasinglulu 		cpu_reset_handler_size);
51*91f16700Schasinglulu 
52*91f16700Schasinglulu 	/* TZDRAM base will be used as the "resume" address */
53*91f16700Schasinglulu 	addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64;
54*91f16700Schasinglulu 	addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU);
55*91f16700Schasinglulu 
56*91f16700Schasinglulu 	/* write lower 32 bits first, then the upper 11 bits */
57*91f16700Schasinglulu 	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
58*91f16700Schasinglulu 	assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW) == addr_low);
59*91f16700Schasinglulu 	mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
60*91f16700Schasinglulu 	assert(mmio_read_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH) == addr_high);
61*91f16700Schasinglulu 
62*91f16700Schasinglulu 	/* save reset vector to be used during SYSTEM_SUSPEND exit */
63*91f16700Schasinglulu 	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
64*91f16700Schasinglulu 			addr_low);
65*91f16700Schasinglulu 	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO) == addr_low);
66*91f16700Schasinglulu 	mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
67*91f16700Schasinglulu 			addr_high);
68*91f16700Schasinglulu 	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI) == addr_high);
69*91f16700Schasinglulu 	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO,
70*91f16700Schasinglulu 						(uint32_t)tzdram_addr);
71*91f16700Schasinglulu 	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO) == (uint32_t)tzdram_addr);
72*91f16700Schasinglulu 	mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI,
73*91f16700Schasinglulu 						(uint32_t)src_len_bytes);
74*91f16700Schasinglulu 	assert(mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI) == (uint32_t)src_len_bytes);
75*91f16700Schasinglulu }
76