blob: 9b39b9d3e6934da432b021204ce9f5d726e009ef [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 Gautier6eef5252021-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 Ganu03e2f802021-12-01 15:56:27 +053044#define TAMP_BOOT_COUNTER_REG_ID U(21)
45
Etienne Carriere72369b12019-12-08 08:17:56 +010046#if defined(IMAGE_BL2)
47#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010048 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010049 MT_MEMORY | \
50 MT_RW | \
51 MT_SECURE | \
52 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-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)
Yann Gautieree8f5422019-02-14 11:13:25 +010060
Etienne Carriere72369b12019-12-08 08:17:56 +010061/* 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
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 Gautieree8f5422019-02-14 11:13:25 +010087 MAP_DEVICE1,
Yann Gautier352d8632020-09-17 11:38:09 +020088#if STM32MP_RAW_NAND
Yann Gautieree8f5422019-02-14 11:13:25 +010089 MAP_DEVICE2,
Yann Gautier352d8632020-09-17 11:38:09 +020090#endif
Yann Gautieree8f5422019-02-14 11:13:25 +010091 {0}
92};
93#endif
94#if defined(IMAGE_BL32)
95static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010096 MAP_SEC_SYSRAM,
97 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-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 Gautiere3bf9132019-05-07 18:52:17 +0200111
Etienne Carriere66b04522019-12-02 10:05:02 +0100112uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
113{
114 if (bank == GPIO_BANK_Z) {
115 return GPIOZ_BASE;
116 }
117
118 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
119
120 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
121}
122
123uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
124{
125 if (bank == GPIO_BANK_Z) {
126 return 0;
127 }
128
129 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
130
131 return bank * GPIO_BANK_OFFSET;
132}
133
Yann Gautier2b79c372021-06-11 10:54:56 +0200134bool stm32_gpio_is_secure_at_reset(unsigned int bank)
135{
136 if (bank == GPIO_BANK_Z) {
137 return true;
138 }
139
140 return false;
141}
142
Yann Gautiere3bf9132019-05-07 18:52:17 +0200143unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
144{
145 if (bank == GPIO_BANK_Z) {
146 return GPIOZ;
147 }
148
149 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
150
151 return GPIOA + (bank - GPIO_BANK_A);
152}
Yann Gautier091eab52019-06-04 18:06:34 +0200153
Etienne Carriered81dadf2020-04-25 11:14:45 +0200154int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
155{
156 switch (bank) {
157 case GPIO_BANK_A:
158 case GPIO_BANK_B:
159 case GPIO_BANK_C:
160 case GPIO_BANK_D:
161 case GPIO_BANK_E:
162 case GPIO_BANK_F:
163 case GPIO_BANK_G:
164 case GPIO_BANK_H:
165 case GPIO_BANK_I:
166 case GPIO_BANK_J:
167 case GPIO_BANK_K:
168 return fdt_path_offset(fdt, "/soc/pin-controller");
169 case GPIO_BANK_Z:
170 return fdt_path_offset(fdt, "/soc/pin-controller-z");
171 default:
172 panic();
173 }
174}
175
Yann Gautier3d8497c2021-10-18 16:06:22 +0200176#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200177/*
178 * UART Management
179 */
180static const uintptr_t stm32mp1_uart_addresses[8] = {
181 USART1_BASE,
182 USART2_BASE,
183 USART3_BASE,
184 UART4_BASE,
185 UART5_BASE,
186 USART6_BASE,
187 UART7_BASE,
188 UART8_BASE,
189};
190
191uintptr_t get_uart_address(uint32_t instance_nb)
192{
193 if ((instance_nb == 0U) ||
194 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
195 return 0U;
196 }
197
198 return stm32mp1_uart_addresses[instance_nb - 1U];
199}
200#endif
201
Yann Gautiercd16df32021-06-04 14:04:05 +0200202#if STM32MP_USB_PROGRAMMER
203struct gpio_bank_pin_list {
204 uint32_t bank;
205 uint32_t pin;
206};
207
208static const struct gpio_bank_pin_list gpio_list[] = {
209 { /* USART2_RX: GPIOA3 */
210 .bank = 0U,
211 .pin = 3U,
212 },
213 { /* USART3_RX: GPIOB12 */
214 .bank = 1U,
215 .pin = 12U,
216 },
217 { /* UART4_RX: GPIOB2 */
218 .bank = 1U,
219 .pin = 2U,
220 },
221 { /* UART5_RX: GPIOB4 */
222 .bank = 1U,
223 .pin = 5U,
224 },
225 { /* USART6_RX: GPIOC7 */
226 .bank = 2U,
227 .pin = 7U,
228 },
229 { /* UART7_RX: GPIOF6 */
230 .bank = 5U,
231 .pin = 6U,
232 },
233 { /* UART8_RX: GPIOE0 */
234 .bank = 4U,
235 .pin = 0U,
236 },
237};
238
239void stm32mp1_deconfigure_uart_pins(void)
240{
241 size_t i;
242
243 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
244 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
245 }
246}
247#endif
248
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200249uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200250{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200251 uint32_t version = 0U;
252
253 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
254 INFO("Cannot get CPU version, debug disabled\n");
255 return 0U;
256 }
257
258 return version;
259}
Yann Gautierc7374052019-06-04 18:02:37 +0200260
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200261uint32_t stm32mp_get_chip_dev_id(void)
262{
263 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200264
Yann Gautierc7374052019-06-04 18:02:37 +0200265 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200266 INFO("Use default chip ID, debug disabled\n");
267 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200268 }
269
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200270 return dev_id;
271}
272
273static uint32_t get_part_number(void)
274{
275 static uint32_t part_number;
276
277 if (part_number != 0U) {
278 return part_number;
279 }
280
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100281 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200282 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200283 }
284
285 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
286 PART_NUMBER_OTP_PART_SHIFT;
287
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200288 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200289
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200290 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200291}
292
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200293static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200294{
295 uint32_t package;
296
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100297 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200298 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200299 }
300
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200301 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200302 PACKAGE_OTP_PKG_SHIFT;
303
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200304 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200305}
306
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200307void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200308{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200309 char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200310
311 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200312 switch (get_part_number()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200313 case STM32MP157C_PART_NB:
314 cpu_s = "157C";
315 break;
316 case STM32MP157A_PART_NB:
317 cpu_s = "157A";
318 break;
319 case STM32MP153C_PART_NB:
320 cpu_s = "153C";
321 break;
322 case STM32MP153A_PART_NB:
323 cpu_s = "153A";
324 break;
325 case STM32MP151C_PART_NB:
326 cpu_s = "151C";
327 break;
328 case STM32MP151A_PART_NB:
329 cpu_s = "151A";
330 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200331 case STM32MP157F_PART_NB:
332 cpu_s = "157F";
333 break;
334 case STM32MP157D_PART_NB:
335 cpu_s = "157D";
336 break;
337 case STM32MP153F_PART_NB:
338 cpu_s = "153F";
339 break;
340 case STM32MP153D_PART_NB:
341 cpu_s = "153D";
342 break;
343 case STM32MP151F_PART_NB:
344 cpu_s = "151F";
345 break;
346 case STM32MP151D_PART_NB:
347 cpu_s = "151D";
348 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200349 default:
350 cpu_s = "????";
351 break;
352 }
353
354 /* Package */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200355 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200356 case PKG_AA_LFBGA448:
357 pkg = "AA";
358 break;
359 case PKG_AB_LFBGA354:
360 pkg = "AB";
361 break;
362 case PKG_AC_TFBGA361:
363 pkg = "AC";
364 break;
365 case PKG_AD_TFBGA257:
366 pkg = "AD";
367 break;
368 default:
369 pkg = "??";
370 break;
371 }
372
373 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200374 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200375 case STM32MP1_REV_B:
376 cpu_r = "B";
377 break;
Lionel Debieve2d64b532019-06-25 10:40:37 +0200378 case STM32MP1_REV_Z:
379 cpu_r = "Z";
380 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200381 default:
382 cpu_r = "?";
383 break;
384 }
385
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200386 snprintf(name, STM32_SOC_NAME_SIZE,
387 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
388}
389
390void stm32mp_print_cpuinfo(void)
391{
392 char name[STM32_SOC_NAME_SIZE];
393
394 stm32mp_get_soc_name(name);
395 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200396}
397
Yann Gautier35dc0772019-05-13 18:34:48 +0200398void stm32mp_print_boardinfo(void)
399{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100400 uint32_t board_id = 0;
Yann Gautier35dc0772019-05-13 18:34:48 +0200401
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100402 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier35dc0772019-05-13 18:34:48 +0200403 return;
404 }
405
Yann Gautier35dc0772019-05-13 18:34:48 +0200406 if (board_id != 0U) {
407 char rev[2];
408
409 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
410 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200411 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200412 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100413 BOARD_ID2VARCPN(board_id),
414 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200415 rev,
416 BOARD_ID2BOM(board_id));
417 }
418}
419
Yann Gautieraf19ff92019-06-04 18:23:10 +0200420/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
421bool stm32mp_is_single_core(void)
422{
Yann Gautier2f3b5602021-10-19 13:31:06 +0200423 bool single_core = false;
424
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200425 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200426 case STM32MP151A_PART_NB:
427 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200428 case STM32MP151D_PART_NB:
429 case STM32MP151F_PART_NB:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200430 single_core = true;
431 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200432 default:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200433 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200434 }
Yann Gautier2f3b5602021-10-19 13:31:06 +0200435
436 return single_core;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200437}
438
Lionel Debieve0e73d732019-09-16 12:17:09 +0200439/* Return true when device is in closed state */
440bool stm32mp_is_closed_device(void)
441{
442 uint32_t value;
443
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100444 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debieve0e73d732019-09-16 12:17:09 +0200445 return true;
446 }
447
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100448 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Lionel Debieve0e73d732019-09-16 12:17:09 +0200449}
450
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100451/* Return true when device supports secure boot */
452bool stm32mp_is_auth_supported(void)
453{
454 bool supported = false;
455
456 switch (get_part_number()) {
457 case STM32MP151C_PART_NB:
458 case STM32MP151F_PART_NB:
459 case STM32MP153C_PART_NB:
460 case STM32MP153F_PART_NB:
461 case STM32MP157C_PART_NB:
462 case STM32MP157F_PART_NB:
463 supported = true;
464 break;
465 default:
466 break;
467 }
468
469 return supported;
470}
471
Yann Gautier091eab52019-06-04 18:06:34 +0200472uint32_t stm32_iwdg_get_instance(uintptr_t base)
473{
474 switch (base) {
475 case IWDG1_BASE:
476 return IWDG1_INST;
477 case IWDG2_BASE:
478 return IWDG2_INST;
479 default:
480 panic();
481 }
482}
483
484uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
485{
486 uint32_t iwdg_cfg = 0U;
487 uint32_t otp_value;
488
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100489 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200490 panic();
491 }
492
493 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
494 iwdg_cfg |= IWDG_HW_ENABLED;
495 }
496
497 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
498 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
499 }
500
501 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
502 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
503 }
504
505 return iwdg_cfg;
506}
507
508#if defined(IMAGE_BL2)
509uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
510{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100511 uint32_t otp_value;
Yann Gautier091eab52019-06-04 18:06:34 +0200512 uint32_t otp;
513 uint32_t result;
514
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100515 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
516 panic();
517 }
518
519 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200520 panic();
521 }
522
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100523 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
524 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200525 }
526
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100527 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
528 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200529 }
530
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100531 result = bsec_write_otp(otp_value, otp);
Yann Gautier091eab52019-06-04 18:06:34 +0200532 if (result != BSEC_OK) {
533 return result;
534 }
535
536 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100537 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
538 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier091eab52019-06-04 18:06:34 +0200539 return BSEC_LOCK_FAIL;
540 }
541
542 return BSEC_OK;
543}
544#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100545
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200546#if STM32MP_USE_STM32IMAGE
Yann Gautier8f268c82020-02-26 13:39:44 +0100547/* Get the non-secure DDR size */
548uint32_t stm32mp_get_ddr_ns_size(void)
549{
550 static uint32_t ddr_ns_size;
551 uint32_t ddr_size;
552
553 if (ddr_ns_size != 0U) {
554 return ddr_ns_size;
555 }
556
557 ddr_size = dt_get_ddr_size();
558 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
559 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
560 panic();
561 }
562
563 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
564
565 return ddr_ns_size;
566}
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200567#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier6eef5252021-12-10 17:04:40 +0100568
569void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
570{
571 uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
572
Yann Gautiera205a5c2021-08-30 15:06:54 +0200573 clk_enable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100574
575 mmio_clrsetbits_32(bkpr_itf_idx,
576 TAMP_BOOT_MODE_ITF_MASK,
577 ((interface << 4) | (instance & 0xFU)) <<
578 TAMP_BOOT_MODE_ITF_SHIFT);
579
Yann Gautiera205a5c2021-08-30 15:06:54 +0200580 clk_disable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100581}
Yann Gautieraaee0612020-12-16 12:04:06 +0100582
583void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
584{
585 static uint32_t itf;
586
587 if (itf == 0U) {
588 uint32_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
589
Yann Gautiera205a5c2021-08-30 15:06:54 +0200590 clk_enable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100591
592 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
593 TAMP_BOOT_MODE_ITF_SHIFT;
594
Yann Gautiera205a5c2021-08-30 15:06:54 +0200595 clk_disable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100596 }
597
598 *interface = itf >> 4;
599 *instance = itf & 0xFU;
600}
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530601
602#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
603void stm32mp1_fwu_set_boot_idx(void)
604{
605 clk_enable(RTCAPB);
606 mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
607 plat_fwu_get_boot_idx());
608 clk_disable(RTCAPB);
609}
610#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */