1 /*
2 * Copyright (c) 2023-2026, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <assert.h>
8 #include <errno.h>
9
10 #include <lib/xlat_tables/xlat_tables_v2.h>
11
12 #include <platform_def.h>
13
14 #define BKPR_FWU_INFO 48U
15 #define BKPR_BOOT_MODE 96U
16
17 #if defined(IMAGE_BL31)
18 /* BL31 only uses the first half of the SYSRAM */
19 #define MAP_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
20 STM32MP_SYSRAM_SIZE / 2U, \
21 MT_MEMORY | \
22 MT_RW | \
23 MT_SECURE | \
24 MT_EXECUTE_NEVER)
25 #else
26 #define MAP_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
27 STM32MP_SYSRAM_SIZE, \
28 MT_MEMORY | \
29 MT_RW | \
30 MT_SECURE | \
31 MT_EXECUTE_NEVER)
32 #endif
33
34 #if STM32MP_USB_PROGRAMMER && !STM32MP21
35 #define MAP_SYSRAM_MEM MAP_REGION_FLAT(STM32MP_SYSRAM_MEM_BASE, \
36 STM32MP_SYSRAM_MEM_SIZE, \
37 MT_MEMORY | \
38 MT_RW | \
39 MT_SECURE | \
40 MT_EXECUTE_NEVER)
41
42 #define MAP_SYSRAM_DEV MAP_REGION_FLAT(STM32MP_SYSRAM_DEVICE_BASE, \
43 STM32MP_SYSRAM_DEVICE_SIZE, \
44 MT_DEVICE | \
45 MT_RW | \
46 MT_SECURE | \
47 MT_EXECUTE_NEVER)
48 #endif /* STM32MP_USB_PROGRAMMER && !STM32MP21 */
49
50 #if STM32MP_DDR_FIP_IO_STORAGE
51 #define MAP_SRAM1 MAP_REGION_FLAT(SRAM1_BASE, \
52 SRAM1_SIZE_FOR_TFA, \
53 MT_MEMORY | \
54 MT_RW | \
55 MT_SECURE | \
56 MT_EXECUTE_NEVER)
57 #endif
58
59 #define MAP_DEVICE MAP_REGION_FLAT(STM32MP_DEVICE_BASE, \
60 STM32MP_DEVICE_SIZE, \
61 MT_DEVICE | \
62 MT_RW | \
63 MT_SECURE | \
64 MT_EXECUTE_NEVER)
65
66 #if defined(IMAGE_BL2)
67 static const mmap_region_t stm32mp2_mmap[] = {
68 #if STM32MP_USB_PROGRAMMER && !STM32MP21
69 MAP_SYSRAM_MEM,
70 MAP_SYSRAM_DEV,
71 #else /* !STM32MP_USB_PROGRAMMER || STM32MP21 */
72 MAP_SYSRAM,
73 #endif /* STM32MP_USB_PROGRAMMER && !STM32MP21 */
74 #if STM32MP_DDR_FIP_IO_STORAGE
75 MAP_SRAM1,
76 #endif
77 MAP_DEVICE,
78 {0}
79 };
80 #endif
81 #if defined(IMAGE_BL31)
82 static const mmap_region_t stm32mp2_mmap[] = {
83 MAP_SYSRAM,
84 MAP_DEVICE,
85 {0}
86 };
87 #endif
88
configure_mmu(void)89 void configure_mmu(void)
90 {
91 mmap_add(stm32mp2_mmap);
92 init_xlat_tables();
93
94 enable_mmu_el3(0);
95 }
96
stm32mp_map_retram(void)97 int stm32mp_map_retram(void)
98 {
99 return mmap_add_dynamic_region(RETRAM_BASE, RETRAM_BASE,
100 RETRAM_SIZE,
101 MT_RW | MT_SECURE);
102 }
103
stm32mp_unmap_retram(void)104 int stm32mp_unmap_retram(void)
105 {
106 return mmap_remove_dynamic_region(RETRAM_BASE,
107 RETRAM_SIZE);
108 }
109
stm32_get_gpio_bank_base(unsigned int bank)110 uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
111 {
112 if (bank == GPIO_BANK_Z) {
113 return GPIOZ_BASE;
114 }
115
116 assert(bank <= GPIO_BANK_K);
117
118 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
119 }
120
stm32_get_gpio_bank_offset(unsigned int bank)121 uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
122 {
123 if (bank == GPIO_BANK_Z) {
124 return 0;
125 }
126
127 assert(bank <= GPIO_BANK_K);
128
129 return bank * GPIO_BANK_OFFSET;
130 }
131
stm32_get_gpio_bank_clock(unsigned int bank)132 unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
133 {
134 if (bank == GPIO_BANK_Z) {
135 return CK_BUS_GPIOZ;
136 }
137
138 assert(bank <= GPIO_BANK_K);
139
140 return CK_BUS_GPIOA + (bank - GPIO_BANK_A);
141 }
142
143 #if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
144 /*
145 * UART Management
146 */
147 static const uintptr_t stm32mp2_uart_addresses[STM32MP_NB_OF_UART] = {
148 USART1_BASE,
149 USART2_BASE,
150 USART3_BASE,
151 UART4_BASE,
152 UART5_BASE,
153 USART6_BASE,
154 UART7_BASE,
155 #if STM32MP25
156 UART8_BASE,
157 UART9_BASE,
158 #endif /* STM32MP25 */
159 };
160
get_uart_address(uint32_t instance_nb)161 uintptr_t get_uart_address(uint32_t instance_nb)
162 {
163 if ((instance_nb == 0U) ||
164 (instance_nb > STM32MP_NB_OF_UART)) {
165 return 0U;
166 }
167
168 return stm32mp2_uart_addresses[instance_nb - 1U];
169 }
170 #endif
171
stm32mp_get_chip_version(void)172 uint32_t stm32mp_get_chip_version(void)
173 {
174 static uint32_t rev;
175
176 if (rev != 0U) {
177 return rev;
178 }
179
180 if (stm32_get_otp_value(REVISION_OTP, &rev) != 0) {
181 panic();
182 }
183
184 return rev;
185 }
186
stm32mp_get_chip_dev_id(void)187 uint32_t stm32mp_get_chip_dev_id(void)
188 {
189 return stm32mp_syscfg_get_chip_dev_id();
190 }
191
get_part_number(void)192 static uint32_t get_part_number(void)
193 {
194 static uint32_t part_number;
195
196 if (part_number != 0U) {
197 return part_number;
198 }
199
200 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
201 panic();
202 }
203
204 return part_number;
205 }
206
get_cpu_package(void)207 static uint32_t get_cpu_package(void)
208 {
209 static uint32_t package = UINT32_MAX;
210
211 if (package == UINT32_MAX) {
212 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
213 panic();
214 }
215 }
216
217 return (package & PACKAGE_OTP_PKG_MASK) >> PACKAGE_OTP_PKG_SHIFT;
218 }
219
stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])220 void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
221 {
222 char *cpu_s, *cpu_r, *pkg;
223
224 /* MPUs Part Numbers */
225 switch (get_part_number()) {
226 #if STM32MP21
227 case STM32MP211A_PART_NB:
228 cpu_s = "211A";
229 break;
230 case STM32MP211C_PART_NB:
231 cpu_s = "211C";
232 break;
233 case STM32MP211D_PART_NB:
234 cpu_s = "211D";
235 break;
236 case STM32MP211F_PART_NB:
237 cpu_s = "211F";
238 break;
239 case STM32MP213A_PART_NB:
240 cpu_s = "213A";
241 break;
242 case STM32MP213C_PART_NB:
243 cpu_s = "213C";
244 break;
245 case STM32MP213D_PART_NB:
246 cpu_s = "213D";
247 break;
248 case STM32MP213F_PART_NB:
249 cpu_s = "213F";
250 break;
251 case STM32MP215A_PART_NB:
252 cpu_s = "215A";
253 break;
254 case STM32MP215C_PART_NB:
255 cpu_s = "215C";
256 break;
257 case STM32MP215D_PART_NB:
258 cpu_s = "215D";
259 break;
260 case STM32MP215F_PART_NB:
261 cpu_s = "215F";
262 break;
263 #endif /* STM32MP21 */
264 #if STM32MP23
265 case STM32MP231A_PART_NB:
266 cpu_s = "231A";
267 break;
268 case STM32MP231C_PART_NB:
269 cpu_s = "231C";
270 break;
271 case STM32MP231D_PART_NB:
272 cpu_s = "231D";
273 break;
274 case STM32MP231F_PART_NB:
275 cpu_s = "231F";
276 break;
277 case STM32MP233A_PART_NB:
278 cpu_s = "233A";
279 break;
280 case STM32MP233C_PART_NB:
281 cpu_s = "233C";
282 break;
283 case STM32MP233D_PART_NB:
284 cpu_s = "233D";
285 break;
286 case STM32MP233F_PART_NB:
287 cpu_s = "233F";
288 break;
289 case STM32MP235A_PART_NB:
290 cpu_s = "235A";
291 break;
292 case STM32MP235C_PART_NB:
293 cpu_s = "235C";
294 break;
295 case STM32MP235D_PART_NB:
296 cpu_s = "235D";
297 break;
298 case STM32MP235F_PART_NB:
299 cpu_s = "235F";
300 break;
301 #endif /* STM32MP23 */
302 #if STM32MP25
303 case STM32MP251A_PART_NB:
304 cpu_s = "251A";
305 break;
306 case STM32MP251C_PART_NB:
307 cpu_s = "251C";
308 break;
309 case STM32MP251D_PART_NB:
310 cpu_s = "251D";
311 break;
312 case STM32MP251F_PART_NB:
313 cpu_s = "251F";
314 break;
315 case STM32MP253A_PART_NB:
316 cpu_s = "253A";
317 break;
318 case STM32MP253C_PART_NB:
319 cpu_s = "253C";
320 break;
321 case STM32MP253D_PART_NB:
322 cpu_s = "253D";
323 break;
324 case STM32MP253F_PART_NB:
325 cpu_s = "253F";
326 break;
327 case STM32MP255A_PART_NB:
328 cpu_s = "255A";
329 break;
330 case STM32MP255C_PART_NB:
331 cpu_s = "255C";
332 break;
333 case STM32MP255D_PART_NB:
334 cpu_s = "255D";
335 break;
336 case STM32MP255F_PART_NB:
337 cpu_s = "255F";
338 break;
339 case STM32MP257A_PART_NB:
340 cpu_s = "257A";
341 break;
342 case STM32MP257C_PART_NB:
343 cpu_s = "257C";
344 break;
345 case STM32MP257D_PART_NB:
346 cpu_s = "257D";
347 break;
348 case STM32MP257F_PART_NB:
349 cpu_s = "257F";
350 break;
351 #endif /* STM32MP25 */
352 default:
353 cpu_s = "????";
354 break;
355 }
356
357 /* Package */
358 switch (get_cpu_package()) {
359 #if STM32MP21
360 case STM32MP21_PKG_CUSTOM:
361 pkg = "XX";
362 break;
363 case STM32MP21_PKG_AL_VFBGA361:
364 pkg = "AL";
365 break;
366 case STM32MP21_PKG_AN_VFBGA273:
367 pkg = "AN";
368 break;
369 case STM32MP21_PKG_AO_VFBGA225:
370 pkg = "AO";
371 break;
372 case STM32MP21_PKG_AM_TFBGA289:
373 pkg = "AM";
374 break;
375 #endif /* STM32MP21 */
376 #if STM32MP23
377 case STM32MP23_PKG_CUSTOM:
378 pkg = "XX";
379 break;
380 case STM32MP23_PKG_AL_VFBGA361:
381 pkg = "AL";
382 break;
383 case STM32MP23_PKG_AK_VFBGA424:
384 pkg = "AK";
385 break;
386 case STM32MP23_PKG_AJ_TFBGA361:
387 pkg = "AJ";
388 break;
389 #endif /* STM32MP23 */
390 #if STM32MP25
391 case STM32MP25_PKG_CUSTOM:
392 pkg = "XX";
393 break;
394 case STM32MP25_PKG_AL_VFBGA361:
395 pkg = "AL";
396 break;
397 case STM32MP25_PKG_AK_VFBGA424:
398 pkg = "AK";
399 break;
400 case STM32MP25_PKG_AI_TFBGA436:
401 pkg = "AI";
402 break;
403 #endif /* STM32MP25 */
404 default:
405 pkg = "??";
406 break;
407 }
408
409 /* REVISION */
410 switch (stm32mp_get_chip_version()) {
411 case STM32MP2_REV_A:
412 cpu_r = "A";
413 break;
414 case STM32MP2_REV_B:
415 cpu_r = "B";
416 break;
417 case STM32MP2_REV_X:
418 cpu_r = "X";
419 break;
420 case STM32MP2_REV_Y:
421 cpu_r = "Y";
422 break;
423 case STM32MP2_REV_Z:
424 cpu_r = "Z";
425 break;
426 default:
427 cpu_r = "?";
428 break;
429 }
430
431 snprintf(name, STM32_SOC_NAME_SIZE,
432 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
433 }
434
stm32mp_print_cpuinfo(void)435 void stm32mp_print_cpuinfo(void)
436 {
437 char name[STM32_SOC_NAME_SIZE];
438
439 stm32mp_get_soc_name(name);
440 NOTICE("CPU: %s\n", name);
441 }
442
stm32mp_print_boardinfo(void)443 void stm32mp_print_boardinfo(void)
444 {
445 uint32_t board_id = 0U;
446
447 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
448 return;
449 }
450
451 if (board_id != 0U) {
452 stm32_display_board_info(board_id);
453 }
454 }
455
456 /* Return true when SoC provides a single Cortex-A35 core, and false otherwise */
stm32mp_is_single_core(void)457 bool stm32mp_is_single_core(void)
458 {
459 #if STM32MP21
460 return true;
461 #else /* STM32MP21 */
462 bool single_core = false;
463
464 switch (get_part_number()) {
465 #if STM32MP23
466 case STM32MP231A_PART_NB:
467 case STM32MP231C_PART_NB:
468 case STM32MP231D_PART_NB:
469 case STM32MP231F_PART_NB:
470 #endif /* STM32MP23 */
471 #if STM32MP25
472 case STM32MP251A_PART_NB:
473 case STM32MP251C_PART_NB:
474 case STM32MP251D_PART_NB:
475 case STM32MP251F_PART_NB:
476 #endif /* STM32MP25 */
477 single_core = true;
478 break;
479 default:
480 break;
481 }
482
483 return single_core;
484 #endif /* STM32MP21 */
485 }
486
487 /* Return true when device is in closed state */
stm32mp_check_closed_device(void)488 uint32_t stm32mp_check_closed_device(void)
489 {
490 return STM32MP_CHIP_SEC_OPEN;
491 }
492
493 /* Return true when device supports secure boot */
stm32mp_is_auth_supported(void)494 bool stm32mp_is_auth_supported(void)
495 {
496 bool supported = false;
497
498 switch (get_part_number()) {
499 #if STM32MP21
500 case STM32MP211C_PART_NB:
501 case STM32MP211F_PART_NB:
502 case STM32MP213C_PART_NB:
503 case STM32MP213F_PART_NB:
504 case STM32MP215C_PART_NB:
505 case STM32MP215F_PART_NB:
506 #endif /* STM32MP21 */
507 #if STM32MP23
508 case STM32MP231C_PART_NB:
509 case STM32MP231F_PART_NB:
510 case STM32MP233C_PART_NB:
511 case STM32MP233F_PART_NB:
512 case STM32MP235C_PART_NB:
513 case STM32MP235F_PART_NB:
514 #endif /* STM32MP23 */
515 #if STM32MP25
516 case STM32MP251C_PART_NB:
517 case STM32MP251F_PART_NB:
518 case STM32MP253C_PART_NB:
519 case STM32MP253F_PART_NB:
520 case STM32MP255C_PART_NB:
521 case STM32MP255F_PART_NB:
522 case STM32MP257C_PART_NB:
523 case STM32MP257F_PART_NB:
524 #endif /* STM32MP25 */
525 supported = true;
526 break;
527 default:
528 break;
529 }
530
531 return supported;
532 }
533
stm32mp_is_wakeup_from_standby(void)534 bool stm32mp_is_wakeup_from_standby(void)
535 {
536 /* TODO add source code to determine if platform is waking up from standby mode */
537 return false;
538 }
539
stm32_risaf_get_instance(uintptr_t base)540 int stm32_risaf_get_instance(uintptr_t base)
541 {
542 switch (base) {
543 case RISAF2_BASE:
544 return (int)RISAF2_INST;
545 case RISAF4_BASE:
546 return (int)RISAF4_INST;
547 default:
548 return -ENODEV;
549 }
550 }
551
stm32_risaf_get_base(int instance)552 uintptr_t stm32_risaf_get_base(int instance)
553 {
554 switch (instance) {
555 case RISAF2_INST:
556 return (uintptr_t)RISAF2_BASE;
557 case RISAF4_INST:
558 return (uintptr_t)RISAF4_BASE;
559 default:
560 return 0U;
561 }
562 }
563
stm32_risaf_get_max_region(int instance)564 int stm32_risaf_get_max_region(int instance)
565 {
566 switch (instance) {
567 case RISAF2_INST:
568 return (int)RISAF2_MAX_REGION;
569 case RISAF4_INST:
570 return (int)RISAF4_MAX_REGION;
571 default:
572 return 0;
573 }
574 }
575
stm32_risaf_get_memory_base(int instance)576 uintptr_t stm32_risaf_get_memory_base(int instance)
577 {
578 switch (instance) {
579 case RISAF2_INST:
580 return (uintptr_t)STM32MP_OSPI_MM_BASE;
581 case RISAF4_INST:
582 return (uintptr_t)STM32MP_DDR_BASE;
583 default:
584 return 0U;
585 }
586 }
587
stm32_risaf_get_memory_size(int instance)588 size_t stm32_risaf_get_memory_size(int instance)
589 {
590 switch (instance) {
591 case RISAF2_INST:
592 return STM32MP_OSPI_MM_SIZE;
593 case RISAF4_INST:
594 return dt_get_ddr_size();
595 default:
596 return 0U;
597 }
598 }
599
stm32_get_bkpr_boot_mode_addr(void)600 uintptr_t stm32_get_bkpr_boot_mode_addr(void)
601 {
602 return tamp_bkpr(BKPR_BOOT_MODE);
603 }
604
605 #if PSA_FWU_SUPPORT
stm32_get_bkpr_fwu_info_addr(void)606 uintptr_t stm32_get_bkpr_fwu_info_addr(void)
607 {
608 return tamp_bkpr(BKPR_FWU_INFO);
609 }
610 #endif /* PSA_FWU_SUPPORT */
611
stm32_ddrdbg_get_base(void)612 uintptr_t stm32_ddrdbg_get_base(void)
613 {
614 return DDRDBG_BASE;
615 }
616