blob: ea35055a83a90fe5c22944a13dcb8c0ec915b362 [file] [log] [blame]
Yann Gautieree8f5422019-02-14 11:13:25 +01001/*
Yann Gautier8402c292022-06-29 17:03:36 +02002 * Copyright (c) 2015-2023, 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 Gautier82000472020-02-05 16:24:21 +010019#if STM32MP13
20#define TAMP_BOOT_MODE_BACKUP_REG_ID U(30)
21#endif
22#if STM32MP15
Yann Gautier6eef5252021-12-10 17:04:40 +010023#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
Yann Gautier82000472020-02-05 16:24:21 +010024#endif
Yann Gautier6eef5252021-12-10 17:04:40 +010025
Yann Gautier9bbd26a2022-03-28 17:49:38 +020026/*
27 * Backup register to store fwu update information.
28 * It should be writeable only by secure world, but also readable by non secure
29 * (so it should be in Zone 2).
30 */
31#define TAMP_BOOT_FWU_INFO_REG_ID U(10)
Igor Opaniukf07e8f32022-06-23 21:19:26 +030032#define TAMP_BOOT_FWU_INFO_IDX_MSK GENMASK(3, 0)
Yann Gautier9bbd26a2022-03-28 17:49:38 +020033#define TAMP_BOOT_FWU_INFO_IDX_OFF U(0)
Igor Opaniukf07e8f32022-06-23 21:19:26 +030034#define TAMP_BOOT_FWU_INFO_CNT_MSK GENMASK(7, 4)
Yann Gautier9bbd26a2022-03-28 17:49:38 +020035#define TAMP_BOOT_FWU_INFO_CNT_OFF U(4)
Sughosh Ganu03e2f802021-12-01 15:56:27 +053036
Etienne Carriere72369b12019-12-08 08:17:56 +010037#if defined(IMAGE_BL2)
38#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010039 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010040 MT_MEMORY | \
41 MT_RW | \
42 MT_SECURE | \
43 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-12-08 08:17:56 +010044#elif defined(IMAGE_BL32)
45#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
46 STM32MP_SEC_SYSRAM_SIZE, \
47 MT_MEMORY | \
48 MT_RW | \
49 MT_SECURE | \
50 MT_EXECUTE_NEVER)
Yann Gautieree8f5422019-02-14 11:13:25 +010051
Etienne Carriere72369b12019-12-08 08:17:56 +010052/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
53#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
54 STM32MP_NS_SYSRAM_SIZE, \
55 MT_DEVICE | \
56 MT_RW | \
57 MT_NS | \
58 MT_EXECUTE_NEVER)
59#endif
60
Yann Gautier84d994b2020-04-14 18:08:50 +020061#if STM32MP13
62#define MAP_SRAM_ALL MAP_REGION_FLAT(SRAMS_BASE, \
63 SRAMS_SIZE_2MB_ALIGNED, \
64 MT_MEMORY | \
65 MT_RW | \
66 MT_SECURE | \
67 MT_EXECUTE_NEVER)
68#endif
69
Yann Gautieree8f5422019-02-14 11:13:25 +010070#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
71 STM32MP1_DEVICE1_SIZE, \
72 MT_DEVICE | \
73 MT_RW | \
74 MT_SECURE | \
75 MT_EXECUTE_NEVER)
76
77#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
78 STM32MP1_DEVICE2_SIZE, \
79 MT_DEVICE | \
80 MT_RW | \
81 MT_SECURE | \
82 MT_EXECUTE_NEVER)
83
84#if defined(IMAGE_BL2)
85static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010086 MAP_SEC_SYSRAM,
Yann Gautier84d994b2020-04-14 18:08:50 +020087#if STM32MP13
88 MAP_SRAM_ALL,
89#endif
Yann Gautieree8f5422019-02-14 11:13:25 +010090 MAP_DEVICE1,
Yann Gautier352d8632020-09-17 11:38:09 +020091#if STM32MP_RAW_NAND
Yann Gautieree8f5422019-02-14 11:13:25 +010092 MAP_DEVICE2,
Yann Gautier352d8632020-09-17 11:38:09 +020093#endif
Yann Gautieree8f5422019-02-14 11:13:25 +010094 {0}
95};
96#endif
97#if defined(IMAGE_BL32)
98static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010099 MAP_SEC_SYSRAM,
100 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +0100101 MAP_DEVICE1,
102 MAP_DEVICE2,
103 {0}
104};
105#endif
106
107void configure_mmu(void)
108{
109 mmap_add(stm32mp1_mmap);
110 init_xlat_tables();
111
112 enable_mmu_svc_mon(0);
113}
Yann Gautiere3bf9132019-05-07 18:52:17 +0200114
Etienne Carriere66b04522019-12-02 10:05:02 +0100115uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
116{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100117#if STM32MP13
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100118 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100119#endif
120#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100121 if (bank == GPIO_BANK_Z) {
122 return GPIOZ_BASE;
123 }
124
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100125 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100126#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100127
128 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
129}
130
131uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
132{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100133#if STM32MP13
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100134 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100135#endif
136#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100137 if (bank == GPIO_BANK_Z) {
138 return 0;
139 }
140
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100141 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100142#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100143
144 return bank * GPIO_BANK_OFFSET;
145}
146
Yann Gautier2b79c372021-06-11 10:54:56 +0200147bool stm32_gpio_is_secure_at_reset(unsigned int bank)
148{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100149#if STM32MP13
150 return true;
151#endif
152#if STM32MP15
Yann Gautier2b79c372021-06-11 10:54:56 +0200153 if (bank == GPIO_BANK_Z) {
154 return true;
155 }
156
157 return false;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100158#endif
Yann Gautier2b79c372021-06-11 10:54:56 +0200159}
160
Yann Gautiere3bf9132019-05-07 18:52:17 +0200161unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
162{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100163#if STM32MP13
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100164 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100165#endif
166#if STM32MP15
Yann Gautiere3bf9132019-05-07 18:52:17 +0200167 if (bank == GPIO_BANK_Z) {
168 return GPIOZ;
169 }
170
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100171 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100172#endif
Yann Gautiere3bf9132019-05-07 18:52:17 +0200173
174 return GPIOA + (bank - GPIO_BANK_A);
175}
Yann Gautier091eab52019-06-04 18:06:34 +0200176
Etienne Carriered81dadf2020-04-25 11:14:45 +0200177int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
178{
Yann Gautiere78db3b2022-03-11 14:18:13 +0100179 const char *node_compatible = NULL;
180
Etienne Carriered81dadf2020-04-25 11:14:45 +0200181 switch (bank) {
182 case GPIO_BANK_A:
183 case GPIO_BANK_B:
184 case GPIO_BANK_C:
185 case GPIO_BANK_D:
186 case GPIO_BANK_E:
187 case GPIO_BANK_F:
188 case GPIO_BANK_G:
189 case GPIO_BANK_H:
190 case GPIO_BANK_I:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100191#if STM32MP13
192 node_compatible = "st,stm32mp135-pinctrl";
193 break;
194#endif
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100195#if STM32MP15
Etienne Carriered81dadf2020-04-25 11:14:45 +0200196 case GPIO_BANK_J:
197 case GPIO_BANK_K:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100198 node_compatible = "st,stm32mp157-pinctrl";
199 break;
Etienne Carriered81dadf2020-04-25 11:14:45 +0200200 case GPIO_BANK_Z:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100201 node_compatible = "st,stm32mp157-z-pinctrl";
202 break;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100203#endif
Etienne Carriered81dadf2020-04-25 11:14:45 +0200204 default:
205 panic();
206 }
Yann Gautiere78db3b2022-03-11 14:18:13 +0100207
208 return fdt_node_offset_by_compatible(fdt, -1, node_compatible);
Etienne Carriered81dadf2020-04-25 11:14:45 +0200209}
210
Yann Gautier3d8497c2021-10-18 16:06:22 +0200211#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200212/*
213 * UART Management
214 */
215static const uintptr_t stm32mp1_uart_addresses[8] = {
216 USART1_BASE,
217 USART2_BASE,
218 USART3_BASE,
219 UART4_BASE,
220 UART5_BASE,
221 USART6_BASE,
222 UART7_BASE,
223 UART8_BASE,
224};
225
226uintptr_t get_uart_address(uint32_t instance_nb)
227{
228 if ((instance_nb == 0U) ||
229 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
230 return 0U;
231 }
232
233 return stm32mp1_uart_addresses[instance_nb - 1U];
234}
235#endif
236
Yann Gautiercd16df32021-06-04 14:04:05 +0200237#if STM32MP_USB_PROGRAMMER
238struct gpio_bank_pin_list {
239 uint32_t bank;
240 uint32_t pin;
241};
242
243static const struct gpio_bank_pin_list gpio_list[] = {
244 { /* USART2_RX: GPIOA3 */
245 .bank = 0U,
246 .pin = 3U,
247 },
248 { /* USART3_RX: GPIOB12 */
249 .bank = 1U,
250 .pin = 12U,
251 },
252 { /* UART4_RX: GPIOB2 */
253 .bank = 1U,
254 .pin = 2U,
255 },
256 { /* UART5_RX: GPIOB4 */
257 .bank = 1U,
258 .pin = 5U,
259 },
260 { /* USART6_RX: GPIOC7 */
261 .bank = 2U,
262 .pin = 7U,
263 },
264 { /* UART7_RX: GPIOF6 */
265 .bank = 5U,
266 .pin = 6U,
267 },
268 { /* UART8_RX: GPIOE0 */
269 .bank = 4U,
270 .pin = 0U,
271 },
272};
273
274void stm32mp1_deconfigure_uart_pins(void)
275{
276 size_t i;
277
278 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
279 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
280 }
281}
282#endif
283
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200284uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200285{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200286#if STM32MP13
287 return stm32mp1_syscfg_get_chip_version();
288#endif
289#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200290 uint32_t version = 0U;
291
292 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
293 INFO("Cannot get CPU version, debug disabled\n");
294 return 0U;
295 }
296
297 return version;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200298#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200299}
Yann Gautierc7374052019-06-04 18:02:37 +0200300
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200301uint32_t stm32mp_get_chip_dev_id(void)
302{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200303#if STM32MP13
304 return stm32mp1_syscfg_get_chip_dev_id();
305#endif
306#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200307 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200308
Yann Gautierc7374052019-06-04 18:02:37 +0200309 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200310 INFO("Use default chip ID, debug disabled\n");
311 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200312 }
313
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200314 return dev_id;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200315#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200316}
317
318static uint32_t get_part_number(void)
319{
320 static uint32_t part_number;
321
322 if (part_number != 0U) {
323 return part_number;
324 }
325
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100326 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200327 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200328 }
329
330 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
331 PART_NUMBER_OTP_PART_SHIFT;
332
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200333 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200334
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200335 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200336}
337
Yann Gautier16188f32020-02-12 15:38:34 +0100338#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200339static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200340{
341 uint32_t package;
342
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100343 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200344 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200345 }
346
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200347 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200348 PACKAGE_OTP_PKG_SHIFT;
349
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200350 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200351}
Yann Gautier16188f32020-02-12 15:38:34 +0100352#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200353
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200354void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200355{
Yann Gautier4bda43f2022-11-24 19:02:23 +0100356 const char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200357
358 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200359 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100360#if STM32MP13
361 case STM32MP135F_PART_NB:
362 cpu_s = "135F";
363 break;
364 case STM32MP135D_PART_NB:
365 cpu_s = "135D";
366 break;
367 case STM32MP135C_PART_NB:
368 cpu_s = "135C";
369 break;
370 case STM32MP135A_PART_NB:
371 cpu_s = "135A";
372 break;
373 case STM32MP133F_PART_NB:
374 cpu_s = "133F";
375 break;
376 case STM32MP133D_PART_NB:
377 cpu_s = "133D";
378 break;
379 case STM32MP133C_PART_NB:
380 cpu_s = "133C";
381 break;
382 case STM32MP133A_PART_NB:
383 cpu_s = "133A";
384 break;
385 case STM32MP131F_PART_NB:
386 cpu_s = "131F";
387 break;
388 case STM32MP131D_PART_NB:
389 cpu_s = "131D";
390 break;
391 case STM32MP131C_PART_NB:
392 cpu_s = "131C";
393 break;
394 case STM32MP131A_PART_NB:
395 cpu_s = "131A";
396 break;
397#endif
398#if STM32MP15
Yann Gautierc7374052019-06-04 18:02:37 +0200399 case STM32MP157C_PART_NB:
400 cpu_s = "157C";
401 break;
402 case STM32MP157A_PART_NB:
403 cpu_s = "157A";
404 break;
405 case STM32MP153C_PART_NB:
406 cpu_s = "153C";
407 break;
408 case STM32MP153A_PART_NB:
409 cpu_s = "153A";
410 break;
411 case STM32MP151C_PART_NB:
412 cpu_s = "151C";
413 break;
414 case STM32MP151A_PART_NB:
415 cpu_s = "151A";
416 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200417 case STM32MP157F_PART_NB:
418 cpu_s = "157F";
419 break;
420 case STM32MP157D_PART_NB:
421 cpu_s = "157D";
422 break;
423 case STM32MP153F_PART_NB:
424 cpu_s = "153F";
425 break;
426 case STM32MP153D_PART_NB:
427 cpu_s = "153D";
428 break;
429 case STM32MP151F_PART_NB:
430 cpu_s = "151F";
431 break;
432 case STM32MP151D_PART_NB:
433 cpu_s = "151D";
434 break;
Yann Gautier16188f32020-02-12 15:38:34 +0100435#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200436 default:
437 cpu_s = "????";
438 break;
439 }
440
441 /* Package */
Yann Gautier16188f32020-02-12 15:38:34 +0100442#if STM32MP13
443 /* On STM32MP13, package is not present in OTP */
444 pkg = "";
445#endif
446#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200447 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200448 case PKG_AA_LFBGA448:
449 pkg = "AA";
450 break;
451 case PKG_AB_LFBGA354:
452 pkg = "AB";
453 break;
454 case PKG_AC_TFBGA361:
455 pkg = "AC";
456 break;
457 case PKG_AD_TFBGA257:
458 pkg = "AD";
459 break;
460 default:
461 pkg = "??";
462 break;
463 }
Yann Gautier16188f32020-02-12 15:38:34 +0100464#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200465
466 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200467 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200468 case STM32MP1_REV_B:
469 cpu_r = "B";
470 break;
Yann Gautier06cc7912022-05-09 17:01:11 +0200471#if STM32MP13
472 case STM32MP1_REV_Y:
473 cpu_r = "Y";
474 break;
475#endif
Lionel Debieve2d64b532019-06-25 10:40:37 +0200476 case STM32MP1_REV_Z:
477 cpu_r = "Z";
478 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200479 default:
480 cpu_r = "?";
481 break;
482 }
483
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200484 snprintf(name, STM32_SOC_NAME_SIZE,
485 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
486}
487
488void stm32mp_print_cpuinfo(void)
489{
490 char name[STM32_SOC_NAME_SIZE];
491
492 stm32mp_get_soc_name(name);
493 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200494}
495
Yann Gautier35dc0772019-05-13 18:34:48 +0200496void stm32mp_print_boardinfo(void)
497{
Yann Gautier45b95992023-01-04 16:46:07 +0100498 uint32_t board_id = 0U;
Yann Gautier35dc0772019-05-13 18:34:48 +0200499
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100500 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier35dc0772019-05-13 18:34:48 +0200501 return;
502 }
503
Yann Gautier35dc0772019-05-13 18:34:48 +0200504 if (board_id != 0U) {
Yann Gautier45b95992023-01-04 16:46:07 +0100505 stm32_display_board_info(board_id);
Yann Gautier35dc0772019-05-13 18:34:48 +0200506 }
507}
508
Yann Gautieraf19ff92019-06-04 18:23:10 +0200509/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
510bool stm32mp_is_single_core(void)
511{
Yann Gautier6bd30e22020-02-06 15:34:16 +0100512#if STM32MP13
513 return true;
514#endif
515#if STM32MP15
Yann Gautier2f3b5602021-10-19 13:31:06 +0200516 bool single_core = false;
517
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200518 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200519 case STM32MP151A_PART_NB:
520 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200521 case STM32MP151D_PART_NB:
522 case STM32MP151F_PART_NB:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200523 single_core = true;
524 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200525 default:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200526 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200527 }
Yann Gautier2f3b5602021-10-19 13:31:06 +0200528
529 return single_core;
Yann Gautier6bd30e22020-02-06 15:34:16 +0100530#endif
Yann Gautieraf19ff92019-06-04 18:23:10 +0200531}
532
Lionel Debieve0e73d732019-09-16 12:17:09 +0200533/* Return true when device is in closed state */
534bool stm32mp_is_closed_device(void)
535{
536 uint32_t value;
537
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100538 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debieve0e73d732019-09-16 12:17:09 +0200539 return true;
540 }
541
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100542#if STM32MP13
543 value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT;
544
545 switch (value) {
546 case CFG0_OPEN_DEVICE:
547 return false;
548 case CFG0_CLOSED_DEVICE:
549 case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
550 case CFG0_CLOSED_DEVICE_NO_JTAG:
551 return true;
552 default:
553 panic();
554 }
555#endif
556#if STM32MP15
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100557 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100558#endif
Lionel Debieve0e73d732019-09-16 12:17:09 +0200559}
560
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100561/* Return true when device supports secure boot */
562bool stm32mp_is_auth_supported(void)
563{
564 bool supported = false;
565
566 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100567#if STM32MP13
568 case STM32MP131C_PART_NB:
569 case STM32MP131F_PART_NB:
570 case STM32MP133C_PART_NB:
571 case STM32MP133F_PART_NB:
572 case STM32MP135C_PART_NB:
573 case STM32MP135F_PART_NB:
574#endif
575#if STM32MP15
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100576 case STM32MP151C_PART_NB:
577 case STM32MP151F_PART_NB:
578 case STM32MP153C_PART_NB:
579 case STM32MP153F_PART_NB:
580 case STM32MP157C_PART_NB:
581 case STM32MP157F_PART_NB:
Yann Gautier16188f32020-02-12 15:38:34 +0100582#endif
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100583 supported = true;
584 break;
585 default:
586 break;
587 }
588
589 return supported;
590}
591
Yann Gautier091eab52019-06-04 18:06:34 +0200592uint32_t stm32_iwdg_get_instance(uintptr_t base)
593{
594 switch (base) {
595 case IWDG1_BASE:
596 return IWDG1_INST;
597 case IWDG2_BASE:
598 return IWDG2_INST;
599 default:
600 panic();
601 }
602}
603
604uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
605{
606 uint32_t iwdg_cfg = 0U;
607 uint32_t otp_value;
608
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100609 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200610 panic();
611 }
612
613 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
614 iwdg_cfg |= IWDG_HW_ENABLED;
615 }
616
617 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
618 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
619 }
620
621 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
622 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
623 }
624
625 return iwdg_cfg;
626}
627
628#if defined(IMAGE_BL2)
629uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
630{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100631 uint32_t otp_value;
Yann Gautier091eab52019-06-04 18:06:34 +0200632 uint32_t otp;
633 uint32_t result;
634
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100635 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
636 panic();
637 }
638
639 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200640 panic();
641 }
642
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100643 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
644 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200645 }
646
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100647 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
648 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200649 }
650
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100651 result = bsec_write_otp(otp_value, otp);
Yann Gautier091eab52019-06-04 18:06:34 +0200652 if (result != BSEC_OK) {
653 return result;
654 }
655
656 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100657 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
658 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier091eab52019-06-04 18:06:34 +0200659 return BSEC_LOCK_FAIL;
660 }
661
662 return BSEC_OK;
663}
664#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100665
Yann Gautier8402c292022-06-29 17:03:36 +0200666uintptr_t stm32_get_bkpr_boot_mode_addr(void)
Yann Gautier6eef5252021-12-10 17:04:40 +0100667{
Yann Gautier8402c292022-06-29 17:03:36 +0200668 return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Igor Opaniukf07e8f32022-06-23 21:19:26 +0300669}
670
Yann Gautier5d2eb552022-11-14 14:14:48 +0100671#if PSA_FWU_SUPPORT
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530672void stm32mp1_fwu_set_boot_idx(void)
673{
674 clk_enable(RTCAPB);
Yann Gautier9bbd26a2022-03-28 17:49:38 +0200675 mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
676 TAMP_BOOT_FWU_INFO_IDX_MSK,
677 (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
678 TAMP_BOOT_FWU_INFO_IDX_MSK);
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530679 clk_disable(RTCAPB);
680}
Nicolas Toromanoff5a937cd2022-02-07 10:12:04 +0100681
682uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
683{
684 uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
685 uint32_t try_cnt;
686
687 clk_enable(RTCAPB);
688 try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
689 TAMP_BOOT_FWU_INFO_CNT_OFF;
690
691 assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
692
693 if (try_cnt != 0U) {
694 mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
695 (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
696 }
697 clk_disable(RTCAPB);
698
699 return try_cnt;
700}
701
702void stm32_set_max_fwu_trial_boot_cnt(void)
703{
704 uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
705
706 clk_enable(RTCAPB);
707 mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
708 (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
709 TAMP_BOOT_FWU_INFO_CNT_MSK);
710 clk_disable(RTCAPB);
711}
Yann Gautier5d2eb552022-11-14 14:14:48 +0100712#endif /* PSA_FWU_SUPPORT */