blob: 86b9f237a729af97c88d5373d222d4599b1258c4 [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
Igor Opaniukf07e8f32022-06-23 21:19:26 +030046#define TAMP_BOOT_MODE_ITF_MASK GENMASK(15, 8)
Yann Gautier6eef5252021-12-10 17:04:40 +010047#define TAMP_BOOT_MODE_ITF_SHIFT 8
Igor Opaniukf07e8f32022-06-23 21:19:26 +030048#define TAMP_BOOT_MODE_AUTH_MASK GENMASK(23, 16)
49#define TAMP_BOOT_MODE_AUTH_SHIFT 16
Yann Gautier6eef5252021-12-10 17:04:40 +010050
Yann Gautier9bbd26a2022-03-28 17:49:38 +020051/*
52 * Backup register to store fwu update information.
53 * It should be writeable only by secure world, but also readable by non secure
54 * (so it should be in Zone 2).
55 */
56#define TAMP_BOOT_FWU_INFO_REG_ID U(10)
Igor Opaniukf07e8f32022-06-23 21:19:26 +030057#define TAMP_BOOT_FWU_INFO_IDX_MSK GENMASK(3, 0)
Yann Gautier9bbd26a2022-03-28 17:49:38 +020058#define TAMP_BOOT_FWU_INFO_IDX_OFF U(0)
Igor Opaniukf07e8f32022-06-23 21:19:26 +030059#define TAMP_BOOT_FWU_INFO_CNT_MSK GENMASK(7, 4)
Yann Gautier9bbd26a2022-03-28 17:49:38 +020060#define TAMP_BOOT_FWU_INFO_CNT_OFF U(4)
Sughosh Ganu03e2f802021-12-01 15:56:27 +053061
Etienne Carriere72369b12019-12-08 08:17:56 +010062#if defined(IMAGE_BL2)
63#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010064 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010065 MT_MEMORY | \
66 MT_RW | \
67 MT_SECURE | \
68 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-12-08 08:17:56 +010069#elif defined(IMAGE_BL32)
70#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
71 STM32MP_SEC_SYSRAM_SIZE, \
72 MT_MEMORY | \
73 MT_RW | \
74 MT_SECURE | \
75 MT_EXECUTE_NEVER)
Yann Gautieree8f5422019-02-14 11:13:25 +010076
Etienne Carriere72369b12019-12-08 08:17:56 +010077/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
78#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
79 STM32MP_NS_SYSRAM_SIZE, \
80 MT_DEVICE | \
81 MT_RW | \
82 MT_NS | \
83 MT_EXECUTE_NEVER)
84#endif
85
Yann Gautier84d994b2020-04-14 18:08:50 +020086#if STM32MP13
87#define MAP_SRAM_ALL MAP_REGION_FLAT(SRAMS_BASE, \
88 SRAMS_SIZE_2MB_ALIGNED, \
89 MT_MEMORY | \
90 MT_RW | \
91 MT_SECURE | \
92 MT_EXECUTE_NEVER)
93#endif
94
Yann Gautieree8f5422019-02-14 11:13:25 +010095#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
96 STM32MP1_DEVICE1_SIZE, \
97 MT_DEVICE | \
98 MT_RW | \
99 MT_SECURE | \
100 MT_EXECUTE_NEVER)
101
102#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
103 STM32MP1_DEVICE2_SIZE, \
104 MT_DEVICE | \
105 MT_RW | \
106 MT_SECURE | \
107 MT_EXECUTE_NEVER)
108
109#if defined(IMAGE_BL2)
110static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100111 MAP_SEC_SYSRAM,
Yann Gautier84d994b2020-04-14 18:08:50 +0200112#if STM32MP13
113 MAP_SRAM_ALL,
114#endif
Yann Gautieree8f5422019-02-14 11:13:25 +0100115 MAP_DEVICE1,
Yann Gautier352d8632020-09-17 11:38:09 +0200116#if STM32MP_RAW_NAND
Yann Gautieree8f5422019-02-14 11:13:25 +0100117 MAP_DEVICE2,
Yann Gautier352d8632020-09-17 11:38:09 +0200118#endif
Yann Gautieree8f5422019-02-14 11:13:25 +0100119 {0}
120};
121#endif
122#if defined(IMAGE_BL32)
123static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +0100124 MAP_SEC_SYSRAM,
125 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +0100126 MAP_DEVICE1,
127 MAP_DEVICE2,
128 {0}
129};
130#endif
131
132void configure_mmu(void)
133{
134 mmap_add(stm32mp1_mmap);
135 init_xlat_tables();
136
137 enable_mmu_svc_mon(0);
138}
Yann Gautiere3bf9132019-05-07 18:52:17 +0200139
Etienne Carriere66b04522019-12-02 10:05:02 +0100140uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
141{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100142#if STM32MP13
143 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
144#endif
145#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100146 if (bank == GPIO_BANK_Z) {
147 return GPIOZ_BASE;
148 }
149
150 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100151#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100152
153 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
154}
155
156uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
157{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100158#if STM32MP13
159 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
160#endif
161#if STM32MP15
Etienne Carriere66b04522019-12-02 10:05:02 +0100162 if (bank == GPIO_BANK_Z) {
163 return 0;
164 }
165
166 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100167#endif
Etienne Carriere66b04522019-12-02 10:05:02 +0100168
169 return bank * GPIO_BANK_OFFSET;
170}
171
Yann Gautier2b79c372021-06-11 10:54:56 +0200172bool stm32_gpio_is_secure_at_reset(unsigned int bank)
173{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100174#if STM32MP13
175 return true;
176#endif
177#if STM32MP15
Yann Gautier2b79c372021-06-11 10:54:56 +0200178 if (bank == GPIO_BANK_Z) {
179 return true;
180 }
181
182 return false;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100183#endif
Yann Gautier2b79c372021-06-11 10:54:56 +0200184}
185
Yann Gautiere3bf9132019-05-07 18:52:17 +0200186unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
187{
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100188#if STM32MP13
189 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_I);
190#endif
191#if STM32MP15
Yann Gautiere3bf9132019-05-07 18:52:17 +0200192 if (bank == GPIO_BANK_Z) {
193 return GPIOZ;
194 }
195
196 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100197#endif
Yann Gautiere3bf9132019-05-07 18:52:17 +0200198
199 return GPIOA + (bank - GPIO_BANK_A);
200}
Yann Gautier091eab52019-06-04 18:06:34 +0200201
Etienne Carriered81dadf2020-04-25 11:14:45 +0200202int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
203{
Yann Gautiere78db3b2022-03-11 14:18:13 +0100204 const char *node_compatible = NULL;
205
Etienne Carriered81dadf2020-04-25 11:14:45 +0200206 switch (bank) {
207 case GPIO_BANK_A:
208 case GPIO_BANK_B:
209 case GPIO_BANK_C:
210 case GPIO_BANK_D:
211 case GPIO_BANK_E:
212 case GPIO_BANK_F:
213 case GPIO_BANK_G:
214 case GPIO_BANK_H:
215 case GPIO_BANK_I:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100216#if STM32MP13
217 node_compatible = "st,stm32mp135-pinctrl";
218 break;
219#endif
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100220#if STM32MP15
Etienne Carriered81dadf2020-04-25 11:14:45 +0200221 case GPIO_BANK_J:
222 case GPIO_BANK_K:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100223 node_compatible = "st,stm32mp157-pinctrl";
224 break;
Etienne Carriered81dadf2020-04-25 11:14:45 +0200225 case GPIO_BANK_Z:
Yann Gautiere78db3b2022-03-11 14:18:13 +0100226 node_compatible = "st,stm32mp157-z-pinctrl";
227 break;
Yann Gautiercc5f89a2020-02-12 09:36:23 +0100228#endif
Etienne Carriered81dadf2020-04-25 11:14:45 +0200229 default:
230 panic();
231 }
Yann Gautiere78db3b2022-03-11 14:18:13 +0100232
233 return fdt_node_offset_by_compatible(fdt, -1, node_compatible);
Etienne Carriered81dadf2020-04-25 11:14:45 +0200234}
235
Yann Gautier3d8497c2021-10-18 16:06:22 +0200236#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200237/*
238 * UART Management
239 */
240static const uintptr_t stm32mp1_uart_addresses[8] = {
241 USART1_BASE,
242 USART2_BASE,
243 USART3_BASE,
244 UART4_BASE,
245 UART5_BASE,
246 USART6_BASE,
247 UART7_BASE,
248 UART8_BASE,
249};
250
251uintptr_t get_uart_address(uint32_t instance_nb)
252{
253 if ((instance_nb == 0U) ||
254 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
255 return 0U;
256 }
257
258 return stm32mp1_uart_addresses[instance_nb - 1U];
259}
260#endif
261
Yann Gautiercd16df32021-06-04 14:04:05 +0200262#if STM32MP_USB_PROGRAMMER
263struct gpio_bank_pin_list {
264 uint32_t bank;
265 uint32_t pin;
266};
267
268static const struct gpio_bank_pin_list gpio_list[] = {
269 { /* USART2_RX: GPIOA3 */
270 .bank = 0U,
271 .pin = 3U,
272 },
273 { /* USART3_RX: GPIOB12 */
274 .bank = 1U,
275 .pin = 12U,
276 },
277 { /* UART4_RX: GPIOB2 */
278 .bank = 1U,
279 .pin = 2U,
280 },
281 { /* UART5_RX: GPIOB4 */
282 .bank = 1U,
283 .pin = 5U,
284 },
285 { /* USART6_RX: GPIOC7 */
286 .bank = 2U,
287 .pin = 7U,
288 },
289 { /* UART7_RX: GPIOF6 */
290 .bank = 5U,
291 .pin = 6U,
292 },
293 { /* UART8_RX: GPIOE0 */
294 .bank = 4U,
295 .pin = 0U,
296 },
297};
298
299void stm32mp1_deconfigure_uart_pins(void)
300{
301 size_t i;
302
303 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
304 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
305 }
306}
307#endif
308
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200309uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200310{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200311#if STM32MP13
312 return stm32mp1_syscfg_get_chip_version();
313#endif
314#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200315 uint32_t version = 0U;
316
317 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
318 INFO("Cannot get CPU version, debug disabled\n");
319 return 0U;
320 }
321
322 return version;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200323#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200324}
Yann Gautierc7374052019-06-04 18:02:37 +0200325
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200326uint32_t stm32mp_get_chip_dev_id(void)
327{
Yann Gautierf36a1d32020-04-21 15:03:59 +0200328#if STM32MP13
329 return stm32mp1_syscfg_get_chip_dev_id();
330#endif
331#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200332 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200333
Yann Gautierc7374052019-06-04 18:02:37 +0200334 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200335 INFO("Use default chip ID, debug disabled\n");
336 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200337 }
338
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200339 return dev_id;
Yann Gautierf36a1d32020-04-21 15:03:59 +0200340#endif
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200341}
342
343static uint32_t get_part_number(void)
344{
345 static uint32_t part_number;
346
347 if (part_number != 0U) {
348 return part_number;
349 }
350
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100351 if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200352 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200353 }
354
355 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
356 PART_NUMBER_OTP_PART_SHIFT;
357
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200358 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200359
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200360 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200361}
362
Yann Gautier16188f32020-02-12 15:38:34 +0100363#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200364static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200365{
366 uint32_t package;
367
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100368 if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200369 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200370 }
371
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200372 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200373 PACKAGE_OTP_PKG_SHIFT;
374
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200375 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200376}
Yann Gautier16188f32020-02-12 15:38:34 +0100377#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200378
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200379void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200380{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200381 char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200382
383 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200384 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100385#if STM32MP13
386 case STM32MP135F_PART_NB:
387 cpu_s = "135F";
388 break;
389 case STM32MP135D_PART_NB:
390 cpu_s = "135D";
391 break;
392 case STM32MP135C_PART_NB:
393 cpu_s = "135C";
394 break;
395 case STM32MP135A_PART_NB:
396 cpu_s = "135A";
397 break;
398 case STM32MP133F_PART_NB:
399 cpu_s = "133F";
400 break;
401 case STM32MP133D_PART_NB:
402 cpu_s = "133D";
403 break;
404 case STM32MP133C_PART_NB:
405 cpu_s = "133C";
406 break;
407 case STM32MP133A_PART_NB:
408 cpu_s = "133A";
409 break;
410 case STM32MP131F_PART_NB:
411 cpu_s = "131F";
412 break;
413 case STM32MP131D_PART_NB:
414 cpu_s = "131D";
415 break;
416 case STM32MP131C_PART_NB:
417 cpu_s = "131C";
418 break;
419 case STM32MP131A_PART_NB:
420 cpu_s = "131A";
421 break;
422#endif
423#if STM32MP15
Yann Gautierc7374052019-06-04 18:02:37 +0200424 case STM32MP157C_PART_NB:
425 cpu_s = "157C";
426 break;
427 case STM32MP157A_PART_NB:
428 cpu_s = "157A";
429 break;
430 case STM32MP153C_PART_NB:
431 cpu_s = "153C";
432 break;
433 case STM32MP153A_PART_NB:
434 cpu_s = "153A";
435 break;
436 case STM32MP151C_PART_NB:
437 cpu_s = "151C";
438 break;
439 case STM32MP151A_PART_NB:
440 cpu_s = "151A";
441 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200442 case STM32MP157F_PART_NB:
443 cpu_s = "157F";
444 break;
445 case STM32MP157D_PART_NB:
446 cpu_s = "157D";
447 break;
448 case STM32MP153F_PART_NB:
449 cpu_s = "153F";
450 break;
451 case STM32MP153D_PART_NB:
452 cpu_s = "153D";
453 break;
454 case STM32MP151F_PART_NB:
455 cpu_s = "151F";
456 break;
457 case STM32MP151D_PART_NB:
458 cpu_s = "151D";
459 break;
Yann Gautier16188f32020-02-12 15:38:34 +0100460#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200461 default:
462 cpu_s = "????";
463 break;
464 }
465
466 /* Package */
Yann Gautier16188f32020-02-12 15:38:34 +0100467#if STM32MP13
468 /* On STM32MP13, package is not present in OTP */
469 pkg = "";
470#endif
471#if STM32MP15
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200472 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200473 case PKG_AA_LFBGA448:
474 pkg = "AA";
475 break;
476 case PKG_AB_LFBGA354:
477 pkg = "AB";
478 break;
479 case PKG_AC_TFBGA361:
480 pkg = "AC";
481 break;
482 case PKG_AD_TFBGA257:
483 pkg = "AD";
484 break;
485 default:
486 pkg = "??";
487 break;
488 }
Yann Gautier16188f32020-02-12 15:38:34 +0100489#endif
Yann Gautierc7374052019-06-04 18:02:37 +0200490
491 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200492 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200493 case STM32MP1_REV_B:
494 cpu_r = "B";
495 break;
Lionel Debieve2d64b532019-06-25 10:40:37 +0200496 case STM32MP1_REV_Z:
497 cpu_r = "Z";
498 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200499 default:
500 cpu_r = "?";
501 break;
502 }
503
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200504 snprintf(name, STM32_SOC_NAME_SIZE,
505 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
506}
507
508void stm32mp_print_cpuinfo(void)
509{
510 char name[STM32_SOC_NAME_SIZE];
511
512 stm32mp_get_soc_name(name);
513 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200514}
515
Yann Gautier35dc0772019-05-13 18:34:48 +0200516void stm32mp_print_boardinfo(void)
517{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100518 uint32_t board_id = 0;
Yann Gautier35dc0772019-05-13 18:34:48 +0200519
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100520 if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
Yann Gautier35dc0772019-05-13 18:34:48 +0200521 return;
522 }
523
Yann Gautier35dc0772019-05-13 18:34:48 +0200524 if (board_id != 0U) {
525 char rev[2];
526
527 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
528 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200529 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200530 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100531 BOARD_ID2VARCPN(board_id),
532 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200533 rev,
534 BOARD_ID2BOM(board_id));
535 }
536}
537
Yann Gautieraf19ff92019-06-04 18:23:10 +0200538/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
539bool stm32mp_is_single_core(void)
540{
Yann Gautier6bd30e22020-02-06 15:34:16 +0100541#if STM32MP13
542 return true;
543#endif
544#if STM32MP15
Yann Gautier2f3b5602021-10-19 13:31:06 +0200545 bool single_core = false;
546
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200547 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200548 case STM32MP151A_PART_NB:
549 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200550 case STM32MP151D_PART_NB:
551 case STM32MP151F_PART_NB:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200552 single_core = true;
553 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200554 default:
Yann Gautier2f3b5602021-10-19 13:31:06 +0200555 break;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200556 }
Yann Gautier2f3b5602021-10-19 13:31:06 +0200557
558 return single_core;
Yann Gautier6bd30e22020-02-06 15:34:16 +0100559#endif
Yann Gautieraf19ff92019-06-04 18:23:10 +0200560}
561
Lionel Debieve0e73d732019-09-16 12:17:09 +0200562/* Return true when device is in closed state */
563bool stm32mp_is_closed_device(void)
564{
565 uint32_t value;
566
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100567 if (stm32_get_otp_value(CFG0_OTP, &value) != 0) {
Lionel Debieve0e73d732019-09-16 12:17:09 +0200568 return true;
569 }
570
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100571#if STM32MP13
572 value = (value & CFG0_OTP_MODE_MASK) >> CFG0_OTP_MODE_SHIFT;
573
574 switch (value) {
575 case CFG0_OPEN_DEVICE:
576 return false;
577 case CFG0_CLOSED_DEVICE:
578 case CFG0_CLOSED_DEVICE_NO_BOUNDARY_SCAN:
579 case CFG0_CLOSED_DEVICE_NO_JTAG:
580 return true;
581 default:
582 panic();
583 }
584#endif
585#if STM32MP15
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100586 return (value & CFG0_CLOSED_DEVICE) == CFG0_CLOSED_DEVICE;
Nicolas Le Bayon34cbf232020-11-26 09:57:09 +0100587#endif
Lionel Debieve0e73d732019-09-16 12:17:09 +0200588}
589
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100590/* Return true when device supports secure boot */
591bool stm32mp_is_auth_supported(void)
592{
593 bool supported = false;
594
595 switch (get_part_number()) {
Yann Gautier16188f32020-02-12 15:38:34 +0100596#if STM32MP13
597 case STM32MP131C_PART_NB:
598 case STM32MP131F_PART_NB:
599 case STM32MP133C_PART_NB:
600 case STM32MP133F_PART_NB:
601 case STM32MP135C_PART_NB:
602 case STM32MP135F_PART_NB:
603#endif
604#if STM32MP15
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100605 case STM32MP151C_PART_NB:
606 case STM32MP151F_PART_NB:
607 case STM32MP153C_PART_NB:
608 case STM32MP153F_PART_NB:
609 case STM32MP157C_PART_NB:
610 case STM32MP157F_PART_NB:
Yann Gautier16188f32020-02-12 15:38:34 +0100611#endif
Lionel Debieve06bc62d2019-12-06 12:42:20 +0100612 supported = true;
613 break;
614 default:
615 break;
616 }
617
618 return supported;
619}
620
Yann Gautier091eab52019-06-04 18:06:34 +0200621uint32_t stm32_iwdg_get_instance(uintptr_t base)
622{
623 switch (base) {
624 case IWDG1_BASE:
625 return IWDG1_INST;
626 case IWDG2_BASE:
627 return IWDG2_INST;
628 default:
629 panic();
630 }
631}
632
633uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
634{
635 uint32_t iwdg_cfg = 0U;
636 uint32_t otp_value;
637
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100638 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200639 panic();
640 }
641
642 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
643 iwdg_cfg |= IWDG_HW_ENABLED;
644 }
645
646 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
647 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
648 }
649
650 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
651 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
652 }
653
654 return iwdg_cfg;
655}
656
657#if defined(IMAGE_BL2)
658uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
659{
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100660 uint32_t otp_value;
Yann Gautier091eab52019-06-04 18:06:34 +0200661 uint32_t otp;
662 uint32_t result;
663
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100664 if (stm32_get_otp_index(HW2_OTP, &otp, NULL) != 0) {
665 panic();
666 }
667
668 if (stm32_get_otp_value(HW2_OTP, &otp_value) != 0) {
Yann Gautier091eab52019-06-04 18:06:34 +0200669 panic();
670 }
671
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100672 if ((flags & IWDG_DISABLE_ON_STOP) != 0) {
673 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200674 }
675
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100676 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0) {
677 otp_value |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
Yann Gautier091eab52019-06-04 18:06:34 +0200678 }
679
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100680 result = bsec_write_otp(otp_value, otp);
Yann Gautier091eab52019-06-04 18:06:34 +0200681 if (result != BSEC_OK) {
682 return result;
683 }
684
685 /* Sticky lock OTP_IWDG (read and write) */
Lionel Debievebc2d88d2019-11-04 14:31:38 +0100686 if ((bsec_set_sr_lock(otp) != BSEC_OK) ||
687 (bsec_set_sw_lock(otp) != BSEC_OK)) {
Yann Gautier091eab52019-06-04 18:06:34 +0200688 return BSEC_LOCK_FAIL;
689 }
690
691 return BSEC_OK;
692}
693#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100694
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200695#if STM32MP_USE_STM32IMAGE
Yann Gautier8f268c82020-02-26 13:39:44 +0100696/* Get the non-secure DDR size */
697uint32_t stm32mp_get_ddr_ns_size(void)
698{
699 static uint32_t ddr_ns_size;
700 uint32_t ddr_size;
701
702 if (ddr_ns_size != 0U) {
703 return ddr_ns_size;
704 }
705
706 ddr_size = dt_get_ddr_size();
707 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
708 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
709 panic();
710 }
711
712 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
713
714 return ddr_ns_size;
715}
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200716#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier6eef5252021-12-10 17:04:40 +0100717
718void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
719{
Nicolas Toromanoffbb82b1b2022-02-09 12:26:31 +0100720 uintptr_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautier6eef5252021-12-10 17:04:40 +0100721
Yann Gautiera205a5c2021-08-30 15:06:54 +0200722 clk_enable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100723
724 mmio_clrsetbits_32(bkpr_itf_idx,
725 TAMP_BOOT_MODE_ITF_MASK,
726 ((interface << 4) | (instance & 0xFU)) <<
727 TAMP_BOOT_MODE_ITF_SHIFT);
728
Yann Gautiera205a5c2021-08-30 15:06:54 +0200729 clk_disable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100730}
Yann Gautieraaee0612020-12-16 12:04:06 +0100731
732void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
733{
734 static uint32_t itf;
735
736 if (itf == 0U) {
Nicolas Toromanoffbb82b1b2022-02-09 12:26:31 +0100737 uintptr_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
Yann Gautieraaee0612020-12-16 12:04:06 +0100738
Yann Gautiera205a5c2021-08-30 15:06:54 +0200739 clk_enable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100740
741 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
742 TAMP_BOOT_MODE_ITF_SHIFT;
743
Yann Gautiera205a5c2021-08-30 15:06:54 +0200744 clk_disable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100745 }
746
747 *interface = itf >> 4;
748 *instance = itf & 0xFU;
749}
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530750
Igor Opaniukf07e8f32022-06-23 21:19:26 +0300751void stm32_save_boot_auth(uint32_t auth_status, uint32_t boot_partition)
752{
753 uint32_t boot_status = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
754
755 clk_enable(RTCAPB);
756
757 mmio_clrsetbits_32(boot_status,
758 TAMP_BOOT_MODE_AUTH_MASK,
759 ((auth_status << 4) | (boot_partition & 0xFU)) <<
760 TAMP_BOOT_MODE_AUTH_SHIFT);
761
762 clk_disable(RTCAPB);
763}
764
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530765#if !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT
766void stm32mp1_fwu_set_boot_idx(void)
767{
768 clk_enable(RTCAPB);
Yann Gautier9bbd26a2022-03-28 17:49:38 +0200769 mmio_clrsetbits_32(tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID),
770 TAMP_BOOT_FWU_INFO_IDX_MSK,
771 (plat_fwu_get_boot_idx() << TAMP_BOOT_FWU_INFO_IDX_OFF) &
772 TAMP_BOOT_FWU_INFO_IDX_MSK);
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530773 clk_disable(RTCAPB);
774}
Nicolas Toromanoff5a937cd2022-02-07 10:12:04 +0100775
776uint32_t stm32_get_and_dec_fwu_trial_boot_cnt(void)
777{
778 uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
779 uint32_t try_cnt;
780
781 clk_enable(RTCAPB);
782 try_cnt = (mmio_read_32(bkpr_fwu_cnt) & TAMP_BOOT_FWU_INFO_CNT_MSK) >>
783 TAMP_BOOT_FWU_INFO_CNT_OFF;
784
785 assert(try_cnt <= FWU_MAX_TRIAL_REBOOT);
786
787 if (try_cnt != 0U) {
788 mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
789 (try_cnt - 1U) << TAMP_BOOT_FWU_INFO_CNT_OFF);
790 }
791 clk_disable(RTCAPB);
792
793 return try_cnt;
794}
795
796void stm32_set_max_fwu_trial_boot_cnt(void)
797{
798 uintptr_t bkpr_fwu_cnt = tamp_bkpr(TAMP_BOOT_FWU_INFO_REG_ID);
799
800 clk_enable(RTCAPB);
801 mmio_clrsetbits_32(bkpr_fwu_cnt, TAMP_BOOT_FWU_INFO_CNT_MSK,
802 (FWU_MAX_TRIAL_REBOOT << TAMP_BOOT_FWU_INFO_CNT_OFF) &
803 TAMP_BOOT_FWU_INFO_CNT_MSK);
804 clk_disable(RTCAPB);
805}
Sughosh Ganu03e2f802021-12-01 15:56:27 +0530806#endif /* !STM32MP_USE_STM32IMAGE && PSA_FWU_SUPPORT */