blob: 7cb71c518bd3efc8247cbf14655c20e9d8bcd125 [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 */
27#define EARLY_TLB_SIZE 0xA000
28u8 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
58void enable_caches(void)
59{
60 /* deactivate the data cache, early enabled in arch_cpu_init() */
61 dcache_disable();
62 /*
63 * Force the call of setup_all_pgtables() in mmu_setup() by clearing tlb_fillptr
64 * to update the TLB location udpated in board_f.c::reserve_mmu
65 */
66 gd->arch.tlb_fillptr = 0;
67 dcache_enable();
68}
69
Patrice Chotardd29531c2023-10-27 16:43:04 +020070/*
71 * Force data-section, as .bss will not be valid
72 * when save_boot_params is invoked.
73 */
74static uintptr_t nt_fw_dtb __section(".data");
75
76uintptr_t get_stm32mp_bl2_dtb(void)
77{
78 return nt_fw_dtb;
79}
80
81/*
82 * Save the FDT address provided by TF-A in r2 at boot time
83 * This function is called from start.S
84 */
85void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2,
86 unsigned long r3)
87{
88 nt_fw_dtb = r2;
89
90 save_boot_params_ret();
91}
Patrick Delaunay7fcceb62022-05-30 19:20:45 +020092
93u32 get_bootmode(void)
94{
95 /* read bootmode from TAMP backup register */
96 return (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
97 TAMP_BOOT_MODE_SHIFT;
98}
99
100static void setup_boot_mode(void)
101{
102 const u32 serial_addr[] = {
103 STM32_USART1_BASE,
104 STM32_USART2_BASE,
105 STM32_USART3_BASE,
106 STM32_UART4_BASE,
107 STM32_UART5_BASE,
108 STM32_USART6_BASE,
109 STM32_UART7_BASE,
110 STM32_UART8_BASE,
111 STM32_UART9_BASE
112 };
113 const u32 sdmmc_addr[] = {
114 STM32_SDMMC1_BASE,
115 STM32_SDMMC2_BASE,
116 STM32_SDMMC3_BASE
117 };
118 char cmd[60];
119 u32 boot_ctx = readl(TAMP_BOOT_CONTEXT);
120 u32 boot_mode =
121 (boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT;
122 unsigned int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
123 u32 forced_mode = (boot_ctx & TAMP_BOOT_FORCED_MASK);
124 struct udevice *dev;
125
126 log_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d forced=%x\n",
127 __func__, boot_ctx, boot_mode, instance, forced_mode);
128 switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
129 case BOOT_SERIAL_UART:
130 if (instance > ARRAY_SIZE(serial_addr))
131 break;
132 /* serial : search associated node in devicetree */
133 sprintf(cmd, "serial@%x", serial_addr[instance]);
134 if (uclass_get_device_by_name(UCLASS_SERIAL, cmd, &dev)) {
135 /* restore console on error */
136 if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL))
137 gd->flags &= ~(GD_FLG_SILENT |
138 GD_FLG_DISABLE_CONSOLE);
139 log_err("uart%d = %s not found in device tree!\n",
140 instance + 1, cmd);
141 break;
142 }
143 sprintf(cmd, "%d", dev_seq(dev));
144 env_set("boot_device", "serial");
145 env_set("boot_instance", cmd);
146
147 /* restore console on uart when not used */
148 if (IS_ENABLED(CONFIG_CMD_STM32PROG_SERIAL) && gd->cur_serial_dev != dev) {
149 gd->flags &= ~(GD_FLG_SILENT |
150 GD_FLG_DISABLE_CONSOLE);
151 log_info("serial boot with console enabled!\n");
152 }
153 break;
154 case BOOT_SERIAL_USB:
155 env_set("boot_device", "usb");
156 env_set("boot_instance", "0");
157 break;
158 case BOOT_FLASH_SD:
159 case BOOT_FLASH_EMMC:
160 if (instance > ARRAY_SIZE(sdmmc_addr))
161 break;
162 /* search associated sdmmc node in devicetree */
163 sprintf(cmd, "mmc@%x", sdmmc_addr[instance]);
164 if (uclass_get_device_by_name(UCLASS_MMC, cmd, &dev)) {
165 printf("mmc%d = %s not found in device tree!\n",
166 instance, cmd);
167 break;
168 }
169 sprintf(cmd, "%d", dev_seq(dev));
170 env_set("boot_device", "mmc");
171 env_set("boot_instance", cmd);
172 break;
173 case BOOT_FLASH_NAND:
174 env_set("boot_device", "nand");
175 env_set("boot_instance", "0");
176 break;
177 case BOOT_FLASH_SPINAND:
178 env_set("boot_device", "spi-nand");
179 env_set("boot_instance", "0");
180 break;
181 case BOOT_FLASH_NOR:
182 env_set("boot_device", "nor");
183 if (IS_ENABLED(CONFIG_SYS_MAX_FLASH_BANKS))
184 sprintf(cmd, "%d", CONFIG_SYS_MAX_FLASH_BANKS);
185 else
186 sprintf(cmd, "%d", 0);
187 env_set("boot_instance", cmd);
188 break;
189 case BOOT_FLASH_HYPERFLASH:
190 env_set("boot_device", "nor");
191 env_set("boot_instance", "0");
192 break;
193 default:
194 env_set("boot_device", "invalid");
195 env_set("boot_instance", "");
196 log_err("unexpected boot mode = %x\n", boot_mode);
197 break;
198 }
199
200 switch (forced_mode) {
201 case BOOT_FASTBOOT:
202 log_info("Enter fastboot!\n");
203 env_set("preboot", "env set preboot; fastboot 0");
204 break;
205 case BOOT_STM32PROG:
206 env_set("boot_device", "usb");
207 env_set("boot_instance", "0");
208 break;
209 case BOOT_UMS_MMC0:
210 case BOOT_UMS_MMC1:
211 case BOOT_UMS_MMC2:
212 log_info("Enter UMS!\n");
213 instance = forced_mode - BOOT_UMS_MMC0;
214 sprintf(cmd, "env set preboot; ums 0 mmc %d", instance);
215 env_set("preboot", cmd);
216 break;
217 case BOOT_RECOVERY:
218 env_set("preboot", "env set preboot; run altbootcmd");
219 break;
220 case BOOT_NORMAL:
221 break;
222 default:
223 log_debug("unexpected forced boot mode = %x\n", forced_mode);
224 break;
225 }
226
227 /* clear TAMP for next reboot */
228 clrsetbits_le32(TAMP_BOOT_CONTEXT, TAMP_BOOT_FORCED_MASK, BOOT_NORMAL);
229}
230
231int arch_misc_init(void)
232{
233 setup_boot_mode();
234 setup_serial_number();
235 setup_mac_address();
236
237 return 0;
238}