blob: f1f7e372f106a34b8bf98723b3b59c9be4498d8b [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 Gautier82000472020-02-05 16:24:21 +010040#if STM32MP13
41#define TAMP_BOOT_MODE_BACKUP_REG_ID U(30)
42#endif
43#if STM32MP15
Yann Gautier6eef5252021-12-10 17:04:40 +010044#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
Yann Gautier82000472020-02-05 16:24:21 +010045#endif
Yann Gautier6eef5252021-12-10 17:04:40 +010046#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
47#define TAMP_BOOT_MODE_ITF_SHIFT 8
48
Sughosh Ganu03e2f802021-12-01 15:56:27 +053049#define TAMP_BOOT_COUNTER_REG_ID U(21)
50
Etienne Carriere72369b12019-12-08 08:17:56 +010051#if defined(IMAGE_BL2)
52#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010053 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010054 MT_MEMORY | \
55 MT_RW | \
56 MT_SECURE | \
57 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-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)
Yann Gautieree8f5422019-02-14 11:13:25 +010065
Etienne Carriere72369b12019-12-08 08:17:56 +010066/* 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
74
Yann Gautieree8f5422019-02-14 11:13:25 +010075#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 Carriere72369b12019-12-08 08:17:56 +010091 MAP_SEC_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +010092 MAP_DEVICE1,
Yann Gautier352d8632020-09-17 11:38:09 +020093#if STM32MP_RAW_NAND
Yann Gautieree8f5422019-02-14 11:13:25 +010094 MAP_DEVICE2,
Yann Gautier352d8632020-09-17 11:38:09 +020095#endif
Yann Gautieree8f5422019-02-14 11:13:25 +010096 {0}
97};
98#endif
99#if defined(IMAGE_BL32)
100static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100101 MAP_SEC_SYSRAM,
102 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-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 Gautiere3bf9132019-05-07 18:52:17 +0200116
Etienne Carriere66b04522019-12-02 10:05:02 +0100117uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
118{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100119#if STM32MP13
120 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
121#endif
122#if STM32MP15
Etienne Carriere66b04522019-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 Gautiercc5f89a2020-02-12 09:36:23 +0100128#endif
Etienne Carriere66b04522019-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 Gautiercc5f89a2020-02-12 09:36:23 +0100135#if STM32MP13
136 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
137#endif
138#if STM32MP15
Etienne Carriere66b04522019-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 Gautiercc5f89a2020-02-12 09:36:23 +0100144#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100145
146 return bank * GPIO_BANK_OFFSET;
147}
148
Yann Gautier2b79c372021-06-11 10:54:56 +0200149bool stm32_gpio_is_secure_at_reset(unsigned int bank)
150{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100151#if STM32MP13
152 return true;
153#endif
154#if STM32MP15
Yann Gautier2b79c372021-06-11 10:54:56 +0200155 if (bank == GPIO_BANK_Z) {
156 return true;
157 }
158
159 return false;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100160#endif
Yann Gautier2b79c372021-06-11 10:54:56 +0200161}
162
Yann Gautiere3bf9132019-05-07 18:52:17 +0200163unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
164{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100165#if STM32MP13
166 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
167#endif
168#if STM32MP15
Yann Gautiere3bf9132019-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 Gautiercc5f89a2020-02-12 09:36:23 +0100174#endif
Yann Gautiere3bf9132019-05-07 18:52:17 +0200175
176 return GPIOA + (bank - GPIO_BANK_A);
177}
Yann Gautier091eab52019-06-04 18:06:34 +0200178
Etienne Carriered81dadf2020-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 Gautiercc5f89a2020-02-12 09:36:23 +0100191#if STM32MP15
Etienne Carriered81dadf2020-04-25 11:14:45 +0200192 case GPIO_BANK_J:
193 case GPIO_BANK_K:
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100194#endif
Etienne Carriered81dadf2020-04-25 11:14:45 +0200195 return fdt_path_offset(fdt, "/soc/pin-controller");
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100196#if STM32MP15
Etienne Carriered81dadf2020-04-25 11:14:45 +0200197 case GPIO_BANK_Z:
198 return fdt_path_offset(fdt, "/soc/pin-controller-z");
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100199#endif
Etienne Carriered81dadf2020-04-25 11:14:45 +0200200 default:
201 panic();
202 }
203}
204
Yann Gautier3d8497c2021-10-18 16:06:22 +0200205#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-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 Gautiercd16df32021-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 Gautiera0a6ff62021-05-10 16:05:18 +0200278uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200279{
Yann Gautiera0a6ff62021-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}
Yann Gautierc7374052019-06-04 18:02:37 +0200289
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200290uint32_t stm32mp_get_chip_dev_id(void)
291{
292 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200293
Yann Gautierc7374052019-06-04 18:02:37 +0200294 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200295 INFO("Use default chip ID, debug disabled\n");
296 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200297 }
298
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200299 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;
308 }
309
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100310 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200311 panic();
Yann Gautierc7374052019-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 Gautiera0a6ff62021-05-10 16:05:18 +0200317 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200318
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200319 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200320}
321
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200322static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200323{
324 uint32_t package;
325
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100326 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200327 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200328 }
329
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200330 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200331 PACKAGE_OTP_PKG_SHIFT;
332
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200333 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200334}
335
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200336void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200337{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200338 char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200339
340 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200341 switch (get_part_number()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200342 case STM32MP157C_PART_NB:
343 cpu_s = "157C";
344 break;
345 case STM32MP157A_PART_NB:
346 cpu_s = "157A";
347 break;
348 case STM32MP153C_PART_NB:
349 cpu_s = "153C";
350 break;
351 case STM32MP153A_PART_NB:
352 cpu_s = "153A";
353 break;
354 case STM32MP151C_PART_NB:
355 cpu_s = "151C";
356 break;
357 case STM32MP151A_PART_NB:
358 cpu_s = "151A";
359 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200360 case STM32MP157F_PART_NB:
361 cpu_s = "157F";
362 break;
363 case STM32MP157D_PART_NB:
364 cpu_s = "157D";
365 break;
366 case STM32MP153F_PART_NB:
367 cpu_s = "153F";
368 break;
369 case STM32MP153D_PART_NB:
370 cpu_s = "153D";
371 break;
372 case STM32MP151F_PART_NB:
373 cpu_s = "151F";
374 break;
375 case STM32MP151D_PART_NB:
376 cpu_s = "151D";
377 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200378 default:
379 cpu_s = "????";
380 break;
381 }
382
383 /* Package */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200384 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200385 case PKG_AA_LFBGA448:
386 pkg = "AA";
387 break;
388 case PKG_AB_LFBGA354:
389 pkg = "AB";
390 break;
391 case PKG_AC_TFBGA361:
392 pkg = "AC";
393 break;
394 case PKG_AD_TFBGA257:
395 pkg = "AD";
396 break;
397 default:
398 pkg = "??";
399 break;
400 }
401
402 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200403 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200404 case STM32MP1_REV_B:
405 cpu_r = "B";
406 break;
Lionel Debieve2d64b532019-06-25 10:40:37 +0200407 case STM32MP1_REV_Z:
408 cpu_r = "Z";
409 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200410 default:
411 cpu_r = "?";
412 break;
413 }
414
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200415 snprintf(name, STM32_SOC_NAME_SIZE,
416 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
417}
418
419void stm32mp_print_cpuinfo(void)
420{
421 char name[STM32_SOC_NAME_SIZE];
422
423 stm32mp_get_soc_name(name);
424 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200425}
426
Yann Gautier35dc0772019-05-13 18:34:48 +0200427void stm32mp_print_boardinfo(void)
428{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100429 uint32_t board_id = 0;
Yann Gautier35dc0772019-05-13 18:34:48 +0200430
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100431 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier35dc0772019-05-13 18:34:48 +0200432 return;
433 }
434
Yann Gautier35dc0772019-05-13 18:34:48 +0200435 if (board_id != 0U) {
436 char rev[2];
437
438 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
439 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200440 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200441 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100442 BOARD_ID2VARCPN(board_id),
443 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200444 rev,
445 BOARD_ID2BOM(board_id));
446 }
447}
448
Yann Gautieraf19ff92019-06-04 18:23:10 +0200449/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
450bool stm32mp_is_single_core(void)
451{
Yann Gautier6bd30e22020-02-06 15:34:16 +0100452#if STM32MP13
453 return true;
454#endif
455#if STM32MP15
Yann Gautier2f3b5602021-10-19 13:31:06 +0200456 bool single_core = false;
457
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200458 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200459 case STM32MP151A_PART_NB:
460 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200461 case STM32MP151D_PART_NB:
462 case STM32MP151F_PART_NB:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200463 single_core = true;
464 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200465 default:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200466 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200467 }
Yann Gautier2f3b5602021-10-19 13:31:06 +0200468
469 return single_core;
Yann Gautier6bd30e22020-02-06 15:34:16 +0100470#endif
Yann Gautieraf19ff92019-06-04 18:23:10 +0200471}
472
Lionel Debieve0e73d732019-09-16 12:17:09 +0200473/* Return true when device is in closed state */
474bool stm32mp_is_closed_device(void)
475{
476 uint32_t value;
477
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100478 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debieve0e73d732019-09-16 12:17:09 +0200479 return true;
480 }
481
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100482 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Lionel Debieve0e73d732019-09-16 12:17:09 +0200483}
484
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100485/* Return true when device supports secure boot */
486bool stm32mp_is_auth_supported(void)
487{
488 bool supported = false;
489
490 switch (get_part_number()) {
491 case STM32MP151C_PART_NB:
492 case STM32MP151F_PART_NB:
493 case STM32MP153C_PART_NB:
494 case STM32MP153F_PART_NB:
495 case STM32MP157C_PART_NB:
496 case STM32MP157F_PART_NB:
497 supported = true;
498 break;
499 default:
500 break;
501 }
502
503 return supported;
504}
505
Yann Gautier091eab52019-06-04 18:06:34 +0200506uint32_t stm32_iwdg_get_instance(uintptr_t base)
507{
508 switch (base) {
509 case IWDG1_BASE:
510 return IWDG1_INST;
511 case IWDG2_BASE:
512 return IWDG2_INST;
513 default:
514 panic();
515 }
516}
517
518uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
519{
520 uint32_t iwdg_cfg = 0U;
521 uint32_t otp_value;
522
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100523 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200524 panic();
525 }
526
527 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
528 iwdg_cfg |= IWDG_HW_ENABLED;
529 }
530
531 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
532 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
533 }
534
535 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
536 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
537 }
538
539 return iwdg_cfg;
540}
541
542#if defined(IMAGE_BL2)
543uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
544{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100545 uint32_t otp_value;
Yann Gautier091eab52019-06-04 18:06:34 +0200546 uint32_t otp;
547 uint32_t result;
548
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100549 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
550 panic();
551 }
552
553 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200554 panic();
555 }
556
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100557 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
558 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200559 }
560
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100561 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
562 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200563 }
564
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100565 result = bsec_write_otp(otp_value, otp);
Yann Gautier091eab52019-06-04 18:06:34 +0200566 if (result != BSEC_OK) {
567 return result;
568 }
569
570 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100571 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
572 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier091eab52019-06-04 18:06:34 +0200573 return BSEC_LOCK_FAIL;
574 }
575
576 return BSEC_OK;
577}
578#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100579
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200580#if STM32MP_USE_STM32IMAGE
Yann Gautier8f268c82020-02-26 13:39:44 +0100581/* Get the non-secure DDR size */
582uint32_t stm32mp_get_ddr_ns_size(void)
583{
584 static uint32_t ddr_ns_size;
585 uint32_t ddr_size;
586
587 if (ddr_ns_size != 0U) {
588 return ddr_ns_size;
589 }
590
591 ddr_size = dt_get_ddr_size();
592 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
593 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
594 panic();
595 }
596
597 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
598
599 return ddr_ns_size;
600}
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200601#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier6eef5252021-12-10 17:04:40 +0100602
603void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
604{
Nicolas Toromanoffbb82b1b2022-02-09 12:26:31 +0100605 uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautier6eef5252021-12-10 17:04:40 +0100606
Yann Gautiera205a5c2021-08-30 15:06:54 +0200607 clk_enable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100608
609 mmio_clrsetbits_32(bkpr_itf_idx,
610 TAMP_BOOT_MODE_ITF_MASK,
611 ((interface << 4) | (instance & 0xFU)) <<
612 TAMP_BOOT_MODE_ITF_SHIFT);
613
Yann Gautiera205a5c2021-08-30 15:06:54 +0200614 clk_disable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100615}
Yann Gautieraaee0612020-12-16 12:04:06 +0100616
617void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
618{
619 static uint32_t itf;
620
621 if (itf == 0U) {
Nicolas Toromanoffbb82b1b2022-02-09 12:26:31 +0100622 uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautieraaee0612020-12-16 12:04:06 +0100623
Yann Gautiera205a5c2021-08-30 15:06:54 +0200624 clk_enable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100625
626 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
627 TAMP_BOOT_MODE_ITF_SHIFT;
628
Yann Gautiera205a5c2021-08-30 15:06:54 +0200629 clk_disable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100630 }
631
632 *interface = itf >> 4;
633 *instance = itf & 0xFU;
634}
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530635
636#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
637void stm32mp1_fwu_set_boot_idx(void)
638{
639 clk_enable(RTCAPB);
640 mmio_write_32(tamp_bkpr(TAMP_BOOT_COUNTER_REG_ID),
641 plat_fwu_get_boot_idx());
642 clk_disable(RTCAPB);
643}
644#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */