blob: c3b87d7f9810b637f09e9375fed67d12693dd458 [file] [log] [blame]
Patrice Chotardd29531c2023-10-27 16:43:04 +02001// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
2/*
3 * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
4 */
5
6#define LOG_CATEGORY LOGC_ARCH
7
Patrice Chotardd29531c2023-10-27 16:43:04 +02008#include <clk.h>
9#include <cpu_func.h>
10#include <debug_uart.h>
11#include <env_internal.h>
12#include <init.h>
13#include <misc.h>
14#include <wdt.h>
15#include <asm/io.h>
16#include <asm/arch/stm32.h>
17#include <asm/arch/sys_proto.h>
18#include <asm/system.h>
19#include <dm/device.h>
20#include <dm/lists.h>
21#include <dm/uclass.h>
22
23/*
24 * early TLB into the .data section so that it not get cleared
25 * with 16kB alignment
26 */
Patrice Chotardfd90b9c2025-04-01 18:14:18 +020027#define EARLY_TLB_SIZE 0x10000
Patrice Chotardd29531c2023-10-27 16:43:04 +020028u8 early_tlb[EARLY_TLB_SIZE] __section(".data") __aligned(0x4000);
29
30/*
31 * initialize the MMU and activate cache in U-Boot pre-reloc stage
32 * MMU/TLB is updated in enable_caches() for U-Boot after relocation
33 */
34static void early_enable_caches(void)
35{
36 if (CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
37 return;
38
39 if (!(CONFIG_IS_ENABLED(SYS_ICACHE_OFF) && CONFIG_IS_ENABLED(SYS_DCACHE_OFF))) {
40 gd->arch.tlb_size = EARLY_TLB_SIZE;
41 gd->arch.tlb_addr = (unsigned long)&early_tlb;
42 }
43 /* enable MMU (default configuration) */
44 dcache_enable();
45}
46
47/*
48 * Early system init
49 */
50int arch_cpu_init(void)
51{
52 icache_enable();
53 early_enable_caches();
54
55 return 0;
56}
57
Patrice Chotardf8521722025-04-03 15:04:35 +020058int mach_cpu_init(void)
59{
60 u32 boot_mode;
61
62 boot_mode = get_bootmode();
63
64 if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) &&
65 (boot_mode & TAMP_BOOT_DEVICE_MASK) == BOOT_SERIAL_UART)
66 gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
67
68 return 0;
69}
70
Patrice Chotardd29531c2023-10-27 16:43:04 +020071void enable_caches(void)
72{
73 /* deactivate the data cache, early enabled in arch_cpu_init() */
74 dcache_disable();
75 /*
76 * Force the call of setup_all_pgtables() in mmu_setup() by clearing tlb_fillptr
77 * to update the TLB location udpated in board_f.c::reserve_mmu
78 */
79 gd->arch.tlb_fillptr = 0;
80 dcache_enable();
81}
82
Patrice Chotardd29531c2023-10-27 16:43:04 +020083/*
84 * Force data-section, as .bss will not be valid
85 * when save_boot_params is invoked.
86 */
87static uintptr_t nt_fw_dtb __section(".data");
88
89uintptr_t get_stm32mp_bl2_dtb(void)
90{
91 return nt_fw_dtb;
92}
93
94/*
95 * Save the FDT address provided by TF-A in r2 at boot time
96 * This function is called from start.S
97 */
98void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
99 unsigned long r3)
100{
101 nt_fw_dtb = r2;
102
103 save_boot_params_ret();
104}
Patrick Delaunay7fcceb62022-05-30 19:20:45 +0200105
106u32 get_bootmode(void)
107{
108 /* read bootmode from TAMP backup register */
109 return (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
110 TAMP_BOOT_MODE_SHIFT;
111}
112
113static void setup_boot_mode(void)
114{
115 const u32 serial_addr[] = {
116 STM32_USART1_BASE,
117 STM32_USART2_BASE,
118 STM32_USART3_BASE,
119 STM32_UART4_BASE,
120 STM32_UART5_BASE,
121 STM32_USART6_BASE,
122 STM32_UART7_BASE,
123 STM32_UART8_BASE,
124 STM32_UART9_BASE
125 };
126 const u32 sdmmc_addr[] = {
127 STM32_SDMMC1_BASE,
128 STM32_SDMMC2_BASE,
129 STM32_SDMMC3_BASE
130 };
131 char cmd[60];
132 u32 boot_ctx = readl(TAMP_BOOT_CONTEXT);
133 u32 boot_mode =
134 (boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT;
135 unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
136 u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK);
137 struct udevice *dev;
138
139 log_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n",
140 __func__, boot_ctx, boot_mode, instance, forced_mode);
141 switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
142 case BOOT_SERIAL_UART:
143 if (instance > ARRAY_SIZE(serial_addr))
144 break;
145 /* serial : search associated node in devicetree */
146 sprintf(cmd, "serial@%x", serial_addr[instance]);
147 if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev)) {
148 /* restore console on error */
149 if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL))
150 gd->flags &= ~(GD_FLG_SILENT |
151 GD_FLG_DISABLE_CONSOLE);
152 log_err("uart%d = %s not found in device tree!\n",
153 instance + 1, cmd);
154 break;
155 }
156 sprintf(cmd, "%d", dev_seq(dev));
157 env_set("boot_device", "serial");
158 env_set("boot_instance", cmd);
159
160 /* restore console on uart when not used */
161 if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && gd->cur_serial_dev != dev) {
162 gd->flags &= ~(GD_FLG_SILENT |
163 GD_FLG_DISABLE_CONSOLE);
164 log_info("serial boot with console enabled!\n");
165 }
166 break;
167 case BOOT_SERIAL_USB:
168 env_set("boot_device", "usb");
169 env_set("boot_instance", "0");
170 break;
171 case BOOT_FLASH_SD:
172 case BOOT_FLASH_EMMC:
173 if (instance > ARRAY_SIZE(sdmmc_addr))
174 break;
175 /* search associated sdmmc node in devicetree */
176 sprintf(cmd, "mmc@%x", sdmmc_addr[instance]);
177 if (uclass_get_device_by_name(UCLASS_MMC, cmd, &dev)) {
178 printf("mmc%d = %s not found in device tree!\n",
179 instance, cmd);
180 break;
181 }
182 sprintf(cmd, "%d", dev_seq(dev));
183 env_set("boot_device", "mmc");
184 env_set("boot_instance", cmd);
185 break;
186 case BOOT_FLASH_NAND:
187 env_set("boot_device", "nand");
188 env_set("boot_instance", "0");
189 break;
190 case BOOT_FLASH_SPINAND:
191 env_set("boot_device", "spi-nand");
192 env_set("boot_instance", "0");
193 break;
194 case BOOT_FLASH_NOR:
195 env_set("boot_device", "nor");
196 if (IS_ENABLED(CONFIG_SYS_MAX_FLASH_BANKS))
197 sprintf(cmd, "%d", CONFIG_SYS_MAX_FLASH_BANKS);
198 else
199 sprintf(cmd, "%d", 0);
200 env_set("boot_instance", cmd);
201 break;
202 case BOOT_FLASH_HYPERFLASH:
203 env_set("boot_device", "nor");
204 env_set("boot_instance", "0");
205 break;
206 default:
207 env_set("boot_device", "invalid");
208 env_set("boot_instance", "");
209 log_err("unexpected boot mode = %x\n", boot_mode);
210 break;
211 }
212
213 switch (forced_mode) {
214 case BOOT_FASTBOOT:
215 log_info("Enter fastboot!\n");
216 env_set("preboot", "env set preboot; fastboot 0");
217 break;
218 case BOOT_STM32PROG:
219 env_set("boot_device", "usb");
220 env_set("boot_instance", "0");
221 break;
222 case BOOT_UMS_MMC0:
223 case BOOT_UMS_MMC1:
224 case BOOT_UMS_MMC2:
225 log_info("Enter UMS!\n");
226 instance = forced_mode - BOOT_UMS_MMC0;
227 sprintf(cmd, "env set preboot; ums 0 mmc %d", instance);
228 env_set("preboot", cmd);
229 break;
230 case BOOT_RECOVERY:
231 env_set("preboot", "env set preboot; run altbootcmd");
232 break;
233 case BOOT_NORMAL:
234 break;
235 default:
236 log_debug("unexpected forced boot mode = %x\n", forced_mode);
237 break;
238 }
239
240 /* clear TAMP for next reboot */
241 clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL);
242}
243
244int arch_misc_init(void)
245{
246 setup_boot_mode();
247 setup_serial_number();
248 setup_mac_address();
249
250 return 0;
251}