blob: d6ad325590c675be9191fe0ed16d3b7916cab040 [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
Yann Gautier9bbd26a2022-03-28 17:49:38 +020049/*
50 * Backup register to store fwu update information.
51 * It should be writeable only by secure world, but also readable by non secure
52 * (so it should be in Zone 2).
53 */
54#define TAMP_BOOT_FWU_INFO_REG_ID U(10)
55#define TAMP_BOOT_FWU_INFO_IDX_MSK U(0xF)
56#define TAMP_BOOT_FWU_INFO_IDX_OFF U(0)
57#define TAMP_BOOT_FWU_INFO_CNT_MSK U(0xF0)
58#define TAMP_BOOT_FWU_INFO_CNT_OFF U(4)
Sughosh Ganu03e2f802021-12-01 15:56:27 +053059
Etienne Carriere72369b12019-12-08 08:17:56 +010060#if defined(IMAGE_BL2)
61#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010062 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010063 MT_MEMORY | \
64 MT_RW | \
65 MT_SECURE | \
66 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-12-08 08:17:56 +010067#elif defined(IMAGE_BL32)
68#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
69 STM32MP_SEC_SYSRAM_SIZE, \
70 MT_MEMORY | \
71 MT_RW | \
72 MT_SECURE | \
73 MT_EXECUTE_NEVER)
Yann Gautieree8f5422019-02-14 11:13:25 +010074
Etienne Carriere72369b12019-12-08 08:17:56 +010075/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
76#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
77 STM32MP_NS_SYSRAM_SIZE, \
78 MT_DEVICE | \
79 MT_RW | \
80 MT_NS | \
81 MT_EXECUTE_NEVER)
82#endif
83
Yann Gautier84d994b2020-04-14 18:08:50 +020084#if STM32MP13
85#define MAP_SRAM_ALL MAP_REGION_FLAT(SRAMS_BASE, \
86 SRAMS_SIZE_2MB_ALIGNED, \
87 MT_MEMORY | \
88 MT_RW | \
89 MT_SECURE | \
90 MT_EXECUTE_NEVER)
91#endif
92
Yann Gautieree8f5422019-02-14 11:13:25 +010093#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
94 STM32MP1_DEVICE1_SIZE, \
95 MT_DEVICE | \
96 MT_RW | \
97 MT_SECURE | \
98 MT_EXECUTE_NEVER)
99
100#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
101 STM32MP1_DEVICE2_SIZE, \
102 MT_DEVICE | \
103 MT_RW | \
104 MT_SECURE | \
105 MT_EXECUTE_NEVER)
106
107#if defined(IMAGE_BL2)
108static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100109 MAP_SEC_SYSRAM,
Yann Gautier84d994b2020-04-14 18:08:50 +0200110#if STM32MP13
111 MAP_SRAM_ALL,
112#endif
Yann Gautieree8f5422019-02-14 11:13:25 +0100113 MAP_DEVICE1,
Yann Gautier352d8632020-09-17 11:38:09 +0200114#if STM32MP_RAW_NAND
Yann Gautieree8f5422019-02-14 11:13:25 +0100115 MAP_DEVICE2,
Yann Gautier352d8632020-09-17 11:38:09 +0200116#endif
Yann Gautieree8f5422019-02-14 11:13:25 +0100117 {0}
118};
119#endif
120#if defined(IMAGE_BL32)
121static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100122 MAP_SEC_SYSRAM,
123 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +0100124 MAP_DEVICE1,
125 MAP_DEVICE2,
126 {0}
127};
128#endif
129
130void configure_mmu(void)
131{
132 mmap_add(stm32mp1_mmap);
133 init_xlat_tables();
134
135 enable_mmu_svc_mon(0);
136}
Yann Gautiere3bf9132019-05-07 18:52:17 +0200137
Etienne Carriere66b04522019-12-02 10:05:02 +0100138uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
139{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100140#if STM32MP13
141 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
142#endif
143#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100144 if (bank == GPIO_BANK_Z) {
145 return GPIOZ_BASE;
146 }
147
148 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100149#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100150
151 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
152}
153
154uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
155{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100156#if STM32MP13
157 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
158#endif
159#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100160 if (bank == GPIO_BANK_Z) {
161 return 0;
162 }
163
164 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100165#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100166
167 return bank * GPIO_BANK_OFFSET;
168}
169
Yann Gautier2b79c372021-06-11 10:54:56 +0200170bool stm32_gpio_is_secure_at_reset(unsigned int bank)
171{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100172#if STM32MP13
173 return true;
174#endif
175#if STM32MP15
Yann Gautier2b79c372021-06-11 10:54:56 +0200176 if (bank == GPIO_BANK_Z) {
177 return true;
178 }
179
180 return false;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100181#endif
Yann Gautier2b79c372021-06-11 10:54:56 +0200182}
183
Yann Gautiere3bf9132019-05-07 18:52:17 +0200184unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
185{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100186#if STM32MP13
187 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
188#endif
189#if STM32MP15
Yann Gautiere3bf9132019-05-07 18:52:17 +0200190 if (bank == GPIO_BANK_Z) {
191 return GPIOZ;
192 }
193
194 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100195#endif
Yann Gautiere3bf9132019-05-07 18:52:17 +0200196
197 return GPIOA + (bank - GPIO_BANK_A);
198}
Yann Gautier091eab52019-06-04 18:06:34 +0200199
Etienne Carriered81dadf2020-04-25 11:14:45 +0200200int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
201{
Yann Gautiere78db3b2022-03-11 14:18:13 +0100202 const char *node_compatible = NULL;
203
Etienne Carriered81dadf2020-04-25 11:14:45 +0200204 switch (bank) {
205 case GPIO_BANK_A:
206 case GPIO_BANK_B:
207 case GPIO_BANK_C:
208 case GPIO_BANK_D:
209 case GPIO_BANK_E:
210 case GPIO_BANK_F:
211 case GPIO_BANK_G:
212 case GPIO_BANK_H:
213 case GPIO_BANK_I:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100214#if STM32MP13
215 node_compatible = "st,stm32mp135-pinctrl";
216 break;
217#endif
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100218#if STM32MP15
Etienne Carriered81dadf2020-04-25 11:14:45 +0200219 case GPIO_BANK_J:
220 case GPIO_BANK_K:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100221 node_compatible = "st,stm32mp157-pinctrl";
222 break;
Etienne Carriered81dadf2020-04-25 11:14:45 +0200223 case GPIO_BANK_Z:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100224 node_compatible = "st,stm32mp157-z-pinctrl";
225 break;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100226#endif
Etienne Carriered81dadf2020-04-25 11:14:45 +0200227 default:
228 panic();
229 }
Yann Gautiere78db3b2022-03-11 14:18:13 +0100230
231 return fdt_node_offset_by_compatible(fdt, -1, node_compatible);
Etienne Carriered81dadf2020-04-25 11:14:45 +0200232}
233
Yann Gautier3d8497c2021-10-18 16:06:22 +0200234#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200235/*
236 * UART Management
237 */
238static const uintptr_t stm32mp1_uart_addresses[8] = {
239 USART1_BASE,
240 USART2_BASE,
241 USART3_BASE,
242 UART4_BASE,
243 UART5_BASE,
244 USART6_BASE,
245 UART7_BASE,
246 UART8_BASE,
247};
248
249uintptr_t get_uart_address(uint32_t instance_nb)
250{
251 if ((instance_nb == 0U) ||
252 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
253 return 0U;
254 }
255
256 return stm32mp1_uart_addresses[instance_nb - 1U];
257}
258#endif
259
Yann Gautiercd16df32021-06-04 14:04:05 +0200260#if STM32MP_USB_PROGRAMMER
261struct gpio_bank_pin_list {
262 uint32_t bank;
263 uint32_t pin;
264};
265
266static const struct gpio_bank_pin_list gpio_list[] = {
267 { /* USART2_RX: GPIOA3 */
268 .bank = 0U,
269 .pin = 3U,
270 },
271 { /* USART3_RX: GPIOB12 */
272 .bank = 1U,
273 .pin = 12U,
274 },
275 { /* UART4_RX: GPIOB2 */
276 .bank = 1U,
277 .pin = 2U,
278 },
279 { /* UART5_RX: GPIOB4 */
280 .bank = 1U,
281 .pin = 5U,
282 },
283 { /* USART6_RX: GPIOC7 */
284 .bank = 2U,
285 .pin = 7U,
286 },
287 { /* UART7_RX: GPIOF6 */
288 .bank = 5U,
289 .pin = 6U,
290 },
291 { /* UART8_RX: GPIOE0 */
292 .bank = 4U,
293 .pin = 0U,
294 },
295};
296
297void stm32mp1_deconfigure_uart_pins(void)
298{
299 size_t i;
300
301 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
302 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
303 }
304}
305#endif
306
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200307uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200308{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200309#if STM32MP13
310 return stm32mp1_syscfg_get_chip_version();
311#endif
312#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200313 uint32_t version = 0U;
314
315 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
316 INFO("Cannot get CPU version, debug disabled\n");
317 return 0U;
318 }
319
320 return version;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200321#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200322}
Yann Gautierc7374052019-06-04 18:02:37 +0200323
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200324uint32_t stm32mp_get_chip_dev_id(void)
325{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200326#if STM32MP13
327 return stm32mp1_syscfg_get_chip_dev_id();
328#endif
329#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200330 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200331
Yann Gautierc7374052019-06-04 18:02:37 +0200332 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200333 INFO("Use default chip ID, debug disabled\n");
334 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200335 }
336
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200337 return dev_id;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200338#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200339}
340
341static uint32_t get_part_number(void)
342{
343 static uint32_t part_number;
344
345 if (part_number != 0U) {
346 return part_number;
347 }
348
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100349 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200350 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200351 }
352
353 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
354 PART_NUMBER_OTP_PART_SHIFT;
355
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200356 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200357
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200358 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200359}
360
Yann Gautier16188f32020-02-12 15:38:34 +0100361#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200362static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200363{
364 uint32_t package;
365
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100366 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200367 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200368 }
369
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200370 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200371 PACKAGE_OTP_PKG_SHIFT;
372
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200373 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200374}
Yann Gautier16188f32020-02-12 15:38:34 +0100375#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200376
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200377void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200378{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200379 char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200380
381 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200382 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100383#if STM32MP13
384 case STM32MP135F_PART_NB:
385 cpu_s = "135F";
386 break;
387 case STM32MP135D_PART_NB:
388 cpu_s = "135D";
389 break;
390 case STM32MP135C_PART_NB:
391 cpu_s = "135C";
392 break;
393 case STM32MP135A_PART_NB:
394 cpu_s = "135A";
395 break;
396 case STM32MP133F_PART_NB:
397 cpu_s = "133F";
398 break;
399 case STM32MP133D_PART_NB:
400 cpu_s = "133D";
401 break;
402 case STM32MP133C_PART_NB:
403 cpu_s = "133C";
404 break;
405 case STM32MP133A_PART_NB:
406 cpu_s = "133A";
407 break;
408 case STM32MP131F_PART_NB:
409 cpu_s = "131F";
410 break;
411 case STM32MP131D_PART_NB:
412 cpu_s = "131D";
413 break;
414 case STM32MP131C_PART_NB:
415 cpu_s = "131C";
416 break;
417 case STM32MP131A_PART_NB:
418 cpu_s = "131A";
419 break;
420#endif
421#if STM32MP15
Yann Gautierc7374052019-06-04 18:02:37 +0200422 case STM32MP157C_PART_NB:
423 cpu_s = "157C";
424 break;
425 case STM32MP157A_PART_NB:
426 cpu_s = "157A";
427 break;
428 case STM32MP153C_PART_NB:
429 cpu_s = "153C";
430 break;
431 case STM32MP153A_PART_NB:
432 cpu_s = "153A";
433 break;
434 case STM32MP151C_PART_NB:
435 cpu_s = "151C";
436 break;
437 case STM32MP151A_PART_NB:
438 cpu_s = "151A";
439 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200440 case STM32MP157F_PART_NB:
441 cpu_s = "157F";
442 break;
443 case STM32MP157D_PART_NB:
444 cpu_s = "157D";
445 break;
446 case STM32MP153F_PART_NB:
447 cpu_s = "153F";
448 break;
449 case STM32MP153D_PART_NB:
450 cpu_s = "153D";
451 break;
452 case STM32MP151F_PART_NB:
453 cpu_s = "151F";
454 break;
455 case STM32MP151D_PART_NB:
456 cpu_s = "151D";
457 break;
Yann Gautier16188f32020-02-12 15:38:34 +0100458#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200459 default:
460 cpu_s = "????";
461 break;
462 }
463
464 /* Package */
Yann Gautier16188f32020-02-12 15:38:34 +0100465#if STM32MP13
466 /* On STM32MP13, package is not present in OTP */
467 pkg = "";
468#endif
469#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200470 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200471 case PKG_AA_LFBGA448:
472 pkg = "AA";
473 break;
474 case PKG_AB_LFBGA354:
475 pkg = "AB";
476 break;
477 case PKG_AC_TFBGA361:
478 pkg = "AC";
479 break;
480 case PKG_AD_TFBGA257:
481 pkg = "AD";
482 break;
483 default:
484 pkg = "??";
485 break;
486 }
Yann Gautier16188f32020-02-12 15:38:34 +0100487#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200488
489 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200490 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200491 case STM32MP1_REV_B:
492 cpu_r = "B";
493 break;
Lionel Debieve2d64b532019-06-25 10:40:37 +0200494 case STM32MP1_REV_Z:
495 cpu_r = "Z";
496 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200497 default:
498 cpu_r = "?";
499 break;
500 }
501
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200502 snprintf(name, STM32_SOC_NAME_SIZE,
503 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
504}
505
506void stm32mp_print_cpuinfo(void)
507{
508 char name[STM32_SOC_NAME_SIZE];
509
510 stm32mp_get_soc_name(name);
511 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200512}
513
Yann Gautier35dc0772019-05-13 18:34:48 +0200514void stm32mp_print_boardinfo(void)
515{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100516 uint32_t board_id = 0;
Yann Gautier35dc0772019-05-13 18:34:48 +0200517
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100518 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier35dc0772019-05-13 18:34:48 +0200519 return;
520 }
521
Yann Gautier35dc0772019-05-13 18:34:48 +0200522 if (board_id != 0U) {
523 char rev[2];
524
525 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
526 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200527 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200528 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100529 BOARD_ID2VARCPN(board_id),
530 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200531 rev,
532 BOARD_ID2BOM(board_id));
533 }
534}
535
Yann Gautieraf19ff92019-06-04 18:23:10 +0200536/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
537bool stm32mp_is_single_core(void)
538{
Yann Gautier6bd30e22020-02-06 15:34:16 +0100539#if STM32MP13
540 return true;
541#endif
542#if STM32MP15
Yann Gautier2f3b5602021-10-19 13:31:06 +0200543 bool single_core = false;
544
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200545 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200546 case STM32MP151A_PART_NB:
547 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200548 case STM32MP151D_PART_NB:
549 case STM32MP151F_PART_NB:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200550 single_core = true;
551 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200552 default:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200553 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200554 }
Yann Gautier2f3b5602021-10-19 13:31:06 +0200555
556 return single_core;
Yann Gautier6bd30e22020-02-06 15:34:16 +0100557#endif
Yann Gautieraf19ff92019-06-04 18:23:10 +0200558}
559
Lionel Debieve0e73d732019-09-16 12:17:09 +0200560/* Return true when device is in closed state */
561bool stm32mp_is_closed_device(void)
562{
563 uint32_t value;
564
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100565 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debieve0e73d732019-09-16 12:17:09 +0200566 return true;
567 }
568
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100569#if STM32MP13
570 value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT;
571
572 switch (value) {
573 case CFG0_OPEN_DEVICE:
574 return false;
575 case CFG0_CLOSED_DEVICE:
576 case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
577 case CFG0_CLOSED_DEVICE_NO_JTAG:
578 return true;
579 default:
580 panic();
581 }
582#endif
583#if STM32MP15
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100584 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100585#endif
Lionel Debieve0e73d732019-09-16 12:17:09 +0200586}
587
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100588/* Return true when device supports secure boot */
589bool stm32mp_is_auth_supported(void)
590{
591 bool supported = false;
592
593 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100594#if STM32MP13
595 case STM32MP131C_PART_NB:
596 case STM32MP131F_PART_NB:
597 case STM32MP133C_PART_NB:
598 case STM32MP133F_PART_NB:
599 case STM32MP135C_PART_NB:
600 case STM32MP135F_PART_NB:
601#endif
602#if STM32MP15
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100603 case STM32MP151C_PART_NB:
604 case STM32MP151F_PART_NB:
605 case STM32MP153C_PART_NB:
606 case STM32MP153F_PART_NB:
607 case STM32MP157C_PART_NB:
608 case STM32MP157F_PART_NB:
Yann Gautier16188f32020-02-12 15:38:34 +0100609#endif
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100610 supported = true;
611 break;
612 default:
613 break;
614 }
615
616 return supported;
617}
618
Yann Gautier091eab52019-06-04 18:06:34 +0200619uint32_t stm32_iwdg_get_instance(uintptr_t base)
620{
621 switch (base) {
622 case IWDG1_BASE:
623 return IWDG1_INST;
624 case IWDG2_BASE:
625 return IWDG2_INST;
626 default:
627 panic();
628 }
629}
630
631uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
632{
633 uint32_t iwdg_cfg = 0U;
634 uint32_t otp_value;
635
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100636 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200637 panic();
638 }
639
640 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
641 iwdg_cfg |= IWDG_HW_ENABLED;
642 }
643
644 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
645 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
646 }
647
648 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
649 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
650 }
651
652 return iwdg_cfg;
653}
654
655#if defined(IMAGE_BL2)
656uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
657{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100658 uint32_t otp_value;
Yann Gautier091eab52019-06-04 18:06:34 +0200659 uint32_t otp;
660 uint32_t result;
661
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100662 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
663 panic();
664 }
665
666 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200667 panic();
668 }
669
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100670 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
671 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200672 }
673
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100674 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
675 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200676 }
677
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100678 result = bsec_write_otp(otp_value, otp);
Yann Gautier091eab52019-06-04 18:06:34 +0200679 if (result != BSEC_OK) {
680 return result;
681 }
682
683 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100684 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
685 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier091eab52019-06-04 18:06:34 +0200686 return BSEC_LOCK_FAIL;
687 }
688
689 return BSEC_OK;
690}
691#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100692
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200693#if STM32MP_USE_STM32IMAGE
Yann Gautier8f268c82020-02-26 13:39:44 +0100694/* Get the non-secure DDR size */
695uint32_t stm32mp_get_ddr_ns_size(void)
696{
697 static uint32_t ddr_ns_size;
698 uint32_t ddr_size;
699
700 if (ddr_ns_size != 0U) {
701 return ddr_ns_size;
702 }
703
704 ddr_size = dt_get_ddr_size();
705 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
706 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
707 panic();
708 }
709
710 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
711
712 return ddr_ns_size;
713}
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200714#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier6eef5252021-12-10 17:04:40 +0100715
716void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
717{
Nicolas Toromanoffbb82b1b2022-02-09 12:26:31 +0100718 uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautier6eef5252021-12-10 17:04:40 +0100719
Yann Gautiera205a5c2021-08-30 15:06:54 +0200720 clk_enable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100721
722 mmio_clrsetbits_32(bkpr_itf_idx,
723 TAMP_BOOT_MODE_ITF_MASK,
724 ((interface << 4) | (instance & 0xFU)) <<
725 TAMP_BOOT_MODE_ITF_SHIFT);
726
Yann Gautiera205a5c2021-08-30 15:06:54 +0200727 clk_disable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100728}
Yann Gautieraaee0612020-12-16 12:04:06 +0100729
730void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
731{
732 static uint32_t itf;
733
734 if (itf == 0U) {
Nicolas Toromanoffbb82b1b2022-02-09 12:26:31 +0100735 uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautieraaee0612020-12-16 12:04:06 +0100736
Yann Gautiera205a5c2021-08-30 15:06:54 +0200737 clk_enable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100738
739 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
740 TAMP_BOOT_MODE_ITF_SHIFT;
741
Yann Gautiera205a5c2021-08-30 15:06:54 +0200742 clk_disable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100743 }
744
745 *interface = itf >> 4;
746 *instance = itf & 0xFU;
747}
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530748
749#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
750void stm32mp1_fwu_set_boot_idx(void)
751{
752 clk_enable(RTCAPB);
Yann Gautier9bbd26a2022-03-28 17:49:38 +0200753 mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
754 TAMP_BOOT_FWU_INFO_IDX_MSK,
755 (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
756 TAMP_BOOT_FWU_INFO_IDX_MSK);
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530757 clk_disable(RTCAPB);
758}
Nicolas Toromanoff5a937cd2022-02-07 10:12:04 +0100759
760uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
761{
762 uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
763 uint32_t try_cnt;
764
765 clk_enable(RTCAPB);
766 try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
767 TAMP_BOOT_FWU_INFO_CNT_OFF;
768
769 assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
770
771 if (try_cnt != 0U) {
772 mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
773 (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
774 }
775 clk_disable(RTCAPB);
776
777 return try_cnt;
778}
779
780void stm32_set_max_fwu_trial_boot_cnt(void)
781{
782 uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
783
784 clk_enable(RTCAPB);
785 mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
786 (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
787 TAMP_BOOT_FWU_INFO_CNT_MSK);
788 clk_disable(RTCAPB);
789}
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530790#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */