blob: 6e729b551863709e23d21f7329ec78fe852a45ce [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 Gautier4dc77a32021-12-10 17:04:40 +010040#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
41#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
42#define TAMP_BOOT_MODE_ITF_SHIFT 8
43
Sughosh Ganuba02add2021-12-01 15:56:27 +053044#define TAMP_BOOT_COUNTER_REG_ID U(21)
45
Etienne Carriere07541432019-12-08 08:17:56 +010046#if defined(IMAGE_BL2)
47#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautier3f9c9782019-02-14 11:13:39 +010048 STM32MP_SYSRAM_SIZE, \
Yann Gautierc9d75b32019-02-14 11:13:25 +010049 MT_MEMORY | \
50 MT_RW | \
51 MT_SECURE | \
52 MT_EXECUTE_NEVER)
Etienne Carriere07541432019-12-08 08:17:56 +010053#elif defined(IMAGE_BL32)
54#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
55 STM32MP_SEC_SYSRAM_SIZE, \
56 MT_MEMORY | \
57 MT_RW | \
58 MT_SECURE | \
59 MT_EXECUTE_NEVER)
60
61/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
62#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
63 STM32MP_NS_SYSRAM_SIZE, \
64 MT_DEVICE | \
65 MT_RW | \
66 MT_NS | \
67 MT_EXECUTE_NEVER)
68#endif
Yann Gautierc9d75b32019-02-14 11:13:25 +010069
70#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 Carriere07541432019-12-08 08:17:56 +010086 MAP_SEC_SYSRAM,
Yann Gautierc9d75b32019-02-14 11:13:25 +010087 MAP_DEVICE1,
Yann Gautierdb3e0ec2020-09-17 11:38:09 +020088#if STM32MP_RAW_NAND
Yann Gautierc9d75b32019-02-14 11:13:25 +010089 MAP_DEVICE2,
Yann Gautierdb3e0ec2020-09-17 11:38:09 +020090#endif
Yann Gautierc9d75b32019-02-14 11:13:25 +010091 {0}
92};
93#endif
94#if defined(IMAGE_BL32)
95static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere07541432019-12-08 08:17:56 +010096 MAP_SEC_SYSRAM,
97 MAP_NS_SYSRAM,
Yann Gautierc9d75b32019-02-14 11:13:25 +010098 MAP_DEVICE1,
99 MAP_DEVICE2,
100 {0}
101};
102#endif
103
104void configure_mmu(void)
105{
106 mmap_add(stm32mp1_mmap);
107 init_xlat_tables();
108
109 enable_mmu_svc_mon(0);
110}
Yann Gautier8f282da2019-05-07 18:52:17 +0200111
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100112uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
113{
Yann Gautier111a3842020-02-12 09:36:23 +0100114#if STM32MP13
115 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
116#endif
117#if STM32MP15
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100118 if (bank == GPIO_BANK_Z) {
119 return GPIOZ_BASE;
120 }
121
122 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautier111a3842020-02-12 09:36:23 +0100123#endif
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100124
125 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
126}
127
128uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
129{
Yann Gautier111a3842020-02-12 09:36:23 +0100130#if STM32MP13
131 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
132#endif
133#if STM32MP15
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100134 if (bank == GPIO_BANK_Z) {
135 return 0;
136 }
137
138 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautier111a3842020-02-12 09:36:23 +0100139#endif
Etienne Carrierec0ea3b12019-12-02 10:05:02 +0100140
141 return bank * GPIO_BANK_OFFSET;
142}
143
Yann Gautier737ad292021-06-11 10:54:56 +0200144bool stm32_gpio_is_secure_at_reset(unsigned int bank)
145{
Yann Gautier111a3842020-02-12 09:36:23 +0100146#if STM32MP13
147 return true;
148#endif
149#if STM32MP15
Yann Gautier737ad292021-06-11 10:54:56 +0200150 if (bank == GPIO_BANK_Z) {
151 return true;
152 }
153
154 return false;
Yann Gautier111a3842020-02-12 09:36:23 +0100155#endif
Yann Gautier737ad292021-06-11 10:54:56 +0200156}
157
Yann Gautier8f282da2019-05-07 18:52:17 +0200158unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
159{
Yann Gautier111a3842020-02-12 09:36:23 +0100160#if STM32MP13
161 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
162#endif
163#if STM32MP15
Yann Gautier8f282da2019-05-07 18:52:17 +0200164 if (bank == GPIO_BANK_Z) {
165 return GPIOZ;
166 }
167
168 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautier111a3842020-02-12 09:36:23 +0100169#endif
Yann Gautier8f282da2019-05-07 18:52:17 +0200170
171 return GPIOA + (bank - GPIO_BANK_A);
172}
Yann Gautier73680c22019-06-04 18:06:34 +0200173
Etienne Carriereccc199e2020-04-25 11:14:45 +0200174int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
175{
176 switch (bank) {
177 case GPIO_BANK_A:
178 case GPIO_BANK_B:
179 case GPIO_BANK_C:
180 case GPIO_BANK_D:
181 case GPIO_BANK_E:
182 case GPIO_BANK_F:
183 case GPIO_BANK_G:
184 case GPIO_BANK_H:
185 case GPIO_BANK_I:
Yann Gautier111a3842020-02-12 09:36:23 +0100186#if STM32MP15
Etienne Carriereccc199e2020-04-25 11:14:45 +0200187 case GPIO_BANK_J:
188 case GPIO_BANK_K:
Yann Gautier111a3842020-02-12 09:36:23 +0100189#endif
Etienne Carriereccc199e2020-04-25 11:14:45 +0200190 return fdt_path_offset(fdt, "/soc/pin-controller");
Yann Gautier111a3842020-02-12 09:36:23 +0100191#if STM32MP15
Etienne Carriereccc199e2020-04-25 11:14:45 +0200192 case GPIO_BANK_Z:
193 return fdt_path_offset(fdt, "/soc/pin-controller-z");
Yann Gautier111a3842020-02-12 09:36:23 +0100194#endif
Etienne Carriereccc199e2020-04-25 11:14:45 +0200195 default:
196 panic();
197 }
198}
199
Yann Gautieracf28c22021-10-18 16:06:22 +0200200#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunay9083fa12021-10-28 13:48:52 +0200201/*
202 * UART Management
203 */
204static const uintptr_t stm32mp1_uart_addresses[8] = {
205 USART1_BASE,
206 USART2_BASE,
207 USART3_BASE,
208 UART4_BASE,
209 UART5_BASE,
210 USART6_BASE,
211 UART7_BASE,
212 UART8_BASE,
213};
214
215uintptr_t get_uart_address(uint32_t instance_nb)
216{
217 if ((instance_nb == 0U) ||
218 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
219 return 0U;
220 }
221
222 return stm32mp1_uart_addresses[instance_nb - 1U];
223}
224#endif
225
Yann Gautierd7176f02021-06-04 14:04:05 +0200226#if STM32MP_USB_PROGRAMMER
227struct gpio_bank_pin_list {
228 uint32_t bank;
229 uint32_t pin;
230};
231
232static const struct gpio_bank_pin_list gpio_list[] = {
233 { /* USART2_RX: GPIOA3 */
234 .bank = 0U,
235 .pin = 3U,
236 },
237 { /* USART3_RX: GPIOB12 */
238 .bank = 1U,
239 .pin = 12U,
240 },
241 { /* UART4_RX: GPIOB2 */
242 .bank = 1U,
243 .pin = 2U,
244 },
245 { /* UART5_RX: GPIOB4 */
246 .bank = 1U,
247 .pin = 5U,
248 },
249 { /* USART6_RX: GPIOC7 */
250 .bank = 2U,
251 .pin = 7U,
252 },
253 { /* UART7_RX: GPIOF6 */
254 .bank = 5U,
255 .pin = 6U,
256 },
257 { /* UART8_RX: GPIOE0 */
258 .bank = 4U,
259 .pin = 0U,
260 },
261};
262
263void stm32mp1_deconfigure_uart_pins(void)
264{
265 size_t i;
266
267 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
268 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
269 }
270}
271#endif
272
Yann Gautier92661e02021-05-10 16:05:18 +0200273uint32_t stm32mp_get_chip_version(void)
Yann Gautierdec286d2019-06-04 18:02:37 +0200274{
Yann Gautier92661e02021-05-10 16:05:18 +0200275 uint32_t version = 0U;
276
277 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
278 INFO("Cannot get CPU version, debug disabled\n");
279 return 0U;
280 }
281
282 return version;
283}
284
285uint32_t stm32mp_get_chip_dev_id(void)
286{
Yann Gautierdec286d2019-06-04 18:02:37 +0200287 uint32_t dev_id;
288
289 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautier92661e02021-05-10 16:05:18 +0200290 INFO("Use default chip ID, debug disabled\n");
291 dev_id = STM32MP1_CHIP_ID;
292 }
293
294 return dev_id;
295}
296
297static uint32_t get_part_number(void)
298{
299 static uint32_t part_number;
300
301 if (part_number != 0U) {
302 return part_number;
Yann Gautierdec286d2019-06-04 18:02:37 +0200303 }
304
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100305 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautier92661e02021-05-10 16:05:18 +0200306 panic();
Yann Gautierdec286d2019-06-04 18:02:37 +0200307 }
308
309 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
310 PART_NUMBER_OTP_PART_SHIFT;
311
Yann Gautier92661e02021-05-10 16:05:18 +0200312 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierdec286d2019-06-04 18:02:37 +0200313
Yann Gautier92661e02021-05-10 16:05:18 +0200314 return part_number;
Yann Gautierdec286d2019-06-04 18:02:37 +0200315}
316
Yann Gautier92661e02021-05-10 16:05:18 +0200317static uint32_t get_cpu_package(void)
Yann Gautierdec286d2019-06-04 18:02:37 +0200318{
319 uint32_t package;
320
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100321 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautier92661e02021-05-10 16:05:18 +0200322 panic();
Yann Gautierdec286d2019-06-04 18:02:37 +0200323 }
324
Yann Gautier92661e02021-05-10 16:05:18 +0200325 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierdec286d2019-06-04 18:02:37 +0200326 PACKAGE_OTP_PKG_SHIFT;
327
Yann Gautier92661e02021-05-10 16:05:18 +0200328 return package;
Yann Gautierdec286d2019-06-04 18:02:37 +0200329}
330
Yann Gautier92661e02021-05-10 16:05:18 +0200331void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierdec286d2019-06-04 18:02:37 +0200332{
Yann Gautier92661e02021-05-10 16:05:18 +0200333 char *cpu_s, *cpu_r, *pkg;
Yann Gautierdec286d2019-06-04 18:02:37 +0200334
335 /* MPUs Part Numbers */
Yann Gautier92661e02021-05-10 16:05:18 +0200336 switch (get_part_number()) {
Yann Gautierdec286d2019-06-04 18:02:37 +0200337 case STM32MP157C_PART_NB:
338 cpu_s = "157C";
339 break;
340 case STM32MP157A_PART_NB:
341 cpu_s = "157A";
342 break;
343 case STM32MP153C_PART_NB:
344 cpu_s = "153C";
345 break;
346 case STM32MP153A_PART_NB:
347 cpu_s = "153A";
348 break;
349 case STM32MP151C_PART_NB:
350 cpu_s = "151C";
351 break;
352 case STM32MP151A_PART_NB:
353 cpu_s = "151A";
354 break;
Lionel Debieve8ccf4952019-05-17 16:01:18 +0200355 case STM32MP157F_PART_NB:
356 cpu_s = "157F";
357 break;
358 case STM32MP157D_PART_NB:
359 cpu_s = "157D";
360 break;
361 case STM32MP153F_PART_NB:
362 cpu_s = "153F";
363 break;
364 case STM32MP153D_PART_NB:
365 cpu_s = "153D";
366 break;
367 case STM32MP151F_PART_NB:
368 cpu_s = "151F";
369 break;
370 case STM32MP151D_PART_NB:
371 cpu_s = "151D";
372 break;
Yann Gautierdec286d2019-06-04 18:02:37 +0200373 default:
374 cpu_s = "????";
375 break;
376 }
377
378 /* Package */
Yann Gautier92661e02021-05-10 16:05:18 +0200379 switch (get_cpu_package()) {
Yann Gautierdec286d2019-06-04 18:02:37 +0200380 case PKG_AA_LFBGA448:
381 pkg = "AA";
382 break;
383 case PKG_AB_LFBGA354:
384 pkg = "AB";
385 break;
386 case PKG_AC_TFBGA361:
387 pkg = "AC";
388 break;
389 case PKG_AD_TFBGA257:
390 pkg = "AD";
391 break;
392 default:
393 pkg = "??";
394 break;
395 }
396
397 /* REVISION */
Yann Gautier92661e02021-05-10 16:05:18 +0200398 switch (stm32mp_get_chip_version()) {
Yann Gautierdec286d2019-06-04 18:02:37 +0200399 case STM32MP1_REV_B:
400 cpu_r = "B";
401 break;
Lionel Debieveffb3f272019-06-25 10:40:37 +0200402 case STM32MP1_REV_Z:
403 cpu_r = "Z";
404 break;
Yann Gautierdec286d2019-06-04 18:02:37 +0200405 default:
406 cpu_r = "?";
407 break;
408 }
409
Yann Gautier92661e02021-05-10 16:05:18 +0200410 snprintf(name, STM32_SOC_NAME_SIZE,
411 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
412}
413
414void stm32mp_print_cpuinfo(void)
415{
416 char name[STM32_SOC_NAME_SIZE];
417
418 stm32mp_get_soc_name(name);
419 NOTICE("CPU: %s\n", name);
Yann Gautierdec286d2019-06-04 18:02:37 +0200420}
421
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200422void stm32mp_print_boardinfo(void)
423{
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100424 uint32_t board_id = 0;
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200425
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100426 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200427 return;
428 }
429
430 if (board_id != 0U) {
431 char rev[2];
432
433 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
434 rev[1] = '\0';
Yann Gautierab049ec2020-10-13 18:03:31 +0200435 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200436 BOARD_ID2NB(board_id),
Patrick Delaunayf964f5c2020-01-08 10:05:14 +0100437 BOARD_ID2VARCPN(board_id),
438 BOARD_ID2VARFG(board_id),
Yann Gautier10e7a9e2019-05-13 18:34:48 +0200439 rev,
440 BOARD_ID2BOM(board_id));
441 }
442}
443
Yann Gautierb2182cd2019-06-04 18:23:10 +0200444/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
445bool stm32mp_is_single_core(void)
446{
Yann Gautier7b48a9f2020-02-06 15:34:16 +0100447#if STM32MP13
448 return true;
449#endif
450#if STM32MP15
Yann Gautierf7130e82021-10-19 13:31:06 +0200451 bool single_core = false;
452
Yann Gautier92661e02021-05-10 16:05:18 +0200453 switch (get_part_number()) {
Yann Gautierb2182cd2019-06-04 18:23:10 +0200454 case STM32MP151A_PART_NB:
455 case STM32MP151C_PART_NB:
Lionel Debieve8ccf4952019-05-17 16:01:18 +0200456 case STM32MP151D_PART_NB:
457 case STM32MP151F_PART_NB:
Yann Gautierf7130e82021-10-19 13:31:06 +0200458 single_core = true;
459 break;
Yann Gautierb2182cd2019-06-04 18:23:10 +0200460 default:
Yann Gautierf7130e82021-10-19 13:31:06 +0200461 break;
Yann Gautierb2182cd2019-06-04 18:23:10 +0200462 }
Yann Gautierf7130e82021-10-19 13:31:06 +0200463
464 return single_core;
Yann Gautier7b48a9f2020-02-06 15:34:16 +0100465#endif
Yann Gautierb2182cd2019-06-04 18:23:10 +0200466}
467
Lionel Debievef7004232019-09-16 12:17:09 +0200468/* Return true when device is in closed state */
469bool stm32mp_is_closed_device(void)
470{
471 uint32_t value;
472
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100473 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debievef7004232019-09-16 12:17:09 +0200474 return true;
475 }
476
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100477 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Lionel Debievef7004232019-09-16 12:17:09 +0200478}
479
Lionel Debieve49abdfd2019-12-06 12:42:20 +0100480/* Return true when device supports secure boot */
481bool stm32mp_is_auth_supported(void)
482{
483 bool supported = false;
484
485 switch (get_part_number()) {
486 case STM32MP151C_PART_NB:
487 case STM32MP151F_PART_NB:
488 case STM32MP153C_PART_NB:
489 case STM32MP153F_PART_NB:
490 case STM32MP157C_PART_NB:
491 case STM32MP157F_PART_NB:
492 supported = true;
493 break;
494 default:
495 break;
496 }
497
498 return supported;
499}
500
Yann Gautier73680c22019-06-04 18:06:34 +0200501uint32_t stm32_iwdg_get_instance(uintptr_t base)
502{
503 switch (base) {
504 case IWDG1_BASE:
505 return IWDG1_INST;
506 case IWDG2_BASE:
507 return IWDG2_INST;
508 default:
509 panic();
510 }
511}
512
513uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
514{
515 uint32_t iwdg_cfg = 0U;
516 uint32_t otp_value;
517
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100518 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier73680c22019-06-04 18:06:34 +0200519 panic();
520 }
521
522 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
523 iwdg_cfg |= IWDG_HW_ENABLED;
524 }
525
526 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
527 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
528 }
529
530 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
531 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
532 }
533
534 return iwdg_cfg;
535}
536
537#if defined(IMAGE_BL2)
538uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
539{
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100540 uint32_t otp_value;
Yann Gautier73680c22019-06-04 18:06:34 +0200541 uint32_t otp;
542 uint32_t result;
543
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100544 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
Yann Gautier73680c22019-06-04 18:06:34 +0200545 panic();
546 }
547
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100548 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
549 panic();
Yann Gautier73680c22019-06-04 18:06:34 +0200550 }
551
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100552 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
553 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier73680c22019-06-04 18:06:34 +0200554 }
555
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100556 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
557 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
558 }
559
560 result = bsec_write_otp(otp_value, otp);
Yann Gautier73680c22019-06-04 18:06:34 +0200561 if (result != BSEC_OK) {
562 return result;
563 }
564
565 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debieveae3ce8b2019-11-04 14:31:38 +0100566 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
567 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier73680c22019-06-04 18:06:34 +0200568 return BSEC_LOCK_FAIL;
569 }
570
571 return BSEC_OK;
572}
573#endif
Yann Gautiere6cc3cc2020-02-26 13:39:44 +0100574
Lionel Debieve4584e012020-09-27 21:13:53 +0200575#if STM32MP_USE_STM32IMAGE
Yann Gautiere6cc3cc2020-02-26 13:39:44 +0100576/* Get the non-secure DDR size */
577uint32_t stm32mp_get_ddr_ns_size(void)
578{
579 static uint32_t ddr_ns_size;
580 uint32_t ddr_size;
581
582 if (ddr_ns_size != 0U) {
583 return ddr_ns_size;
584 }
585
586 ddr_size = dt_get_ddr_size();
587 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
588 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
589 panic();
590 }
591
592 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
593
594 return ddr_ns_size;
595}
Lionel Debieve4584e012020-09-27 21:13:53 +0200596#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier4dc77a32021-12-10 17:04:40 +0100597
598void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
599{
Nicolas Toromanoffc8701882022-02-09 12:26:31 +0100600 uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautier4dc77a32021-12-10 17:04:40 +0100601
Yann Gautier33667d22021-08-30 15:06:54 +0200602 clk_enable(RTCAPB);
Yann Gautier4dc77a32021-12-10 17:04:40 +0100603
604 mmio_clrsetbits_32(bkpr_itf_idx,
605 TAMP_BOOT_MODE_ITF_MASK,
606 ((interface << 4) | (instance & 0xFU)) <<
607 TAMP_BOOT_MODE_ITF_SHIFT);
608
Yann Gautier33667d22021-08-30 15:06:54 +0200609 clk_disable(RTCAPB);
Yann Gautier4dc77a32021-12-10 17:04:40 +0100610}
Yann Gautiera6bfa752020-12-16 12:04:06 +0100611
612void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
613{
614 static uint32_t itf;
615
616 if (itf == 0U) {
Nicolas Toromanoffc8701882022-02-09 12:26:31 +0100617 uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautiera6bfa752020-12-16 12:04:06 +0100618
Yann Gautier33667d22021-08-30 15:06:54 +0200619 clk_enable(RTCAPB);
Yann Gautiera6bfa752020-12-16 12:04:06 +0100620
621 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
622 TAMP_BOOT_MODE_ITF_SHIFT;
623
Yann Gautier33667d22021-08-30 15:06:54 +0200624 clk_disable(RTCAPB);
Yann Gautiera6bfa752020-12-16 12:04:06 +0100625 }
626
627 *interface = itf >> 4;
628 *instance = itf & 0xFU;
629}
Sughosh Ganuba02add2021-12-01 15:56:27 +0530630
631#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
632void stm32mp1_fwu_set_boot_idx(void)
633{
634 clk_enable(RTCAPB);
635 mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
636 plat_fwu_get_boot_idx());
637 clk_disable(RTCAPB);
638}
639#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */