blob: 50112d066e658fd6e2337ddc33cae30f6ba07e95 [file] [log] [blame]
Yann Gautieree8f5422019-02-14 11:13:25 +01001/*
Yann Gautiera0a6ff62021-05-10 16:05:18 +02002 * Copyright (c) 2015-2021, 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 Gautiercd16df32021-06-04 14:04:05 +02009#include <drivers/st/stm32_gpio.h>
10#include <drivers/st/stm32_iwdg.h>
Yann Gautier6eef5252021-12-10 17:04:40 +010011#include <lib/mmio.h>
Yann Gautiercd16df32021-06-04 14:04:05 +020012#include <lib/xlat_tables/xlat_tables_v2.h>
Yann Gautier0c810882021-12-17 09:53:04 +010013#include <libfdt.h>
Yann Gautier35dc0772019-05-13 18:34:48 +020014
Yann Gautieree8f5422019-02-14 11:13:25 +010015#include <platform_def.h>
16
Yann Gautier35dc0772019-05-13 18:34:48 +020017/* Internal layout of the 32bit OTP word board_id */
18#define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16)
19#define BOARD_ID_BOARD_NB_SHIFT 16
Patrick Delaunay7704f162020-01-08 10:05:14 +010020#define BOARD_ID_VARCPN_MASK GENMASK(15, 12)
21#define BOARD_ID_VARCPN_SHIFT 12
Yann Gautier35dc0772019-05-13 18:34:48 +020022#define BOARD_ID_REVISION_MASK GENMASK(11, 8)
23#define BOARD_ID_REVISION_SHIFT 8
Patrick Delaunay7704f162020-01-08 10:05:14 +010024#define BOARD_ID_VARFG_MASK GENMASK(7, 4)
25#define BOARD_ID_VARFG_SHIFT 4
Yann Gautier35dc0772019-05-13 18:34:48 +020026#define BOARD_ID_BOM_MASK GENMASK(3, 0)
27
28#define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \
29 BOARD_ID_BOARD_NB_SHIFT)
Patrick Delaunay7704f162020-01-08 10:05:14 +010030#define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \
31 BOARD_ID_VARCPN_SHIFT)
Yann Gautier35dc0772019-05-13 18:34:48 +020032#define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \
33 BOARD_ID_REVISION_SHIFT)
Patrick Delaunay7704f162020-01-08 10:05:14 +010034#define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \
35 BOARD_ID_VARFG_SHIFT)
Yann Gautier35dc0772019-05-13 18:34:48 +020036#define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK)
37
Yann Gautier6eef5252021-12-10 17:04:40 +010038#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
39#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
40#define TAMP_BOOT_MODE_ITF_SHIFT 8
41
Etienne Carriere72369b12019-12-08 08:17:56 +010042#if defined(IMAGE_BL2)
43#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010044 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010045 MT_MEMORY | \
46 MT_RW | \
47 MT_SECURE | \
48 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-12-08 08:17:56 +010049#elif defined(IMAGE_BL32)
50#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
51 STM32MP_SEC_SYSRAM_SIZE, \
52 MT_MEMORY | \
53 MT_RW | \
54 MT_SECURE | \
55 MT_EXECUTE_NEVER)
Yann Gautieree8f5422019-02-14 11:13:25 +010056
Etienne Carriere72369b12019-12-08 08:17:56 +010057/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
58#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
59 STM32MP_NS_SYSRAM_SIZE, \
60 MT_DEVICE | \
61 MT_RW | \
62 MT_NS | \
63 MT_EXECUTE_NEVER)
64#endif
65
Yann Gautieree8f5422019-02-14 11:13:25 +010066#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
67 STM32MP1_DEVICE1_SIZE, \
68 MT_DEVICE | \
69 MT_RW | \
70 MT_SECURE | \
71 MT_EXECUTE_NEVER)
72
73#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
74 STM32MP1_DEVICE2_SIZE, \
75 MT_DEVICE | \
76 MT_RW | \
77 MT_SECURE | \
78 MT_EXECUTE_NEVER)
79
80#if defined(IMAGE_BL2)
81static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010082 MAP_SEC_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +010083 MAP_DEVICE1,
84 MAP_DEVICE2,
85 {0}
86};
87#endif
88#if defined(IMAGE_BL32)
89static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010090 MAP_SEC_SYSRAM,
91 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +010092 MAP_DEVICE1,
93 MAP_DEVICE2,
94 {0}
95};
96#endif
97
98void configure_mmu(void)
99{
100 mmap_add(stm32mp1_mmap);
101 init_xlat_tables();
102
103 enable_mmu_svc_mon(0);
104}
Yann Gautiere3bf9132019-05-07 18:52:17 +0200105
Etienne Carriere66b04522019-12-02 10:05:02 +0100106uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
107{
108 if (bank == GPIO_BANK_Z) {
109 return GPIOZ_BASE;
110 }
111
112 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
113
114 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
115}
116
117uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
118{
119 if (bank == GPIO_BANK_Z) {
120 return 0;
121 }
122
123 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
124
125 return bank * GPIO_BANK_OFFSET;
126}
127
Yann Gautier2b79c372021-06-11 10:54:56 +0200128bool stm32_gpio_is_secure_at_reset(unsigned int bank)
129{
130 if (bank == GPIO_BANK_Z) {
131 return true;
132 }
133
134 return false;
135}
136
Yann Gautiere3bf9132019-05-07 18:52:17 +0200137unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
138{
139 if (bank == GPIO_BANK_Z) {
140 return GPIOZ;
141 }
142
143 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
144
145 return GPIOA + (bank - GPIO_BANK_A);
146}
Yann Gautier091eab52019-06-04 18:06:34 +0200147
Etienne Carriered81dadf2020-04-25 11:14:45 +0200148int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
149{
150 switch (bank) {
151 case GPIO_BANK_A:
152 case GPIO_BANK_B:
153 case GPIO_BANK_C:
154 case GPIO_BANK_D:
155 case GPIO_BANK_E:
156 case GPIO_BANK_F:
157 case GPIO_BANK_G:
158 case GPIO_BANK_H:
159 case GPIO_BANK_I:
160 case GPIO_BANK_J:
161 case GPIO_BANK_K:
162 return fdt_path_offset(fdt, "/soc/pin-controller");
163 case GPIO_BANK_Z:
164 return fdt_path_offset(fdt, "/soc/pin-controller-z");
165 default:
166 panic();
167 }
168}
169
Yann Gautier3d8497c2021-10-18 16:06:22 +0200170#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200171/*
172 * UART Management
173 */
174static const uintptr_t stm32mp1_uart_addresses[8] = {
175 USART1_BASE,
176 USART2_BASE,
177 USART3_BASE,
178 UART4_BASE,
179 UART5_BASE,
180 USART6_BASE,
181 UART7_BASE,
182 UART8_BASE,
183};
184
185uintptr_t get_uart_address(uint32_t instance_nb)
186{
187 if ((instance_nb == 0U) ||
188 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
189 return 0U;
190 }
191
192 return stm32mp1_uart_addresses[instance_nb - 1U];
193}
194#endif
195
Yann Gautiercd16df32021-06-04 14:04:05 +0200196#if STM32MP_USB_PROGRAMMER
197struct gpio_bank_pin_list {
198 uint32_t bank;
199 uint32_t pin;
200};
201
202static const struct gpio_bank_pin_list gpio_list[] = {
203 { /* USART2_RX: GPIOA3 */
204 .bank = 0U,
205 .pin = 3U,
206 },
207 { /* USART3_RX: GPIOB12 */
208 .bank = 1U,
209 .pin = 12U,
210 },
211 { /* UART4_RX: GPIOB2 */
212 .bank = 1U,
213 .pin = 2U,
214 },
215 { /* UART5_RX: GPIOB4 */
216 .bank = 1U,
217 .pin = 5U,
218 },
219 { /* USART6_RX: GPIOC7 */
220 .bank = 2U,
221 .pin = 7U,
222 },
223 { /* UART7_RX: GPIOF6 */
224 .bank = 5U,
225 .pin = 6U,
226 },
227 { /* UART8_RX: GPIOE0 */
228 .bank = 4U,
229 .pin = 0U,
230 },
231};
232
233void stm32mp1_deconfigure_uart_pins(void)
234{
235 size_t i;
236
237 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
238 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
239 }
240}
241#endif
242
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200243uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200244{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200245 uint32_t version = 0U;
246
247 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
248 INFO("Cannot get CPU version, debug disabled\n");
249 return 0U;
250 }
251
252 return version;
253}
Yann Gautierc7374052019-06-04 18:02:37 +0200254
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200255uint32_t stm32mp_get_chip_dev_id(void)
256{
257 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200258
Yann Gautierc7374052019-06-04 18:02:37 +0200259 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200260 INFO("Use default chip ID, debug disabled\n");
261 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200262 }
263
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200264 return dev_id;
265}
266
267static uint32_t get_part_number(void)
268{
269 static uint32_t part_number;
270
271 if (part_number != 0U) {
272 return part_number;
273 }
274
Yann Gautierc7374052019-06-04 18:02:37 +0200275 if (bsec_shadow_read_otp(&part_number, PART_NUMBER_OTP) != BSEC_OK) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200276 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200277 }
278
279 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
280 PART_NUMBER_OTP_PART_SHIFT;
281
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200282 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200283
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200284 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200285}
286
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200287static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200288{
289 uint32_t package;
290
291 if (bsec_shadow_read_otp(&package, PACKAGE_OTP) != BSEC_OK) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200292 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200293 }
294
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200295 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200296 PACKAGE_OTP_PKG_SHIFT;
297
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200298 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200299}
300
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200301void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200302{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200303 char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200304
305 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200306 switch (get_part_number()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200307 case STM32MP157C_PART_NB:
308 cpu_s = "157C";
309 break;
310 case STM32MP157A_PART_NB:
311 cpu_s = "157A";
312 break;
313 case STM32MP153C_PART_NB:
314 cpu_s = "153C";
315 break;
316 case STM32MP153A_PART_NB:
317 cpu_s = "153A";
318 break;
319 case STM32MP151C_PART_NB:
320 cpu_s = "151C";
321 break;
322 case STM32MP151A_PART_NB:
323 cpu_s = "151A";
324 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200325 case STM32MP157F_PART_NB:
326 cpu_s = "157F";
327 break;
328 case STM32MP157D_PART_NB:
329 cpu_s = "157D";
330 break;
331 case STM32MP153F_PART_NB:
332 cpu_s = "153F";
333 break;
334 case STM32MP153D_PART_NB:
335 cpu_s = "153D";
336 break;
337 case STM32MP151F_PART_NB:
338 cpu_s = "151F";
339 break;
340 case STM32MP151D_PART_NB:
341 cpu_s = "151D";
342 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200343 default:
344 cpu_s = "????";
345 break;
346 }
347
348 /* Package */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200349 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200350 case PKG_AA_LFBGA448:
351 pkg = "AA";
352 break;
353 case PKG_AB_LFBGA354:
354 pkg = "AB";
355 break;
356 case PKG_AC_TFBGA361:
357 pkg = "AC";
358 break;
359 case PKG_AD_TFBGA257:
360 pkg = "AD";
361 break;
362 default:
363 pkg = "??";
364 break;
365 }
366
367 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200368 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200369 case STM32MP1_REV_B:
370 cpu_r = "B";
371 break;
Lionel Debieve2d64b532019-06-25 10:40:37 +0200372 case STM32MP1_REV_Z:
373 cpu_r = "Z";
374 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200375 default:
376 cpu_r = "?";
377 break;
378 }
379
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200380 snprintf(name, STM32_SOC_NAME_SIZE,
381 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
382}
383
384void stm32mp_print_cpuinfo(void)
385{
386 char name[STM32_SOC_NAME_SIZE];
387
388 stm32mp_get_soc_name(name);
389 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200390}
391
Yann Gautier35dc0772019-05-13 18:34:48 +0200392void stm32mp_print_boardinfo(void)
393{
394 uint32_t board_id;
395 uint32_t board_otp;
396 int bsec_node, bsec_board_id_node;
397 void *fdt;
398 const fdt32_t *cuint;
399
400 if (fdt_get_address(&fdt) == 0) {
401 panic();
402 }
403
404 bsec_node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT);
405 if (bsec_node < 0) {
406 return;
407 }
408
409 bsec_board_id_node = fdt_subnode_offset(fdt, bsec_node, "board_id");
410 if (bsec_board_id_node <= 0) {
411 return;
412 }
413
414 cuint = fdt_getprop(fdt, bsec_board_id_node, "reg", NULL);
415 if (cuint == NULL) {
416 panic();
417 }
418
419 board_otp = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
420
421 if (bsec_shadow_read_otp(&board_id, board_otp) != BSEC_OK) {
422 ERROR("BSEC: PART_NUMBER_OTP Error\n");
423 return;
424 }
425
426 if (board_id != 0U) {
427 char rev[2];
428
429 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
430 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200431 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200432 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100433 BOARD_ID2VARCPN(board_id),
434 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200435 rev,
436 BOARD_ID2BOM(board_id));
437 }
438}
439
Yann Gautieraf19ff92019-06-04 18:23:10 +0200440/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
441bool stm32mp_is_single_core(void)
442{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200443 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200444 case STM32MP151A_PART_NB:
445 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200446 case STM32MP151D_PART_NB:
447 case STM32MP151F_PART_NB:
448 return true;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200449 default:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200450 return false;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200451 }
Yann Gautieraf19ff92019-06-04 18:23:10 +0200452}
453
Lionel Debieve0e73d732019-09-16 12:17:09 +0200454/* Return true when device is in closed state */
455bool stm32mp_is_closed_device(void)
456{
457 uint32_t value;
458
459 if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
460 (bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
461 return true;
462 }
463
464 return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
465}
466
Yann Gautier091eab52019-06-04 18:06:34 +0200467uint32_t stm32_iwdg_get_instance(uintptr_t base)
468{
469 switch (base) {
470 case IWDG1_BASE:
471 return IWDG1_INST;
472 case IWDG2_BASE:
473 return IWDG2_INST;
474 default:
475 panic();
476 }
477}
478
479uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
480{
481 uint32_t iwdg_cfg = 0U;
482 uint32_t otp_value;
483
484#if defined(IMAGE_BL2)
485 if (bsec_shadow_register(HW2_OTP) != BSEC_OK) {
486 panic();
487 }
488#endif
489
490 if (bsec_read_otp(&otp_value, HW2_OTP) != BSEC_OK) {
491 panic();
492 }
493
494 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
495 iwdg_cfg |= IWDG_HW_ENABLED;
496 }
497
498 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
499 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
500 }
501
502 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
503 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
504 }
505
506 return iwdg_cfg;
507}
508
509#if defined(IMAGE_BL2)
510uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
511{
512 uint32_t otp;
513 uint32_t result;
514
515 if (bsec_shadow_read_otp(&otp, HW2_OTP) != BSEC_OK) {
516 panic();
517 }
518
519 if ((flags & IWDG_DISABLE_ON_STOP) != 0U) {
520 otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
521 }
522
523 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0U) {
524 otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
525 }
526
527 result = bsec_write_otp(otp, HW2_OTP);
528 if (result != BSEC_OK) {
529 return result;
530 }
531
532 /* Sticky lock OTP_IWDG (read and write) */
533 if (!bsec_write_sr_lock(HW2_OTP, 1U) ||
534 !bsec_write_sw_lock(HW2_OTP, 1U)) {
535 return BSEC_LOCK_FAIL;
536 }
537
538 return BSEC_OK;
539}
540#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100541
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200542#if STM32MP_USE_STM32IMAGE
Yann Gautier8f268c82020-02-26 13:39:44 +0100543/* Get the non-secure DDR size */
544uint32_t stm32mp_get_ddr_ns_size(void)
545{
546 static uint32_t ddr_ns_size;
547 uint32_t ddr_size;
548
549 if (ddr_ns_size != 0U) {
550 return ddr_ns_size;
551 }
552
553 ddr_size = dt_get_ddr_size();
554 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
555 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
556 panic();
557 }
558
559 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
560
561 return ddr_ns_size;
562}
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200563#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier6eef5252021-12-10 17:04:40 +0100564
565void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
566{
567 uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
568
569 stm32mp_clk_enable(RTCAPB);
570
571 mmio_clrsetbits_32(bkpr_itf_idx,
572 TAMP_BOOT_MODE_ITF_MASK,
573 ((interface << 4) | (instance & 0xFU)) <<
574 TAMP_BOOT_MODE_ITF_SHIFT);
575
576 stm32mp_clk_disable(RTCAPB);
577}
Yann Gautieraaee0612020-12-16 12:04:06 +0100578
579void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
580{
581 static uint32_t itf;
582
583 if (itf == 0U) {
584 uint32_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
585
586 stm32mp_clk_enable(RTCAPB);
587
588 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
589 TAMP_BOOT_MODE_ITF_SHIFT;
590
591 stm32mp_clk_disable(RTCAPB);
592 }
593
594 *interface = itf >> 4;
595 *instance = itf & 0xFU;
596}