blob: c31b0046b9adfcd4c6c173babd36069fa3b2cc85 [file] [log] [blame]
Angel Ponsa2ee7612020-04-04 18:51:15 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Patrick Georgi40a3e322015-06-22 19:41:29 +02002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Patrick Georgi40a3e322015-06-22 19:41:29 +02004#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
11static void enable_core_clocks(int cpu)
12{
Julius Werner7dcf9d52015-10-16 13:10:02 -070013 const uint32_t cpu_clocks[] = {
Patrick Georgi40a3e322015-06-22 19:41:29 +020014 [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
Elyes Haouas98a9b342023-09-10 10:39:11 +020024 assert(cpu < CONFIG_MAX_CPUS);
Patrick Georgi40a3e322015-06-22 19:41:29 +020025
26 /* Clear reset of CPU components. */
27 write32(CLK_RST_REG(rst_cpug_cmplx_clr), cpu_clocks[cpu]);
28}
29
30void 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);
Julius Werner55009af2019-12-02 22:03:27 -080048 setbits32(&sb->sb_aa64_reset_low, 1);
Patrick Georgi40a3e322015-06-22 19:41:29 +020049 write32(&sb->sb_aa64_reset_high, 0);
50}
51
52void start_cpu_silent(int cpu, void *entry_64)
53{
54 cpu_prepare_startup(entry_64);
55 enable_core_clocks(cpu);
56}
57
58void 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}