xref: /aosp_15_r20/external/coreboot/src/soc/nvidia/tegra210/cpu.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <assert.h>
5 #include <console/console.h>
6 #include <soc/addressmap.h>
7 #include <soc/clk_rst.h>
8 #include <soc/cpu.h>
9 #include <soc/secure_boot.h>
10 
enable_core_clocks(int cpu)11 static void enable_core_clocks(int cpu)
12 {
13 	const uint32_t cpu_clocks[] = {
14 		[0] = CRC_RST_CPUG_CLR_CPU0 | CRC_RST_CPUG_CLR_DBG0 |
15 		CRC_RST_CPUG_CLR_CORE0 | CRC_RST_CPUG_CLR_CX0,
16 		[1] = CRC_RST_CPUG_CLR_CPU1 | CRC_RST_CPUG_CLR_DBG1 |
17 		CRC_RST_CPUG_CLR_CORE1 | CRC_RST_CPUG_CLR_CX1,
18 		[2] = CRC_RST_CPUG_CLR_CPU2 | CRC_RST_CPUG_CLR_DBG2 |
19 		CRC_RST_CPUG_CLR_CORE2 | CRC_RST_CPUG_CLR_CX2,
20 		[3] = CRC_RST_CPUG_CLR_CPU3 | CRC_RST_CPUG_CLR_DBG3 |
21 		CRC_RST_CPUG_CLR_CORE3 | CRC_RST_CPUG_CLR_CX3,
22 	};
23 
24 	assert(cpu < CONFIG_MAX_CPUS);
25 
26 	/* Clear reset of CPU components. */
27 	write32(CLK_RST_REG(rst_cpug_cmplx_clr), cpu_clocks[cpu]);
28 }
29 
cpu_prepare_startup(void * entry_64)30 void cpu_prepare_startup(void *entry_64)
31 {
32 	struct tegra_secure_boot *sb =
33 		(struct tegra_secure_boot *)TEGRA_SB_BASE;
34 
35 	/*
36 	 * T210 TRM, section 12.4.4.2: "SB_AA64_RESET_LOW_0[0:0] is used to
37 	 * decide between CPU boot up in AARCH32 (=0) or AARCH64 (=1) mode.
38 	 * This bit .. is sampled only during 'cold reset of CPU'. Before the
39 	 * CPU is powered up, the CPU reset vector is loaded in
40 	 * EVP_CPU_REST_VECTOR_0 for 32-bit boot mode .... However, the CPU
41 	 * decides to boot in 32-/64-bit mode based on
42 	 * SB_AA64_RESET_LOW_0[0:0]. If this bit is set (=1), the CPU boots in
43 	 * 64-bit mode using SB_AA64_RESET_* as the reset address. If this bit
44 	 * is clear (=0), CPU boots in 32-bit mode using EVP_CPU_RESET_VECTOR."
45 	 */
46 
47 	write32(&sb->sb_aa64_reset_low, (uintptr_t)entry_64);
48 	setbits32(&sb->sb_aa64_reset_low, 1);
49 	write32(&sb->sb_aa64_reset_high, 0);
50 }
51 
start_cpu_silent(int cpu,void * entry_64)52 void start_cpu_silent(int cpu, void *entry_64)
53 {
54 	cpu_prepare_startup(entry_64);
55 	enable_core_clocks(cpu);
56 }
57 
start_cpu(int cpu,void * entry_64)58 void start_cpu(int cpu, void *entry_64)
59 {
60 	printk(BIOS_DEBUG, "Starting CPU%d @ %p.\n", cpu, entry_64);
61 	start_cpu_silent(cpu, entry_64);
62 }
63