blob: a9b9f4c5acd338ca5eccd6f2032254b00d0ef683 [file] [log] [blame]
Yann Gautieree8f5422019-02-14 11:13:25 +01001/*
Yann Gautier352d8632020-09-17 11:38:09 +02002 * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
Yann Gautieree8f5422019-02-14 11:13:25 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautiere3bf9132019-05-07 18:52:17 +02007#include <assert.h>
8
Yann Gautiera205a5c2021-08-30 15:06:54 +02009#include <drivers/clk.h>
Yann Gautiercd16df32021-06-04 14:04:05 +020010#include <drivers/st/stm32_gpio.h>
11#include <drivers/st/stm32_iwdg.h>
Yann Gautier6eef5252021-12-10 17:04:40 +010012#include <lib/mmio.h>
Yann Gautiercd16df32021-06-04 14:04:05 +020013#include <lib/xlat_tables/xlat_tables_v2.h>
Yann Gautier0c810882021-12-17 09:53:04 +010014#include <libfdt.h>
Yann Gautier35dc0772019-05-13 18:34:48 +020015
Sughosh Ganu03e2f802021-12-01 15:56:27 +053016#include <plat/common/platform.h>
Yann Gautieree8f5422019-02-14 11:13:25 +010017#include <platform_def.h>
18
Yann Gautier35dc0772019-05-13 18:34:48 +020019/* Internal layout of the 32bit OTP word board_id */
20#define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16)
21#define BOARD_ID_BOARD_NB_SHIFT 16
Patrick Delaunay7704f162020-01-08 10:05:14 +010022#define BOARD_ID_VARCPN_MASK GENMASK(15, 12)
23#define BOARD_ID_VARCPN_SHIFT 12
Yann Gautier35dc0772019-05-13 18:34:48 +020024#define BOARD_ID_REVISION_MASK GENMASK(11, 8)
25#define BOARD_ID_REVISION_SHIFT 8
Patrick Delaunay7704f162020-01-08 10:05:14 +010026#define BOARD_ID_VARFG_MASK GENMASK(7, 4)
27#define BOARD_ID_VARFG_SHIFT 4
Yann Gautier35dc0772019-05-13 18:34:48 +020028#define BOARD_ID_BOM_MASK GENMASK(3, 0)
29
30#define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \
31 BOARD_ID_BOARD_NB_SHIFT)
Patrick Delaunay7704f162020-01-08 10:05:14 +010032#define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \
33 BOARD_ID_VARCPN_SHIFT)
Yann Gautier35dc0772019-05-13 18:34:48 +020034#define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \
35 BOARD_ID_REVISION_SHIFT)
Patrick Delaunay7704f162020-01-08 10:05:14 +010036#define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \
37 BOARD_ID_VARFG_SHIFT)
Yann Gautier35dc0772019-05-13 18:34:48 +020038#define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK)
39
Yann Gautier82000472020-02-05 16:24:21 +010040#if STM32MP13
41#define TAMP_BOOT_MODE_BACKUP_REG_ID U(30)
42#endif
43#if STM32MP15
Yann Gautier6eef5252021-12-10 17:04:40 +010044#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
Yann Gautier82000472020-02-05 16:24:21 +010045#endif
Yann Gautier6eef5252021-12-10 17:04:40 +010046#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
47#define TAMP_BOOT_MODE_ITF_SHIFT 8
48
Sughosh Ganu03e2f802021-12-01 15:56:27 +053049#define TAMP_BOOT_COUNTER_REG_ID U(21)
50
Etienne Carriere72369b12019-12-08 08:17:56 +010051#if defined(IMAGE_BL2)
52#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010053 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010054 MT_MEMORY | \
55 MT_RW | \
56 MT_SECURE | \
57 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-12-08 08:17:56 +010058#elif defined(IMAGE_BL32)
59#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
60 STM32MP_SEC_SYSRAM_SIZE, \
61 MT_MEMORY | \
62 MT_RW | \
63 MT_SECURE | \
64 MT_EXECUTE_NEVER)
Yann Gautieree8f5422019-02-14 11:13:25 +010065
Etienne Carriere72369b12019-12-08 08:17:56 +010066/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
67#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
68 STM32MP_NS_SYSRAM_SIZE, \
69 MT_DEVICE | \
70 MT_RW | \
71 MT_NS | \
72 MT_EXECUTE_NEVER)
73#endif
74
Yann Gautier84d994b2020-04-14 18:08:50 +020075#if STM32MP13
76#define MAP_SRAM_ALL MAP_REGION_FLAT(SRAMS_BASE, \
77 SRAMS_SIZE_2MB_ALIGNED, \
78 MT_MEMORY | \
79 MT_RW | \
80 MT_SECURE | \
81 MT_EXECUTE_NEVER)
82#endif
83
Yann Gautieree8f5422019-02-14 11:13:25 +010084#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
85 STM32MP1_DEVICE1_SIZE, \
86 MT_DEVICE | \
87 MT_RW | \
88 MT_SECURE | \
89 MT_EXECUTE_NEVER)
90
91#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
92 STM32MP1_DEVICE2_SIZE, \
93 MT_DEVICE | \
94 MT_RW | \
95 MT_SECURE | \
96 MT_EXECUTE_NEVER)
97
98#if defined(IMAGE_BL2)
99static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100100 MAP_SEC_SYSRAM,
Yann Gautier84d994b2020-04-14 18:08:50 +0200101#if STM32MP13
102 MAP_SRAM_ALL,
103#endif
Yann Gautieree8f5422019-02-14 11:13:25 +0100104 MAP_DEVICE1,
Yann Gautier352d8632020-09-17 11:38:09 +0200105#if STM32MP_RAW_NAND
Yann Gautieree8f5422019-02-14 11:13:25 +0100106 MAP_DEVICE2,
Yann Gautier352d8632020-09-17 11:38:09 +0200107#endif
Yann Gautieree8f5422019-02-14 11:13:25 +0100108 {0}
109};
110#endif
111#if defined(IMAGE_BL32)
112static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100113 MAP_SEC_SYSRAM,
114 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +0100115 MAP_DEVICE1,
116 MAP_DEVICE2,
117 {0}
118};
119#endif
120
121void configure_mmu(void)
122{
123 mmap_add(stm32mp1_mmap);
124 init_xlat_tables();
125
126 enable_mmu_svc_mon(0);
127}
Yann Gautiere3bf9132019-05-07 18:52:17 +0200128
Etienne Carriere66b04522019-12-02 10:05:02 +0100129uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
130{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100131#if STM32MP13
132 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
133#endif
134#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100135 if (bank == GPIO_BANK_Z) {
136 return GPIOZ_BASE;
137 }
138
139 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100140#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100141
142 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
143}
144
145uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
146{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100147#if STM32MP13
148 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
149#endif
150#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100151 if (bank == GPIO_BANK_Z) {
152 return 0;
153 }
154
155 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100156#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100157
158 return bank * GPIO_BANK_OFFSET;
159}
160
Yann Gautier2b79c372021-06-11 10:54:56 +0200161bool stm32_gpio_is_secure_at_reset(unsigned int bank)
162{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100163#if STM32MP13
164 return true;
165#endif
166#if STM32MP15
Yann Gautier2b79c372021-06-11 10:54:56 +0200167 if (bank == GPIO_BANK_Z) {
168 return true;
169 }
170
171 return false;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100172#endif
Yann Gautier2b79c372021-06-11 10:54:56 +0200173}
174
Yann Gautiere3bf9132019-05-07 18:52:17 +0200175unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
176{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100177#if STM32MP13
178 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
179#endif
180#if STM32MP15
Yann Gautiere3bf9132019-05-07 18:52:17 +0200181 if (bank == GPIO_BANK_Z) {
182 return GPIOZ;
183 }
184
185 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100186#endif
Yann Gautiere3bf9132019-05-07 18:52:17 +0200187
188 return GPIOA + (bank - GPIO_BANK_A);
189}
Yann Gautier091eab52019-06-04 18:06:34 +0200190
Etienne Carriered81dadf2020-04-25 11:14:45 +0200191int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
192{
193 switch (bank) {
194 case GPIO_BANK_A:
195 case GPIO_BANK_B:
196 case GPIO_BANK_C:
197 case GPIO_BANK_D:
198 case GPIO_BANK_E:
199 case GPIO_BANK_F:
200 case GPIO_BANK_G:
201 case GPIO_BANK_H:
202 case GPIO_BANK_I:
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100203#if STM32MP15
Etienne Carriered81dadf2020-04-25 11:14:45 +0200204 case GPIO_BANK_J:
205 case GPIO_BANK_K:
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100206#endif
Etienne Carriered81dadf2020-04-25 11:14:45 +0200207 return fdt_path_offset(fdt, "/soc/pin-controller");
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100208#if STM32MP15
Etienne Carriered81dadf2020-04-25 11:14:45 +0200209 case GPIO_BANK_Z:
210 return fdt_path_offset(fdt, "/soc/pin-controller-z");
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100211#endif
Etienne Carriered81dadf2020-04-25 11:14:45 +0200212 default:
213 panic();
214 }
215}
216
Yann Gautier3d8497c2021-10-18 16:06:22 +0200217#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200218/*
219 * UART Management
220 */
221static const uintptr_t stm32mp1_uart_addresses[8] = {
222 USART1_BASE,
223 USART2_BASE,
224 USART3_BASE,
225 UART4_BASE,
226 UART5_BASE,
227 USART6_BASE,
228 UART7_BASE,
229 UART8_BASE,
230};
231
232uintptr_t get_uart_address(uint32_t instance_nb)
233{
234 if ((instance_nb == 0U) ||
235 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
236 return 0U;
237 }
238
239 return stm32mp1_uart_addresses[instance_nb - 1U];
240}
241#endif
242
Yann Gautiercd16df32021-06-04 14:04:05 +0200243#if STM32MP_USB_PROGRAMMER
244struct gpio_bank_pin_list {
245 uint32_t bank;
246 uint32_t pin;
247};
248
249static const struct gpio_bank_pin_list gpio_list[] = {
250 { /* USART2_RX: GPIOA3 */
251 .bank = 0U,
252 .pin = 3U,
253 },
254 { /* USART3_RX: GPIOB12 */
255 .bank = 1U,
256 .pin = 12U,
257 },
258 { /* UART4_RX: GPIOB2 */
259 .bank = 1U,
260 .pin = 2U,
261 },
262 { /* UART5_RX: GPIOB4 */
263 .bank = 1U,
264 .pin = 5U,
265 },
266 { /* USART6_RX: GPIOC7 */
267 .bank = 2U,
268 .pin = 7U,
269 },
270 { /* UART7_RX: GPIOF6 */
271 .bank = 5U,
272 .pin = 6U,
273 },
274 { /* UART8_RX: GPIOE0 */
275 .bank = 4U,
276 .pin = 0U,
277 },
278};
279
280void stm32mp1_deconfigure_uart_pins(void)
281{
282 size_t i;
283
284 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
285 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
286 }
287}
288#endif
289
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200290uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200291{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200292#if STM32MP13
293 return stm32mp1_syscfg_get_chip_version();
294#endif
295#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200296 uint32_t version = 0U;
297
298 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
299 INFO("Cannot get CPU version, debug disabled\n");
300 return 0U;
301 }
302
303 return version;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200304#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200305}
Yann Gautierc7374052019-06-04 18:02:37 +0200306
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200307uint32_t stm32mp_get_chip_dev_id(void)
308{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200309#if STM32MP13
310 return stm32mp1_syscfg_get_chip_dev_id();
311#endif
312#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200313 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200314
Yann Gautierc7374052019-06-04 18:02:37 +0200315 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200316 INFO("Use default chip ID, debug disabled\n");
317 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200318 }
319
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200320 return dev_id;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200321#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200322}
323
324static uint32_t get_part_number(void)
325{
326 static uint32_t part_number;
327
328 if (part_number != 0U) {
329 return part_number;
330 }
331
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100332 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200333 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200334 }
335
336 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
337 PART_NUMBER_OTP_PART_SHIFT;
338
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200339 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200340
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200341 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200342}
343
Yann Gautier16188f32020-02-12 15:38:34 +0100344#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200345static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200346{
347 uint32_t package;
348
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100349 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200350 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200351 }
352
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200353 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200354 PACKAGE_OTP_PKG_SHIFT;
355
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200356 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200357}
Yann Gautier16188f32020-02-12 15:38:34 +0100358#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200359
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200360void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200361{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200362 char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200363
364 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200365 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100366#if STM32MP13
367 case STM32MP135F_PART_NB:
368 cpu_s = "135F";
369 break;
370 case STM32MP135D_PART_NB:
371 cpu_s = "135D";
372 break;
373 case STM32MP135C_PART_NB:
374 cpu_s = "135C";
375 break;
376 case STM32MP135A_PART_NB:
377 cpu_s = "135A";
378 break;
379 case STM32MP133F_PART_NB:
380 cpu_s = "133F";
381 break;
382 case STM32MP133D_PART_NB:
383 cpu_s = "133D";
384 break;
385 case STM32MP133C_PART_NB:
386 cpu_s = "133C";
387 break;
388 case STM32MP133A_PART_NB:
389 cpu_s = "133A";
390 break;
391 case STM32MP131F_PART_NB:
392 cpu_s = "131F";
393 break;
394 case STM32MP131D_PART_NB:
395 cpu_s = "131D";
396 break;
397 case STM32MP131C_PART_NB:
398 cpu_s = "131C";
399 break;
400 case STM32MP131A_PART_NB:
401 cpu_s = "131A";
402 break;
403#endif
404#if STM32MP15
Yann Gautierc7374052019-06-04 18:02:37 +0200405 case STM32MP157C_PART_NB:
406 cpu_s = "157C";
407 break;
408 case STM32MP157A_PART_NB:
409 cpu_s = "157A";
410 break;
411 case STM32MP153C_PART_NB:
412 cpu_s = "153C";
413 break;
414 case STM32MP153A_PART_NB:
415 cpu_s = "153A";
416 break;
417 case STM32MP151C_PART_NB:
418 cpu_s = "151C";
419 break;
420 case STM32MP151A_PART_NB:
421 cpu_s = "151A";
422 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200423 case STM32MP157F_PART_NB:
424 cpu_s = "157F";
425 break;
426 case STM32MP157D_PART_NB:
427 cpu_s = "157D";
428 break;
429 case STM32MP153F_PART_NB:
430 cpu_s = "153F";
431 break;
432 case STM32MP153D_PART_NB:
433 cpu_s = "153D";
434 break;
435 case STM32MP151F_PART_NB:
436 cpu_s = "151F";
437 break;
438 case STM32MP151D_PART_NB:
439 cpu_s = "151D";
440 break;
Yann Gautier16188f32020-02-12 15:38:34 +0100441#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200442 default:
443 cpu_s = "????";
444 break;
445 }
446
447 /* Package */
Yann Gautier16188f32020-02-12 15:38:34 +0100448#if STM32MP13
449 /* On STM32MP13, package is not present in OTP */
450 pkg = "";
451#endif
452#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200453 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200454 case PKG_AA_LFBGA448:
455 pkg = "AA";
456 break;
457 case PKG_AB_LFBGA354:
458 pkg = "AB";
459 break;
460 case PKG_AC_TFBGA361:
461 pkg = "AC";
462 break;
463 case PKG_AD_TFBGA257:
464 pkg = "AD";
465 break;
466 default:
467 pkg = "??";
468 break;
469 }
Yann Gautier16188f32020-02-12 15:38:34 +0100470#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200471
472 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200473 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200474 case STM32MP1_REV_B:
475 cpu_r = "B";
476 break;
Lionel Debieve2d64b532019-06-25 10:40:37 +0200477 case STM32MP1_REV_Z:
478 cpu_r = "Z";
479 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200480 default:
481 cpu_r = "?";
482 break;
483 }
484
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200485 snprintf(name, STM32_SOC_NAME_SIZE,
486 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
487}
488
489void stm32mp_print_cpuinfo(void)
490{
491 char name[STM32_SOC_NAME_SIZE];
492
493 stm32mp_get_soc_name(name);
494 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200495}
496
Yann Gautier35dc0772019-05-13 18:34:48 +0200497void stm32mp_print_boardinfo(void)
498{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100499 uint32_t board_id = 0;
Yann Gautier35dc0772019-05-13 18:34:48 +0200500
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100501 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier35dc0772019-05-13 18:34:48 +0200502 return;
503 }
504
Yann Gautier35dc0772019-05-13 18:34:48 +0200505 if (board_id != 0U) {
506 char rev[2];
507
508 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
509 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200510 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200511 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100512 BOARD_ID2VARCPN(board_id),
513 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200514 rev,
515 BOARD_ID2BOM(board_id));
516 }
517}
518
Yann Gautieraf19ff92019-06-04 18:23:10 +0200519/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
520bool stm32mp_is_single_core(void)
521{
Yann Gautier6bd30e22020-02-06 15:34:16 +0100522#if STM32MP13
523 return true;
524#endif
525#if STM32MP15
Yann Gautier2f3b5602021-10-19 13:31:06 +0200526 bool single_core = false;
527
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200528 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200529 case STM32MP151A_PART_NB:
530 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200531 case STM32MP151D_PART_NB:
532 case STM32MP151F_PART_NB:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200533 single_core = true;
534 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200535 default:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200536 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200537 }
Yann Gautier2f3b5602021-10-19 13:31:06 +0200538
539 return single_core;
Yann Gautier6bd30e22020-02-06 15:34:16 +0100540#endif
Yann Gautieraf19ff92019-06-04 18:23:10 +0200541}
542
Lionel Debieve0e73d732019-09-16 12:17:09 +0200543/* Return true when device is in closed state */
544bool stm32mp_is_closed_device(void)
545{
546 uint32_t value;
547
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100548 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debieve0e73d732019-09-16 12:17:09 +0200549 return true;
550 }
551
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100552#if STM32MP13
553 value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT;
554
555 switch (value) {
556 case CFG0_OPEN_DEVICE:
557 return false;
558 case CFG0_CLOSED_DEVICE:
559 case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
560 case CFG0_CLOSED_DEVICE_NO_JTAG:
561 return true;
562 default:
563 panic();
564 }
565#endif
566#if STM32MP15
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100567 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100568#endif
Lionel Debieve0e73d732019-09-16 12:17:09 +0200569}
570
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100571/* Return true when device supports secure boot */
572bool stm32mp_is_auth_supported(void)
573{
574 bool supported = false;
575
576 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100577#if STM32MP13
578 case STM32MP131C_PART_NB:
579 case STM32MP131F_PART_NB:
580 case STM32MP133C_PART_NB:
581 case STM32MP133F_PART_NB:
582 case STM32MP135C_PART_NB:
583 case STM32MP135F_PART_NB:
584#endif
585#if STM32MP15
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100586 case STM32MP151C_PART_NB:
587 case STM32MP151F_PART_NB:
588 case STM32MP153C_PART_NB:
589 case STM32MP153F_PART_NB:
590 case STM32MP157C_PART_NB:
591 case STM32MP157F_PART_NB:
Yann Gautier16188f32020-02-12 15:38:34 +0100592#endif
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100593 supported = true;
594 break;
595 default:
596 break;
597 }
598
599 return supported;
600}
601
Yann Gautier091eab52019-06-04 18:06:34 +0200602uint32_t stm32_iwdg_get_instance(uintptr_t base)
603{
604 switch (base) {
605 case IWDG1_BASE:
606 return IWDG1_INST;
607 case IWDG2_BASE:
608 return IWDG2_INST;
609 default:
610 panic();
611 }
612}
613
614uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
615{
616 uint32_t iwdg_cfg = 0U;
617 uint32_t otp_value;
618
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100619 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200620 panic();
621 }
622
623 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
624 iwdg_cfg |= IWDG_HW_ENABLED;
625 }
626
627 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
628 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
629 }
630
631 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
632 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
633 }
634
635 return iwdg_cfg;
636}
637
638#if defined(IMAGE_BL2)
639uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
640{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100641 uint32_t otp_value;
Yann Gautier091eab52019-06-04 18:06:34 +0200642 uint32_t otp;
643 uint32_t result;
644
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100645 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
646 panic();
647 }
648
649 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200650 panic();
651 }
652
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100653 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
654 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200655 }
656
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100657 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
658 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200659 }
660
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100661 result = bsec_write_otp(otp_value, otp);
Yann Gautier091eab52019-06-04 18:06:34 +0200662 if (result != BSEC_OK) {
663 return result;
664 }
665
666 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100667 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
668 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier091eab52019-06-04 18:06:34 +0200669 return BSEC_LOCK_FAIL;
670 }
671
672 return BSEC_OK;
673}
674#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100675
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200676#if STM32MP_USE_STM32IMAGE
Yann Gautier8f268c82020-02-26 13:39:44 +0100677/* Get the non-secure DDR size */
678uint32_t stm32mp_get_ddr_ns_size(void)
679{
680 static uint32_t ddr_ns_size;
681 uint32_t ddr_size;
682
683 if (ddr_ns_size != 0U) {
684 return ddr_ns_size;
685 }
686
687 ddr_size = dt_get_ddr_size();
688 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
689 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
690 panic();
691 }
692
693 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
694
695 return ddr_ns_size;
696}
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200697#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier6eef5252021-12-10 17:04:40 +0100698
699void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
700{
Nicolas Toromanoffbb82b1b2022-02-09 12:26:31 +0100701 uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautier6eef5252021-12-10 17:04:40 +0100702
Yann Gautiera205a5c2021-08-30 15:06:54 +0200703 clk_enable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100704
705 mmio_clrsetbits_32(bkpr_itf_idx,
706 TAMP_BOOT_MODE_ITF_MASK,
707 ((interface << 4) | (instance & 0xFU)) <<
708 TAMP_BOOT_MODE_ITF_SHIFT);
709
Yann Gautiera205a5c2021-08-30 15:06:54 +0200710 clk_disable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100711}
Yann Gautieraaee0612020-12-16 12:04:06 +0100712
713void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
714{
715 static uint32_t itf;
716
717 if (itf == 0U) {
Nicolas Toromanoffbb82b1b2022-02-09 12:26:31 +0100718 uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautieraaee0612020-12-16 12:04:06 +0100719
Yann Gautiera205a5c2021-08-30 15:06:54 +0200720 clk_enable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100721
722 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
723 TAMP_BOOT_MODE_ITF_SHIFT;
724
Yann Gautiera205a5c2021-08-30 15:06:54 +0200725 clk_disable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100726 }
727
728 *interface = itf >> 4;
729 *instance = itf & 0xFU;
730}
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530731
732#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
733void stm32mp1_fwu_set_boot_idx(void)
734{
735 clk_enable(RTCAPB);
736 mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
737 plat_fwu_get_boot_idx());
738 clk_disable(RTCAPB);
739}
740#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */