blob: 62db2e6da53264ca25990d28959b06ef84624d8e [file] [log] [blame]
Yann Gautierc9d75b32019-02-14 11:13:25 +01001/*
Yann Gautierdb3e0ec2020-09-17 11:38:09 +02002 * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
Yann Gautierc9d75b32019-02-14 11:13:25 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Yann Gautier8f282da2019-05-07 18:52:17 +02007#include <assert.h>
8
Yann Gautier33667d22021-08-30 15:06:54 +02009#include <drivers/clk.h>
Yann Gautierd7176f02021-06-04 14:04:05 +020010#include <drivers/st/stm32_gpio.h>
11#include <drivers/st/stm32_iwdg.h>
Yann Gautier4dc77a32021-12-10 17:04:40 +010012#include <lib/mmio.h>
Yann Gautierd7176f02021-06-04 14:04:05 +020013#include <lib/xlat_tables/xlat_tables_v2.h>
Yann Gautierff7675e2021-12-17 09:53:04 +010014#include <libfdt.h>
Yann Gautier10e7a9e2019-05-13 18:34:48 +020015
Sughosh Ganuba02add2021-12-01 15:56:27 +053016#include <plat/common/platform.h>
Yann Gautierc9d75b32019-02-14 11:13:25 +010017#include <platform_def.h>
18
Yann Gautier10e7a9e2019-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 Delaunayf964f5c2020-01-08 10:05:14 +010022#define BOARD_ID_VARCPN_MASK GENMASK(15, 12)
23#define BOARD_ID_VARCPN_SHIFT 12
Yann Gautier10e7a9e2019-05-13 18:34:48 +020024#define BOARD_ID_REVISION_MASK GENMASK(11, 8)
25#define BOARD_ID_REVISION_SHIFT 8
Patrick Delaunayf964f5c2020-01-08 10:05:14 +010026#define BOARD_ID_VARFG_MASK GENMASK(7, 4)
27#define BOARD_ID_VARFG_SHIFT 4
Yann Gautier10e7a9e2019-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 Delaunayf964f5c2020-01-08 10:05:14 +010032#define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \
33 BOARD_ID_VARCPN_SHIFT)
Yann Gautier10e7a9e2019-05-13 18:34:48 +020034#define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \
35 BOARD_ID_REVISION_SHIFT)
Patrick Delaunayf964f5c2020-01-08 10:05:14 +010036#define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \
37 BOARD_ID_VARFG_SHIFT)
Yann Gautier10e7a9e2019-05-13 18:34:48 +020038#define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK)
39
Yann Gautier4b031ab2020-02-05 16:24:21 +010040#if STM32MP13
41#define TAMP_BOOT_MODE_BACKUP_REG_ID U(30)
42#endif
43#if STM32MP15
Yann Gautier4dc77a32021-12-10 17:04:40 +010044#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
Yann Gautier4b031ab2020-02-05 16:24:21 +010045#endif
Yann Gautier4dc77a32021-12-10 17:04:40 +010046#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
47#define TAMP_BOOT_MODE_ITF_SHIFT 8
48
Sughosh Ganuba02add2021-12-01 15:56:27 +053049#define TAMP_BOOT_COUNTER_REG_ID U(21)
50
Etienne Carriere07541432019-12-08 08:17:56 +010051#if defined(IMAGE_BL2)
52#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautier3f9c9782019-02-14 11:13:39 +010053 STM32MP_SYSRAM_SIZE, \
Yann Gautierc9d75b32019-02-14 11:13:25 +010054 MT_MEMORY | \
55 MT_RW | \
56 MT_SECURE | \
57 MT_EXECUTE_NEVER)
Etienne Carriere07541432019-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)
65
66/* 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
Yann Gautierc9d75b32019-02-14 11:13:25 +010074
75#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
76 STM32MP1_DEVICE1_SIZE, \
77 MT_DEVICE | \
78 MT_RW | \
79 MT_SECURE | \
80 MT_EXECUTE_NEVER)
81
82#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
83 STM32MP1_DEVICE2_SIZE, \
84 MT_DEVICE | \
85 MT_RW | \
86 MT_SECURE | \
87 MT_EXECUTE_NEVER)
88
89#if defined(IMAGE_BL2)
90static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere07541432019-12-08 08:17:56 +010091 MAP_SEC_SYSRAM,
Yann Gautierc9d75b32019-02-14 11:13:25 +010092 MAP_DEVICE1,
Yann Gautierdb3e0ec2020-09-17 11:38:09 +020093#if STM32MP_RAW_NAND
Yann Gautierc9d75b32019-02-14 11:13:25 +010094 MAP_DEVICE2,
Yann Gautierdb3e0ec2020-09-17 11:38:09 +020095#endif
Yann Gautierc9d75b32019-02-14 11:13:25 +010096 {0}
97};
98#endif
99#if defined(IMAGE_BL32)
100static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere07541432019-12-08 08:17:56 +0100101 MAP_SEC_SYSRAM,
102 MAP_NS_SYSRAM,
Yann Gautierc9d75b32019-02-14 11:13:25 +0100103 MAP_DEVICE1,
104 MAP_DEVICE2,
105 {0}
106};
107#endif
108
109void configure_mmu(void)
110{
111 mmap_add(stm32mp1_mmap);
112 init_xlat_tables();
113
114 enable_mmu_svc_mon(0);
115}
Yann Gautier8f282da2019-05-07 18:52:17 +0200116
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100117uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
118{
Yann Gautier111a3842020-02-12 09:36:23 +0100119#if STM32MP13
120 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
121#endif
122#if STM32MP15
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100123 if (bank == GPIO_BANK_Z) {
124 return GPIOZ_BASE;
125 }
126
127 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautier111a3842020-02-12 09:36:23 +0100128#endif
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100129
130 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
131}
132
133uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
134{
Yann Gautier111a3842020-02-12 09:36:23 +0100135#if STM32MP13
136 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
137#endif
138#if STM32MP15
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100139 if (bank == GPIO_BANK_Z) {
140 return 0;
141 }
142
143 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautier111a3842020-02-12 09:36:23 +0100144#endif
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100145
146 return bank * GPIO_BANK_OFFSET;
147}
148
Yann Gautier737ad292021-06-11 10:54:56 +0200149bool stm32_gpio_is_secure_at_reset(unsigned int bank)
150{
Yann Gautier111a3842020-02-12 09:36:23 +0100151#if STM32MP13
152 return true;
153#endif
154#if STM32MP15
Yann Gautier737ad292021-06-11 10:54:56 +0200155 if (bank == GPIO_BANK_Z) {
156 return true;
157 }
158
159 return false;
Yann Gautier111a3842020-02-12 09:36:23 +0100160#endif
Yann Gautier737ad292021-06-11 10:54:56 +0200161}
162
Yann Gautier8f282da2019-05-07 18:52:17 +0200163unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
164{
Yann Gautier111a3842020-02-12 09:36:23 +0100165#if STM32MP13
166 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
167#endif
168#if STM32MP15
Yann Gautier8f282da2019-05-07 18:52:17 +0200169 if (bank == GPIO_BANK_Z) {
170 return GPIOZ;
171 }
172
173 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautier111a3842020-02-12 09:36:23 +0100174#endif
Yann Gautier8f282da2019-05-07 18:52:17 +0200175
176 return GPIOA + (bank - GPIO_BANK_A);
177}
Yann Gautier73680c22019-06-04 18:06:34 +0200178
Etienne Carriereccc199e2020-04-25 11:14:45 +0200179int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
180{
181 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 Gautier111a3842020-02-12 09:36:23 +0100191#if STM32MP15
Etienne Carriereccc199e2020-04-25 11:14:45 +0200192 case GPIO_BANK_J:
193 case GPIO_BANK_K:
Yann Gautier111a3842020-02-12 09:36:23 +0100194#endif
Etienne Carriereccc199e2020-04-25 11:14:45 +0200195 return fdt_path_offset(fdt, "/soc/pin-controller");
Yann Gautier111a3842020-02-12 09:36:23 +0100196#if STM32MP15
Etienne Carriereccc199e2020-04-25 11:14:45 +0200197 case GPIO_BANK_Z:
198 return fdt_path_offset(fdt, "/soc/pin-controller-z");
Yann Gautier111a3842020-02-12 09:36:23 +0100199#endif
Etienne Carriereccc199e2020-04-25 11:14:45 +0200200 default:
201 panic();
202 }
203}
204
Yann Gautieracf28c22021-10-18 16:06:22 +0200205#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunay9083fa12021-10-28 13:48:52 +0200206/*
207 * UART Management
208 */
209static const uintptr_t stm32mp1_uart_addresses[8] = {
210 USART1_BASE,
211 USART2_BASE,
212 USART3_BASE,
213 UART4_BASE,
214 UART5_BASE,
215 USART6_BASE,
216 UART7_BASE,
217 UART8_BASE,
218};
219
220uintptr_t get_uart_address(uint32_t instance_nb)
221{
222 if ((instance_nb == 0U) ||
223 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
224 return 0U;
225 }
226
227 return stm32mp1_uart_addresses[instance_nb - 1U];
228}
229#endif
230
Yann Gautierd7176f02021-06-04 14:04:05 +0200231#if STM32MP_USB_PROGRAMMER
232struct gpio_bank_pin_list {
233 uint32_t bank;
234 uint32_t pin;
235};
236
237static const struct gpio_bank_pin_list gpio_list[] = {
238 { /* USART2_RX: GPIOA3 */
239 .bank = 0U,
240 .pin = 3U,
241 },
242 { /* USART3_RX: GPIOB12 */
243 .bank = 1U,
244 .pin = 12U,
245 },
246 { /* UART4_RX: GPIOB2 */
247 .bank = 1U,
248 .pin = 2U,
249 },
250 { /* UART5_RX: GPIOB4 */
251 .bank = 1U,
252 .pin = 5U,
253 },
254 { /* USART6_RX: GPIOC7 */
255 .bank = 2U,
256 .pin = 7U,
257 },
258 { /* UART7_RX: GPIOF6 */
259 .bank = 5U,
260 .pin = 6U,
261 },
262 { /* UART8_RX: GPIOE0 */
263 .bank = 4U,
264 .pin = 0U,
265 },
266};
267
268void stm32mp1_deconfigure_uart_pins(void)
269{
270 size_t i;
271
272 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
273 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
274 }
275}
276#endif
277
Yann Gautier92661e02021-05-10 16:05:18 +0200278uint32_t stm32mp_get_chip_version(void)
Yann Gautierdec286d2019-06-04 18:02:37 +0200279{
Yann Gautier92661e02021-05-10 16:05:18 +0200280 uint32_t version = 0U;
281
282 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
283 INFO("Cannot get CPU version, debug disabled\n");
284 return 0U;
285 }
286
287 return version;
288}
289
290uint32_t stm32mp_get_chip_dev_id(void)
291{
Yann Gautierdec286d2019-06-04 18:02:37 +0200292 uint32_t dev_id;
293
294 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautier92661e02021-05-10 16:05:18 +0200295 INFO("Use default chip ID, debug disabled\n");
296 dev_id = STM32MP1_CHIP_ID;
297 }
298
299 return dev_id;
300}
301
302static uint32_t get_part_number(void)
303{
304 static uint32_t part_number;
305
306 if (part_number != 0U) {
307 return part_number;
Yann Gautierdec286d2019-06-04 18:02:37 +0200308 }
309
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100310 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautier92661e02021-05-10 16:05:18 +0200311 panic();
Yann Gautierdec286d2019-06-04 18:02:37 +0200312 }
313
314 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
315 PART_NUMBER_OTP_PART_SHIFT;
316
Yann Gautier92661e02021-05-10 16:05:18 +0200317 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierdec286d2019-06-04 18:02:37 +0200318
Yann Gautier92661e02021-05-10 16:05:18 +0200319 return part_number;
Yann Gautierdec286d2019-06-04 18:02:37 +0200320}
321
Yann Gautier30eea112020-02-12 15:38:34 +0100322#if STM32MP15
Yann Gautier92661e02021-05-10 16:05:18 +0200323static uint32_t get_cpu_package(void)
Yann Gautierdec286d2019-06-04 18:02:37 +0200324{
325 uint32_t package;
326
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100327 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautier92661e02021-05-10 16:05:18 +0200328 panic();
Yann Gautierdec286d2019-06-04 18:02:37 +0200329 }
330
Yann Gautier92661e02021-05-10 16:05:18 +0200331 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierdec286d2019-06-04 18:02:37 +0200332 PACKAGE_OTP_PKG_SHIFT;
333
Yann Gautier92661e02021-05-10 16:05:18 +0200334 return package;
Yann Gautierdec286d2019-06-04 18:02:37 +0200335}
Yann Gautier30eea112020-02-12 15:38:34 +0100336#endif
Yann Gautierdec286d2019-06-04 18:02:37 +0200337
Yann Gautier92661e02021-05-10 16:05:18 +0200338void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierdec286d2019-06-04 18:02:37 +0200339{
Yann Gautier92661e02021-05-10 16:05:18 +0200340 char *cpu_s, *cpu_r, *pkg;
Yann Gautierdec286d2019-06-04 18:02:37 +0200341
342 /* MPUs Part Numbers */
Yann Gautier92661e02021-05-10 16:05:18 +0200343 switch (get_part_number()) {
Yann Gautier30eea112020-02-12 15:38:34 +0100344#if STM32MP13
345 case STM32MP135F_PART_NB:
346 cpu_s = "135F";
347 break;
348 case STM32MP135D_PART_NB:
349 cpu_s = "135D";
350 break;
351 case STM32MP135C_PART_NB:
352 cpu_s = "135C";
353 break;
354 case STM32MP135A_PART_NB:
355 cpu_s = "135A";
356 break;
357 case STM32MP133F_PART_NB:
358 cpu_s = "133F";
359 break;
360 case STM32MP133D_PART_NB:
361 cpu_s = "133D";
362 break;
363 case STM32MP133C_PART_NB:
364 cpu_s = "133C";
365 break;
366 case STM32MP133A_PART_NB:
367 cpu_s = "133A";
368 break;
369 case STM32MP131F_PART_NB:
370 cpu_s = "131F";
371 break;
372 case STM32MP131D_PART_NB:
373 cpu_s = "131D";
374 break;
375 case STM32MP131C_PART_NB:
376 cpu_s = "131C";
377 break;
378 case STM32MP131A_PART_NB:
379 cpu_s = "131A";
380 break;
381#endif
382#if STM32MP15
Yann Gautierdec286d2019-06-04 18:02:37 +0200383 case STM32MP157C_PART_NB:
384 cpu_s = "157C";
385 break;
386 case STM32MP157A_PART_NB:
387 cpu_s = "157A";
388 break;
389 case STM32MP153C_PART_NB:
390 cpu_s = "153C";
391 break;
392 case STM32MP153A_PART_NB:
393 cpu_s = "153A";
394 break;
395 case STM32MP151C_PART_NB:
396 cpu_s = "151C";
397 break;
398 case STM32MP151A_PART_NB:
399 cpu_s = "151A";
400 break;
Lionel Debieve8ccf4952019-05-17 16:01:18 +0200401 case STM32MP157F_PART_NB:
402 cpu_s = "157F";
403 break;
404 case STM32MP157D_PART_NB:
405 cpu_s = "157D";
406 break;
407 case STM32MP153F_PART_NB:
408 cpu_s = "153F";
409 break;
410 case STM32MP153D_PART_NB:
411 cpu_s = "153D";
412 break;
413 case STM32MP151F_PART_NB:
414 cpu_s = "151F";
415 break;
416 case STM32MP151D_PART_NB:
417 cpu_s = "151D";
418 break;
Yann Gautier30eea112020-02-12 15:38:34 +0100419#endif
Yann Gautierdec286d2019-06-04 18:02:37 +0200420 default:
421 cpu_s = "????";
422 break;
423 }
424
425 /* Package */
Yann Gautier30eea112020-02-12 15:38:34 +0100426#if STM32MP13
427 /* On STM32MP13, package is not present in OTP */
428 pkg = "";
429#endif
430#if STM32MP15
Yann Gautier92661e02021-05-10 16:05:18 +0200431 switch (get_cpu_package()) {
Yann Gautierdec286d2019-06-04 18:02:37 +0200432 case PKG_AA_LFBGA448:
433 pkg = "AA";
434 break;
435 case PKG_AB_LFBGA354:
436 pkg = "AB";
437 break;
438 case PKG_AC_TFBGA361:
439 pkg = "AC";
440 break;
441 case PKG_AD_TFBGA257:
442 pkg = "AD";
443 break;
444 default:
445 pkg = "??";
446 break;
447 }
Yann Gautier30eea112020-02-12 15:38:34 +0100448#endif
Yann Gautierdec286d2019-06-04 18:02:37 +0200449
450 /* REVISION */
Yann Gautier92661e02021-05-10 16:05:18 +0200451 switch (stm32mp_get_chip_version()) {
Yann Gautierdec286d2019-06-04 18:02:37 +0200452 case STM32MP1_REV_B:
453 cpu_r = "B";
454 break;
Lionel Debieveffb3f272019-06-25 10:40:37 +0200455 case STM32MP1_REV_Z:
456 cpu_r = "Z";
457 break;
Yann Gautierdec286d2019-06-04 18:02:37 +0200458 default:
459 cpu_r = "?";
460 break;
461 }
462
Yann Gautier92661e02021-05-10 16:05:18 +0200463 snprintf(name, STM32_SOC_NAME_SIZE,
464 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
465}
466
467void stm32mp_print_cpuinfo(void)
468{
469 char name[STM32_SOC_NAME_SIZE];
470
471 stm32mp_get_soc_name(name);
472 NOTICE("CPU: %s\n", name);
Yann Gautierdec286d2019-06-04 18:02:37 +0200473}
474
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200475void stm32mp_print_boardinfo(void)
476{
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100477 uint32_t board_id = 0;
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200478
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100479 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200480 return;
481 }
482
483 if (board_id != 0U) {
484 char rev[2];
485
486 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
487 rev[1] = '\0';
Yann Gautierab049ec2020-10-13 18:03:31 +0200488 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200489 BOARD_ID2NB(board_id),
Patrick Delaunayf964f5c2020-01-08 10:05:14 +0100490 BOARD_ID2VARCPN(board_id),
491 BOARD_ID2VARFG(board_id),
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200492 rev,
493 BOARD_ID2BOM(board_id));
494 }
495}
496
Yann Gautierb2182cd2019-06-04 18:23:10 +0200497/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
498bool stm32mp_is_single_core(void)
499{
Yann Gautier7b48a9f2020-02-06 15:34:16 +0100500#if STM32MP13
501 return true;
502#endif
503#if STM32MP15
Yann Gautierf7130e82021-10-19 13:31:06 +0200504 bool single_core = false;
505
Yann Gautier92661e02021-05-10 16:05:18 +0200506 switch (get_part_number()) {
Yann Gautierb2182cd2019-06-04 18:23:10 +0200507 case STM32MP151A_PART_NB:
508 case STM32MP151C_PART_NB:
Lionel Debieve8ccf4952019-05-17 16:01:18 +0200509 case STM32MP151D_PART_NB:
510 case STM32MP151F_PART_NB:
Yann Gautierf7130e82021-10-19 13:31:06 +0200511 single_core = true;
512 break;
Yann Gautierb2182cd2019-06-04 18:23:10 +0200513 default:
Yann Gautierf7130e82021-10-19 13:31:06 +0200514 break;
Yann Gautierb2182cd2019-06-04 18:23:10 +0200515 }
Yann Gautierf7130e82021-10-19 13:31:06 +0200516
517 return single_core;
Yann Gautier7b48a9f2020-02-06 15:34:16 +0100518#endif
Yann Gautierb2182cd2019-06-04 18:23:10 +0200519}
520
Lionel Debievef7004232019-09-16 12:17:09 +0200521/* Return true when device is in closed state */
522bool stm32mp_is_closed_device(void)
523{
524 uint32_t value;
525
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100526 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debievef7004232019-09-16 12:17:09 +0200527 return true;
528 }
529
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100530 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Lionel Debievef7004232019-09-16 12:17:09 +0200531}
532
Lionel Debieve49abdfd2019-12-06 12:42:20 +0100533/* Return true when device supports secure boot */
534bool stm32mp_is_auth_supported(void)
535{
536 bool supported = false;
537
538 switch (get_part_number()) {
Yann Gautier30eea112020-02-12 15:38:34 +0100539#if STM32MP13
540 case STM32MP131C_PART_NB:
541 case STM32MP131F_PART_NB:
542 case STM32MP133C_PART_NB:
543 case STM32MP133F_PART_NB:
544 case STM32MP135C_PART_NB:
545 case STM32MP135F_PART_NB:
546#endif
547#if STM32MP15
Lionel Debieve49abdfd2019-12-06 12:42:20 +0100548 case STM32MP151C_PART_NB:
549 case STM32MP151F_PART_NB:
550 case STM32MP153C_PART_NB:
551 case STM32MP153F_PART_NB:
552 case STM32MP157C_PART_NB:
553 case STM32MP157F_PART_NB:
Yann Gautier30eea112020-02-12 15:38:34 +0100554#endif
Lionel Debieve49abdfd2019-12-06 12:42:20 +0100555 supported = true;
556 break;
557 default:
558 break;
559 }
560
561 return supported;
562}
563
Yann Gautier73680c22019-06-04 18:06:34 +0200564uint32_t stm32_iwdg_get_instance(uintptr_t base)
565{
566 switch (base) {
567 case IWDG1_BASE:
568 return IWDG1_INST;
569 case IWDG2_BASE:
570 return IWDG2_INST;
571 default:
572 panic();
573 }
574}
575
576uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
577{
578 uint32_t iwdg_cfg = 0U;
579 uint32_t otp_value;
580
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100581 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier73680c22019-06-04 18:06:34 +0200582 panic();
583 }
584
585 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
586 iwdg_cfg |= IWDG_HW_ENABLED;
587 }
588
589 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
590 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
591 }
592
593 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
594 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
595 }
596
597 return iwdg_cfg;
598}
599
600#if defined(IMAGE_BL2)
601uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
602{
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100603 uint32_t otp_value;
Yann Gautier73680c22019-06-04 18:06:34 +0200604 uint32_t otp;
605 uint32_t result;
606
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100607 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
Yann Gautier73680c22019-06-04 18:06:34 +0200608 panic();
609 }
610
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100611 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
612 panic();
Yann Gautier73680c22019-06-04 18:06:34 +0200613 }
614
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100615 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
616 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier73680c22019-06-04 18:06:34 +0200617 }
618
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100619 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
620 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
621 }
622
623 result = bsec_write_otp(otp_value, otp);
Yann Gautier73680c22019-06-04 18:06:34 +0200624 if (result != BSEC_OK) {
625 return result;
626 }
627
628 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100629 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
630 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier73680c22019-06-04 18:06:34 +0200631 return BSEC_LOCK_FAIL;
632 }
633
634 return BSEC_OK;
635}
636#endif
Yann Gautiere6cc3cc2020-02-26 13:39:44 +0100637
Lionel Debieve4584e012020-09-27 21:13:53 +0200638#if STM32MP_USE_STM32IMAGE
Yann Gautiere6cc3cc2020-02-26 13:39:44 +0100639/* Get the non-secure DDR size */
640uint32_t stm32mp_get_ddr_ns_size(void)
641{
642 static uint32_t ddr_ns_size;
643 uint32_t ddr_size;
644
645 if (ddr_ns_size != 0U) {
646 return ddr_ns_size;
647 }
648
649 ddr_size = dt_get_ddr_size();
650 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
651 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
652 panic();
653 }
654
655 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
656
657 return ddr_ns_size;
658}
Lionel Debieve4584e012020-09-27 21:13:53 +0200659#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier4dc77a32021-12-10 17:04:40 +0100660
661void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
662{
Nicolas Toromanoffc8701882022-02-09 12:26:31 +0100663 uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautier4dc77a32021-12-10 17:04:40 +0100664
Yann Gautier33667d22021-08-30 15:06:54 +0200665 clk_enable(RTCAPB);
Yann Gautier4dc77a32021-12-10 17:04:40 +0100666
667 mmio_clrsetbits_32(bkpr_itf_idx,
668 TAMP_BOOT_MODE_ITF_MASK,
669 ((interface << 4) | (instance & 0xFU)) <<
670 TAMP_BOOT_MODE_ITF_SHIFT);
671
Yann Gautier33667d22021-08-30 15:06:54 +0200672 clk_disable(RTCAPB);
Yann Gautier4dc77a32021-12-10 17:04:40 +0100673}
Yann Gautiera6bfa752020-12-16 12:04:06 +0100674
675void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
676{
677 static uint32_t itf;
678
679 if (itf == 0U) {
Nicolas Toromanoffc8701882022-02-09 12:26:31 +0100680 uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautiera6bfa752020-12-16 12:04:06 +0100681
Yann Gautier33667d22021-08-30 15:06:54 +0200682 clk_enable(RTCAPB);
Yann Gautiera6bfa752020-12-16 12:04:06 +0100683
684 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
685 TAMP_BOOT_MODE_ITF_SHIFT;
686
Yann Gautier33667d22021-08-30 15:06:54 +0200687 clk_disable(RTCAPB);
Yann Gautiera6bfa752020-12-16 12:04:06 +0100688 }
689
690 *interface = itf >> 4;
691 *instance = itf & 0xFU;
692}
Sughosh Ganuba02add2021-12-01 15:56:27 +0530693
694#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
695void stm32mp1_fwu_set_boot_idx(void)
696{
697 clk_enable(RTCAPB);
698 mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
699 plat_fwu_get_boot_idx());
700 clk_disable(RTCAPB);
701}
702#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */