blob: 7119b6477c7650f31603712ba394a9ddfdae7bc2 [file] [log] [blame]
Yann Gautieree8f5422019-02-14 11:13:25 +01001/*
Yann Gautier8402c292022-06-29 17:03:36 +02002 * Copyright (c) 2015-2023, 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
Yann Gautier9bbd26a2022-03-28 17:49:38 +020047/*
48 * Backup register to store fwu update information.
49 * It should be writeable only by secure world, but also readable by non secure
50 * (so it should be in Zone 2).
51 */
52#define TAMP_BOOT_FWU_INFO_REG_ID U(10)
Igor Opaniukf07e8f32022-06-23 21:19:26 +030053#define TAMP_BOOT_FWU_INFO_IDX_MSK GENMASK(3, 0)
Yann Gautier9bbd26a2022-03-28 17:49:38 +020054#define TAMP_BOOT_FWU_INFO_IDX_OFF U(0)
Igor Opaniukf07e8f32022-06-23 21:19:26 +030055#define TAMP_BOOT_FWU_INFO_CNT_MSK GENMASK(7, 4)
Yann Gautier9bbd26a2022-03-28 17:49:38 +020056#define TAMP_BOOT_FWU_INFO_CNT_OFF U(4)
Sughosh Ganu03e2f802021-12-01 15:56:27 +053057
Etienne Carriere72369b12019-12-08 08:17:56 +010058#if defined(IMAGE_BL2)
59#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010060 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010061 MT_MEMORY | \
62 MT_RW | \
63 MT_SECURE | \
64 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-12-08 08:17:56 +010065#elif defined(IMAGE_BL32)
66#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
67 STM32MP_SEC_SYSRAM_SIZE, \
68 MT_MEMORY | \
69 MT_RW | \
70 MT_SECURE | \
71 MT_EXECUTE_NEVER)
Yann Gautieree8f5422019-02-14 11:13:25 +010072
Etienne Carriere72369b12019-12-08 08:17:56 +010073/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
74#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
75 STM32MP_NS_SYSRAM_SIZE, \
76 MT_DEVICE | \
77 MT_RW | \
78 MT_NS | \
79 MT_EXECUTE_NEVER)
80#endif
81
Yann Gautier84d994b2020-04-14 18:08:50 +020082#if STM32MP13
83#define MAP_SRAM_ALL MAP_REGION_FLAT(SRAMS_BASE, \
84 SRAMS_SIZE_2MB_ALIGNED, \
85 MT_MEMORY | \
86 MT_RW | \
87 MT_SECURE | \
88 MT_EXECUTE_NEVER)
89#endif
90
Yann Gautieree8f5422019-02-14 11:13:25 +010091#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
92 STM32MP1_DEVICE1_SIZE, \
93 MT_DEVICE | \
94 MT_RW | \
95 MT_SECURE | \
96 MT_EXECUTE_NEVER)
97
98#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
99 STM32MP1_DEVICE2_SIZE, \
100 MT_DEVICE | \
101 MT_RW | \
102 MT_SECURE | \
103 MT_EXECUTE_NEVER)
104
105#if defined(IMAGE_BL2)
106static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100107 MAP_SEC_SYSRAM,
Yann Gautier84d994b2020-04-14 18:08:50 +0200108#if STM32MP13
109 MAP_SRAM_ALL,
110#endif
Yann Gautieree8f5422019-02-14 11:13:25 +0100111 MAP_DEVICE1,
Yann Gautier352d8632020-09-17 11:38:09 +0200112#if STM32MP_RAW_NAND
Yann Gautieree8f5422019-02-14 11:13:25 +0100113 MAP_DEVICE2,
Yann Gautier352d8632020-09-17 11:38:09 +0200114#endif
Yann Gautieree8f5422019-02-14 11:13:25 +0100115 {0}
116};
117#endif
118#if defined(IMAGE_BL32)
119static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100120 MAP_SEC_SYSRAM,
121 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +0100122 MAP_DEVICE1,
123 MAP_DEVICE2,
124 {0}
125};
126#endif
127
128void configure_mmu(void)
129{
130 mmap_add(stm32mp1_mmap);
131 init_xlat_tables();
132
133 enable_mmu_svc_mon(0);
134}
Yann Gautiere3bf9132019-05-07 18:52:17 +0200135
Etienne Carriere66b04522019-12-02 10:05:02 +0100136uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
137{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100138#if STM32MP13
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100139 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100140#endif
141#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100142 if (bank == GPIO_BANK_Z) {
143 return GPIOZ_BASE;
144 }
145
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100146 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100147#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100148
149 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
150}
151
152uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
153{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100154#if STM32MP13
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100155 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100156#endif
157#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100158 if (bank == GPIO_BANK_Z) {
159 return 0;
160 }
161
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100162 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100163#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100164
165 return bank * GPIO_BANK_OFFSET;
166}
167
Yann Gautier2b79c372021-06-11 10:54:56 +0200168bool stm32_gpio_is_secure_at_reset(unsigned int bank)
169{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100170#if STM32MP13
171 return true;
172#endif
173#if STM32MP15
Yann Gautier2b79c372021-06-11 10:54:56 +0200174 if (bank == GPIO_BANK_Z) {
175 return true;
176 }
177
178 return false;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100179#endif
Yann Gautier2b79c372021-06-11 10:54:56 +0200180}
181
Yann Gautiere3bf9132019-05-07 18:52:17 +0200182unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
183{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100184#if STM32MP13
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100185 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_I));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100186#endif
187#if STM32MP15
Yann Gautiere3bf9132019-05-07 18:52:17 +0200188 if (bank == GPIO_BANK_Z) {
189 return GPIOZ;
190 }
191
Yann Gautier88b8f2b2022-11-18 15:03:22 +0100192 assert((GPIO_BANK_A == 0) && (bank <= GPIO_BANK_K));
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100193#endif
Yann Gautiere3bf9132019-05-07 18:52:17 +0200194
195 return GPIOA + (bank - GPIO_BANK_A);
196}
Yann Gautier091eab52019-06-04 18:06:34 +0200197
Etienne Carriered81dadf2020-04-25 11:14:45 +0200198int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
199{
Yann Gautiere78db3b2022-03-11 14:18:13 +0100200 const char *node_compatible = NULL;
201
Etienne Carriered81dadf2020-04-25 11:14:45 +0200202 switch (bank) {
203 case GPIO_BANK_A:
204 case GPIO_BANK_B:
205 case GPIO_BANK_C:
206 case GPIO_BANK_D:
207 case GPIO_BANK_E:
208 case GPIO_BANK_F:
209 case GPIO_BANK_G:
210 case GPIO_BANK_H:
211 case GPIO_BANK_I:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100212#if STM32MP13
213 node_compatible = "st,stm32mp135-pinctrl";
214 break;
215#endif
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100216#if STM32MP15
Etienne Carriered81dadf2020-04-25 11:14:45 +0200217 case GPIO_BANK_J:
218 case GPIO_BANK_K:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100219 node_compatible = "st,stm32mp157-pinctrl";
220 break;
Etienne Carriered81dadf2020-04-25 11:14:45 +0200221 case GPIO_BANK_Z:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100222 node_compatible = "st,stm32mp157-z-pinctrl";
223 break;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100224#endif
Etienne Carriered81dadf2020-04-25 11:14:45 +0200225 default:
226 panic();
227 }
Yann Gautiere78db3b2022-03-11 14:18:13 +0100228
229 return fdt_node_offset_by_compatible(fdt, -1, node_compatible);
Etienne Carriered81dadf2020-04-25 11:14:45 +0200230}
231
Yann Gautier3d8497c2021-10-18 16:06:22 +0200232#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200233/*
234 * UART Management
235 */
236static const uintptr_t stm32mp1_uart_addresses[8] = {
237 USART1_BASE,
238 USART2_BASE,
239 USART3_BASE,
240 UART4_BASE,
241 UART5_BASE,
242 USART6_BASE,
243 UART7_BASE,
244 UART8_BASE,
245};
246
247uintptr_t get_uart_address(uint32_t instance_nb)
248{
249 if ((instance_nb == 0U) ||
250 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
251 return 0U;
252 }
253
254 return stm32mp1_uart_addresses[instance_nb - 1U];
255}
256#endif
257
Yann Gautiercd16df32021-06-04 14:04:05 +0200258#if STM32MP_USB_PROGRAMMER
259struct gpio_bank_pin_list {
260 uint32_t bank;
261 uint32_t pin;
262};
263
264static const struct gpio_bank_pin_list gpio_list[] = {
265 { /* USART2_RX: GPIOA3 */
266 .bank = 0U,
267 .pin = 3U,
268 },
269 { /* USART3_RX: GPIOB12 */
270 .bank = 1U,
271 .pin = 12U,
272 },
273 { /* UART4_RX: GPIOB2 */
274 .bank = 1U,
275 .pin = 2U,
276 },
277 { /* UART5_RX: GPIOB4 */
278 .bank = 1U,
279 .pin = 5U,
280 },
281 { /* USART6_RX: GPIOC7 */
282 .bank = 2U,
283 .pin = 7U,
284 },
285 { /* UART7_RX: GPIOF6 */
286 .bank = 5U,
287 .pin = 6U,
288 },
289 { /* UART8_RX: GPIOE0 */
290 .bank = 4U,
291 .pin = 0U,
292 },
293};
294
295void stm32mp1_deconfigure_uart_pins(void)
296{
297 size_t i;
298
299 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
300 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
301 }
302}
303#endif
304
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200305uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200306{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200307#if STM32MP13
308 return stm32mp1_syscfg_get_chip_version();
309#endif
310#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200311 uint32_t version = 0U;
312
313 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
314 INFO("Cannot get CPU version, debug disabled\n");
315 return 0U;
316 }
317
318 return version;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200319#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200320}
Yann Gautierc7374052019-06-04 18:02:37 +0200321
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200322uint32_t stm32mp_get_chip_dev_id(void)
323{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200324#if STM32MP13
325 return stm32mp1_syscfg_get_chip_dev_id();
326#endif
327#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200328 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200329
Yann Gautierc7374052019-06-04 18:02:37 +0200330 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200331 INFO("Use default chip ID, debug disabled\n");
332 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200333 }
334
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200335 return dev_id;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200336#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200337}
338
339static uint32_t get_part_number(void)
340{
341 static uint32_t part_number;
342
343 if (part_number != 0U) {
344 return part_number;
345 }
346
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100347 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200348 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200349 }
350
351 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
352 PART_NUMBER_OTP_PART_SHIFT;
353
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200354 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200355
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200356 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200357}
358
Yann Gautier16188f32020-02-12 15:38:34 +0100359#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200360static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200361{
362 uint32_t package;
363
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100364 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200365 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200366 }
367
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200368 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200369 PACKAGE_OTP_PKG_SHIFT;
370
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200371 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200372}
Yann Gautier16188f32020-02-12 15:38:34 +0100373#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200374
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200375void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200376{
Yann Gautier4bda43f2022-11-24 19:02:23 +0100377 const char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200378
379 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200380 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100381#if STM32MP13
382 case STM32MP135F_PART_NB:
383 cpu_s = "135F";
384 break;
385 case STM32MP135D_PART_NB:
386 cpu_s = "135D";
387 break;
388 case STM32MP135C_PART_NB:
389 cpu_s = "135C";
390 break;
391 case STM32MP135A_PART_NB:
392 cpu_s = "135A";
393 break;
394 case STM32MP133F_PART_NB:
395 cpu_s = "133F";
396 break;
397 case STM32MP133D_PART_NB:
398 cpu_s = "133D";
399 break;
400 case STM32MP133C_PART_NB:
401 cpu_s = "133C";
402 break;
403 case STM32MP133A_PART_NB:
404 cpu_s = "133A";
405 break;
406 case STM32MP131F_PART_NB:
407 cpu_s = "131F";
408 break;
409 case STM32MP131D_PART_NB:
410 cpu_s = "131D";
411 break;
412 case STM32MP131C_PART_NB:
413 cpu_s = "131C";
414 break;
415 case STM32MP131A_PART_NB:
416 cpu_s = "131A";
417 break;
418#endif
419#if STM32MP15
Yann Gautierc7374052019-06-04 18:02:37 +0200420 case STM32MP157C_PART_NB:
421 cpu_s = "157C";
422 break;
423 case STM32MP157A_PART_NB:
424 cpu_s = "157A";
425 break;
426 case STM32MP153C_PART_NB:
427 cpu_s = "153C";
428 break;
429 case STM32MP153A_PART_NB:
430 cpu_s = "153A";
431 break;
432 case STM32MP151C_PART_NB:
433 cpu_s = "151C";
434 break;
435 case STM32MP151A_PART_NB:
436 cpu_s = "151A";
437 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200438 case STM32MP157F_PART_NB:
439 cpu_s = "157F";
440 break;
441 case STM32MP157D_PART_NB:
442 cpu_s = "157D";
443 break;
444 case STM32MP153F_PART_NB:
445 cpu_s = "153F";
446 break;
447 case STM32MP153D_PART_NB:
448 cpu_s = "153D";
449 break;
450 case STM32MP151F_PART_NB:
451 cpu_s = "151F";
452 break;
453 case STM32MP151D_PART_NB:
454 cpu_s = "151D";
455 break;
Yann Gautier16188f32020-02-12 15:38:34 +0100456#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200457 default:
458 cpu_s = "????";
459 break;
460 }
461
462 /* Package */
Yann Gautier16188f32020-02-12 15:38:34 +0100463#if STM32MP13
464 /* On STM32MP13, package is not present in OTP */
465 pkg = "";
466#endif
467#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200468 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200469 case PKG_AA_LFBGA448:
470 pkg = "AA";
471 break;
472 case PKG_AB_LFBGA354:
473 pkg = "AB";
474 break;
475 case PKG_AC_TFBGA361:
476 pkg = "AC";
477 break;
478 case PKG_AD_TFBGA257:
479 pkg = "AD";
480 break;
481 default:
482 pkg = "??";
483 break;
484 }
Yann Gautier16188f32020-02-12 15:38:34 +0100485#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200486
487 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200488 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200489 case STM32MP1_REV_B:
490 cpu_r = "B";
491 break;
Yann Gautier06cc7912022-05-09 17:01:11 +0200492#if STM32MP13
493 case STM32MP1_REV_Y:
494 cpu_r = "Y";
495 break;
496#endif
Lionel Debieve2d64b532019-06-25 10:40:37 +0200497 case STM32MP1_REV_Z:
498 cpu_r = "Z";
499 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200500 default:
501 cpu_r = "?";
502 break;
503 }
504
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200505 snprintf(name, STM32_SOC_NAME_SIZE,
506 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
507}
508
509void stm32mp_print_cpuinfo(void)
510{
511 char name[STM32_SOC_NAME_SIZE];
512
513 stm32mp_get_soc_name(name);
514 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200515}
516
Yann Gautier35dc0772019-05-13 18:34:48 +0200517void stm32mp_print_boardinfo(void)
518{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100519 uint32_t board_id = 0;
Yann Gautier35dc0772019-05-13 18:34:48 +0200520
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100521 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier35dc0772019-05-13 18:34:48 +0200522 return;
523 }
524
Yann Gautier35dc0772019-05-13 18:34:48 +0200525 if (board_id != 0U) {
526 char rev[2];
527
528 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
529 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200530 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200531 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100532 BOARD_ID2VARCPN(board_id),
533 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200534 rev,
535 BOARD_ID2BOM(board_id));
536 }
537}
538
Yann Gautieraf19ff92019-06-04 18:23:10 +0200539/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
540bool stm32mp_is_single_core(void)
541{
Yann Gautier6bd30e22020-02-06 15:34:16 +0100542#if STM32MP13
543 return true;
544#endif
545#if STM32MP15
Yann Gautier2f3b5602021-10-19 13:31:06 +0200546 bool single_core = false;
547
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200548 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200549 case STM32MP151A_PART_NB:
550 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200551 case STM32MP151D_PART_NB:
552 case STM32MP151F_PART_NB:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200553 single_core = true;
554 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200555 default:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200556 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200557 }
Yann Gautier2f3b5602021-10-19 13:31:06 +0200558
559 return single_core;
Yann Gautier6bd30e22020-02-06 15:34:16 +0100560#endif
Yann Gautieraf19ff92019-06-04 18:23:10 +0200561}
562
Lionel Debieve0e73d732019-09-16 12:17:09 +0200563/* Return true when device is in closed state */
564bool stm32mp_is_closed_device(void)
565{
566 uint32_t value;
567
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100568 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debieve0e73d732019-09-16 12:17:09 +0200569 return true;
570 }
571
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100572#if STM32MP13
573 value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT;
574
575 switch (value) {
576 case CFG0_OPEN_DEVICE:
577 return false;
578 case CFG0_CLOSED_DEVICE:
579 case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
580 case CFG0_CLOSED_DEVICE_NO_JTAG:
581 return true;
582 default:
583 panic();
584 }
585#endif
586#if STM32MP15
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100587 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100588#endif
Lionel Debieve0e73d732019-09-16 12:17:09 +0200589}
590
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100591/* Return true when device supports secure boot */
592bool stm32mp_is_auth_supported(void)
593{
594 bool supported = false;
595
596 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100597#if STM32MP13
598 case STM32MP131C_PART_NB:
599 case STM32MP131F_PART_NB:
600 case STM32MP133C_PART_NB:
601 case STM32MP133F_PART_NB:
602 case STM32MP135C_PART_NB:
603 case STM32MP135F_PART_NB:
604#endif
605#if STM32MP15
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100606 case STM32MP151C_PART_NB:
607 case STM32MP151F_PART_NB:
608 case STM32MP153C_PART_NB:
609 case STM32MP153F_PART_NB:
610 case STM32MP157C_PART_NB:
611 case STM32MP157F_PART_NB:
Yann Gautier16188f32020-02-12 15:38:34 +0100612#endif
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100613 supported = true;
614 break;
615 default:
616 break;
617 }
618
619 return supported;
620}
621
Yann Gautier091eab52019-06-04 18:06:34 +0200622uint32_t stm32_iwdg_get_instance(uintptr_t base)
623{
624 switch (base) {
625 case IWDG1_BASE:
626 return IWDG1_INST;
627 case IWDG2_BASE:
628 return IWDG2_INST;
629 default:
630 panic();
631 }
632}
633
634uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
635{
636 uint32_t iwdg_cfg = 0U;
637 uint32_t otp_value;
638
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100639 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200640 panic();
641 }
642
643 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
644 iwdg_cfg |= IWDG_HW_ENABLED;
645 }
646
647 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
648 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
649 }
650
651 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
652 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
653 }
654
655 return iwdg_cfg;
656}
657
658#if defined(IMAGE_BL2)
659uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
660{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100661 uint32_t otp_value;
Yann Gautier091eab52019-06-04 18:06:34 +0200662 uint32_t otp;
663 uint32_t result;
664
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100665 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
666 panic();
667 }
668
669 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200670 panic();
671 }
672
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100673 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
674 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200675 }
676
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100677 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
678 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200679 }
680
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100681 result = bsec_write_otp(otp_value, otp);
Yann Gautier091eab52019-06-04 18:06:34 +0200682 if (result != BSEC_OK) {
683 return result;
684 }
685
686 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100687 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
688 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier091eab52019-06-04 18:06:34 +0200689 return BSEC_LOCK_FAIL;
690 }
691
692 return BSEC_OK;
693}
694#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100695
Yann Gautier8402c292022-06-29 17:03:36 +0200696uintptr_t stm32_get_bkpr_boot_mode_addr(void)
Yann Gautier6eef5252021-12-10 17:04:40 +0100697{
Yann Gautier8402c292022-06-29 17:03:36 +0200698 return tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Igor Opaniukf07e8f32022-06-23 21:19:26 +0300699}
700
Yann Gautier5d2eb552022-11-14 14:14:48 +0100701#if PSA_FWU_SUPPORT
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530702void stm32mp1_fwu_set_boot_idx(void)
703{
704 clk_enable(RTCAPB);
Yann Gautier9bbd26a2022-03-28 17:49:38 +0200705 mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
706 TAMP_BOOT_FWU_INFO_IDX_MSK,
707 (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
708 TAMP_BOOT_FWU_INFO_IDX_MSK);
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530709 clk_disable(RTCAPB);
710}
Nicolas Toromanoff5a937cd2022-02-07 10:12:04 +0100711
712uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
713{
714 uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
715 uint32_t try_cnt;
716
717 clk_enable(RTCAPB);
718 try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
719 TAMP_BOOT_FWU_INFO_CNT_OFF;
720
721 assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
722
723 if (try_cnt != 0U) {
724 mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
725 (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
726 }
727 clk_disable(RTCAPB);
728
729 return try_cnt;
730}
731
732void stm32_set_max_fwu_trial_boot_cnt(void)
733{
734 uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
735
736 clk_enable(RTCAPB);
737 mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
738 (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
739 TAMP_BOOT_FWU_INFO_CNT_MSK);
740 clk_disable(RTCAPB);
741}
Yann Gautier5d2eb552022-11-14 14:14:48 +0100742#endif /* PSA_FWU_SUPPORT */