blob: e58528e910935cadc3ef576563981a4721929f33 [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 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
Yann Gautieree8f5422019-02-14 11:13:25 +010016#include <platform_def.h>
17
Yann Gautier35dc0772019-05-13 18:34:48 +020018/* Internal layout of the 32bit OTP word board_id */
19#define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16)
20#define BOARD_ID_BOARD_NB_SHIFT 16
Patrick Delaunay7704f162020-01-08 10:05:14 +010021#define BOARD_ID_VARCPN_MASK GENMASK(15, 12)
22#define BOARD_ID_VARCPN_SHIFT 12
Yann Gautier35dc0772019-05-13 18:34:48 +020023#define BOARD_ID_REVISION_MASK GENMASK(11, 8)
24#define BOARD_ID_REVISION_SHIFT 8
Patrick Delaunay7704f162020-01-08 10:05:14 +010025#define BOARD_ID_VARFG_MASK GENMASK(7, 4)
26#define BOARD_ID_VARFG_SHIFT 4
Yann Gautier35dc0772019-05-13 18:34:48 +020027#define BOARD_ID_BOM_MASK GENMASK(3, 0)
28
29#define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \
30 BOARD_ID_BOARD_NB_SHIFT)
Patrick Delaunay7704f162020-01-08 10:05:14 +010031#define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \
32 BOARD_ID_VARCPN_SHIFT)
Yann Gautier35dc0772019-05-13 18:34:48 +020033#define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \
34 BOARD_ID_REVISION_SHIFT)
Patrick Delaunay7704f162020-01-08 10:05:14 +010035#define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \
36 BOARD_ID_VARFG_SHIFT)
Yann Gautier35dc0772019-05-13 18:34:48 +020037#define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK)
38
Yann Gautier6eef5252021-12-10 17:04:40 +010039#define TAMP_BOOT_MODE_BACKUP_REG_ID U(20)
40#define TAMP_BOOT_MODE_ITF_MASK U(0x0000FF00)
41#define TAMP_BOOT_MODE_ITF_SHIFT 8
42
Etienne Carriere72369b12019-12-08 08:17:56 +010043#if defined(IMAGE_BL2)
44#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010045 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010046 MT_MEMORY | \
47 MT_RW | \
48 MT_SECURE | \
49 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-12-08 08:17:56 +010050#elif defined(IMAGE_BL32)
51#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
52 STM32MP_SEC_SYSRAM_SIZE, \
53 MT_MEMORY | \
54 MT_RW | \
55 MT_SECURE | \
56 MT_EXECUTE_NEVER)
Yann Gautieree8f5422019-02-14 11:13:25 +010057
Etienne Carriere72369b12019-12-08 08:17:56 +010058/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
59#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
60 STM32MP_NS_SYSRAM_SIZE, \
61 MT_DEVICE | \
62 MT_RW | \
63 MT_NS | \
64 MT_EXECUTE_NEVER)
65#endif
66
Yann Gautieree8f5422019-02-14 11:13:25 +010067#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
68 STM32MP1_DEVICE1_SIZE, \
69 MT_DEVICE | \
70 MT_RW | \
71 MT_SECURE | \
72 MT_EXECUTE_NEVER)
73
74#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
75 STM32MP1_DEVICE2_SIZE, \
76 MT_DEVICE | \
77 MT_RW | \
78 MT_SECURE | \
79 MT_EXECUTE_NEVER)
80
81#if defined(IMAGE_BL2)
82static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010083 MAP_SEC_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +010084 MAP_DEVICE1,
85 MAP_DEVICE2,
86 {0}
87};
88#endif
89#if defined(IMAGE_BL32)
90static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010091 MAP_SEC_SYSRAM,
92 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +010093 MAP_DEVICE1,
94 MAP_DEVICE2,
95 {0}
96};
97#endif
98
99void configure_mmu(void)
100{
101 mmap_add(stm32mp1_mmap);
102 init_xlat_tables();
103
104 enable_mmu_svc_mon(0);
105}
Yann Gautiere3bf9132019-05-07 18:52:17 +0200106
Etienne Carriere66b04522019-12-02 10:05:02 +0100107uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
108{
109 if (bank == GPIO_BANK_Z) {
110 return GPIOZ_BASE;
111 }
112
113 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
114
115 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
116}
117
118uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
119{
120 if (bank == GPIO_BANK_Z) {
121 return 0;
122 }
123
124 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
125
126 return bank * GPIO_BANK_OFFSET;
127}
128
Yann Gautier2b79c372021-06-11 10:54:56 +0200129bool stm32_gpio_is_secure_at_reset(unsigned int bank)
130{
131 if (bank == GPIO_BANK_Z) {
132 return true;
133 }
134
135 return false;
136}
137
Yann Gautiere3bf9132019-05-07 18:52:17 +0200138unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
139{
140 if (bank == GPIO_BANK_Z) {
141 return GPIOZ;
142 }
143
144 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
145
146 return GPIOA + (bank - GPIO_BANK_A);
147}
Yann Gautier091eab52019-06-04 18:06:34 +0200148
Etienne Carriered81dadf2020-04-25 11:14:45 +0200149int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
150{
151 switch (bank) {
152 case GPIO_BANK_A:
153 case GPIO_BANK_B:
154 case GPIO_BANK_C:
155 case GPIO_BANK_D:
156 case GPIO_BANK_E:
157 case GPIO_BANK_F:
158 case GPIO_BANK_G:
159 case GPIO_BANK_H:
160 case GPIO_BANK_I:
161 case GPIO_BANK_J:
162 case GPIO_BANK_K:
163 return fdt_path_offset(fdt, "/soc/pin-controller");
164 case GPIO_BANK_Z:
165 return fdt_path_offset(fdt, "/soc/pin-controller-z");
166 default:
167 panic();
168 }
169}
170
Yann Gautier3d8497c2021-10-18 16:06:22 +0200171#if STM32MP_UART_PROGRAMMER || !defined(IMAGE_BL2)
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200172/*
173 * UART Management
174 */
175static const uintptr_t stm32mp1_uart_addresses[8] = {
176 USART1_BASE,
177 USART2_BASE,
178 USART3_BASE,
179 UART4_BASE,
180 UART5_BASE,
181 USART6_BASE,
182 UART7_BASE,
183 UART8_BASE,
184};
185
186uintptr_t get_uart_address(uint32_t instance_nb)
187{
188 if ((instance_nb == 0U) ||
189 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
190 return 0U;
191 }
192
193 return stm32mp1_uart_addresses[instance_nb - 1U];
194}
195#endif
196
Yann Gautiercd16df32021-06-04 14:04:05 +0200197#if STM32MP_USB_PROGRAMMER
198struct gpio_bank_pin_list {
199 uint32_t bank;
200 uint32_t pin;
201};
202
203static const struct gpio_bank_pin_list gpio_list[] = {
204 { /* USART2_RX: GPIOA3 */
205 .bank = 0U,
206 .pin = 3U,
207 },
208 { /* USART3_RX: GPIOB12 */
209 .bank = 1U,
210 .pin = 12U,
211 },
212 { /* UART4_RX: GPIOB2 */
213 .bank = 1U,
214 .pin = 2U,
215 },
216 { /* UART5_RX: GPIOB4 */
217 .bank = 1U,
218 .pin = 5U,
219 },
220 { /* USART6_RX: GPIOC7 */
221 .bank = 2U,
222 .pin = 7U,
223 },
224 { /* UART7_RX: GPIOF6 */
225 .bank = 5U,
226 .pin = 6U,
227 },
228 { /* UART8_RX: GPIOE0 */
229 .bank = 4U,
230 .pin = 0U,
231 },
232};
233
234void stm32mp1_deconfigure_uart_pins(void)
235{
236 size_t i;
237
238 for (i = 0U; i < ARRAY_SIZE(gpio_list); i++) {
239 set_gpio_reset_cfg(gpio_list[i].bank, gpio_list[i].pin);
240 }
241}
242#endif
243
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200244uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200245{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200246 uint32_t version = 0U;
247
248 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
249 INFO("Cannot get CPU version, debug disabled\n");
250 return 0U;
251 }
252
253 return version;
254}
Yann Gautierc7374052019-06-04 18:02:37 +0200255
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200256uint32_t stm32mp_get_chip_dev_id(void)
257{
258 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200259
Yann Gautierc7374052019-06-04 18:02:37 +0200260 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200261 INFO("Use default chip ID, debug disabled\n");
262 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200263 }
264
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200265 return dev_id;
266}
267
268static uint32_t get_part_number(void)
269{
270 static uint32_t part_number;
271
272 if (part_number != 0U) {
273 return part_number;
274 }
275
Yann Gautierc7374052019-06-04 18:02:37 +0200276 if (bsec_shadow_read_otp(&part_number, PART_NUMBER_OTP) != BSEC_OK) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200277 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200278 }
279
280 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
281 PART_NUMBER_OTP_PART_SHIFT;
282
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200283 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200284
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200285 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200286}
287
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200288static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200289{
290 uint32_t package;
291
292 if (bsec_shadow_read_otp(&package, PACKAGE_OTP) != BSEC_OK) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200293 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200294 }
295
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200296 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200297 PACKAGE_OTP_PKG_SHIFT;
298
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200299 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200300}
301
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200302void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200303{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200304 char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200305
306 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200307 switch (get_part_number()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200308 case STM32MP157C_PART_NB:
309 cpu_s = "157C";
310 break;
311 case STM32MP157A_PART_NB:
312 cpu_s = "157A";
313 break;
314 case STM32MP153C_PART_NB:
315 cpu_s = "153C";
316 break;
317 case STM32MP153A_PART_NB:
318 cpu_s = "153A";
319 break;
320 case STM32MP151C_PART_NB:
321 cpu_s = "151C";
322 break;
323 case STM32MP151A_PART_NB:
324 cpu_s = "151A";
325 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200326 case STM32MP157F_PART_NB:
327 cpu_s = "157F";
328 break;
329 case STM32MP157D_PART_NB:
330 cpu_s = "157D";
331 break;
332 case STM32MP153F_PART_NB:
333 cpu_s = "153F";
334 break;
335 case STM32MP153D_PART_NB:
336 cpu_s = "153D";
337 break;
338 case STM32MP151F_PART_NB:
339 cpu_s = "151F";
340 break;
341 case STM32MP151D_PART_NB:
342 cpu_s = "151D";
343 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200344 default:
345 cpu_s = "????";
346 break;
347 }
348
349 /* Package */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200350 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200351 case PKG_AA_LFBGA448:
352 pkg = "AA";
353 break;
354 case PKG_AB_LFBGA354:
355 pkg = "AB";
356 break;
357 case PKG_AC_TFBGA361:
358 pkg = "AC";
359 break;
360 case PKG_AD_TFBGA257:
361 pkg = "AD";
362 break;
363 default:
364 pkg = "??";
365 break;
366 }
367
368 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200369 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200370 case STM32MP1_REV_B:
371 cpu_r = "B";
372 break;
Lionel Debieve2d64b532019-06-25 10:40:37 +0200373 case STM32MP1_REV_Z:
374 cpu_r = "Z";
375 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200376 default:
377 cpu_r = "?";
378 break;
379 }
380
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200381 snprintf(name, STM32_SOC_NAME_SIZE,
382 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
383}
384
385void stm32mp_print_cpuinfo(void)
386{
387 char name[STM32_SOC_NAME_SIZE];
388
389 stm32mp_get_soc_name(name);
390 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200391}
392
Yann Gautier35dc0772019-05-13 18:34:48 +0200393void stm32mp_print_boardinfo(void)
394{
395 uint32_t board_id;
396 uint32_t board_otp;
397 int bsec_node, bsec_board_id_node;
398 void *fdt;
399 const fdt32_t *cuint;
400
401 if (fdt_get_address(&fdt) == 0) {
402 panic();
403 }
404
405 bsec_node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT);
406 if (bsec_node < 0) {
407 return;
408 }
409
410 bsec_board_id_node = fdt_subnode_offset(fdt, bsec_node, "board_id");
411 if (bsec_board_id_node <= 0) {
412 return;
413 }
414
415 cuint = fdt_getprop(fdt, bsec_board_id_node, "reg", NULL);
416 if (cuint == NULL) {
417 panic();
418 }
419
420 board_otp = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
421
422 if (bsec_shadow_read_otp(&board_id, board_otp) != BSEC_OK) {
423 ERROR("BSEC: PART_NUMBER_OTP Error\n");
424 return;
425 }
426
427 if (board_id != 0U) {
428 char rev[2];
429
430 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
431 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200432 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200433 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100434 BOARD_ID2VARCPN(board_id),
435 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200436 rev,
437 BOARD_ID2BOM(board_id));
438 }
439}
440
Yann Gautieraf19ff92019-06-04 18:23:10 +0200441/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
442bool stm32mp_is_single_core(void)
443{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200444 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200445 case STM32MP151A_PART_NB:
446 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200447 case STM32MP151D_PART_NB:
448 case STM32MP151F_PART_NB:
449 return true;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200450 default:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200451 return false;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200452 }
Yann Gautieraf19ff92019-06-04 18:23:10 +0200453}
454
Lionel Debieve0e73d732019-09-16 12:17:09 +0200455/* Return true when device is in closed state */
456bool stm32mp_is_closed_device(void)
457{
458 uint32_t value;
459
460 if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
461 (bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
462 return true;
463 }
464
465 return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
466}
467
Yann Gautier091eab52019-06-04 18:06:34 +0200468uint32_t stm32_iwdg_get_instance(uintptr_t base)
469{
470 switch (base) {
471 case IWDG1_BASE:
472 return IWDG1_INST;
473 case IWDG2_BASE:
474 return IWDG2_INST;
475 default:
476 panic();
477 }
478}
479
480uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
481{
482 uint32_t iwdg_cfg = 0U;
483 uint32_t otp_value;
484
485#if defined(IMAGE_BL2)
486 if (bsec_shadow_register(HW2_OTP) != BSEC_OK) {
487 panic();
488 }
489#endif
490
491 if (bsec_read_otp(&otp_value, HW2_OTP) != BSEC_OK) {
492 panic();
493 }
494
495 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
496 iwdg_cfg |= IWDG_HW_ENABLED;
497 }
498
499 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
500 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
501 }
502
503 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
504 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
505 }
506
507 return iwdg_cfg;
508}
509
510#if defined(IMAGE_BL2)
511uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
512{
513 uint32_t otp;
514 uint32_t result;
515
516 if (bsec_shadow_read_otp(&otp, HW2_OTP) != BSEC_OK) {
517 panic();
518 }
519
520 if ((flags & IWDG_DISABLE_ON_STOP) != 0U) {
521 otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
522 }
523
524 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0U) {
525 otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
526 }
527
528 result = bsec_write_otp(otp, HW2_OTP);
529 if (result != BSEC_OK) {
530 return result;
531 }
532
533 /* Sticky lock OTP_IWDG (read and write) */
534 if (!bsec_write_sr_lock(HW2_OTP, 1U) ||
535 !bsec_write_sw_lock(HW2_OTP, 1U)) {
536 return BSEC_LOCK_FAIL;
537 }
538
539 return BSEC_OK;
540}
541#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100542
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200543#if STM32MP_USE_STM32IMAGE
Yann Gautier8f268c82020-02-26 13:39:44 +0100544/* Get the non-secure DDR size */
545uint32_t stm32mp_get_ddr_ns_size(void)
546{
547 static uint32_t ddr_ns_size;
548 uint32_t ddr_size;
549
550 if (ddr_ns_size != 0U) {
551 return ddr_ns_size;
552 }
553
554 ddr_size = dt_get_ddr_size();
555 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
556 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
557 panic();
558 }
559
560 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
561
562 return ddr_ns_size;
563}
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200564#endif /* STM32MP_USE_STM32IMAGE */
Yann Gautier6eef5252021-12-10 17:04:40 +0100565
566void stm32_save_boot_interface(uint32_t interface, uint32_t instance)
567{
568 uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
569
Yann Gautiera205a5c2021-08-30 15:06:54 +0200570 clk_enable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100571
572 mmio_clrsetbits_32(bkpr_itf_idx,
573 TAMP_BOOT_MODE_ITF_MASK,
574 ((interface << 4) | (instance & 0xFU)) <<
575 TAMP_BOOT_MODE_ITF_SHIFT);
576
Yann Gautiera205a5c2021-08-30 15:06:54 +0200577 clk_disable(RTCAPB);
Yann Gautier6eef5252021-12-10 17:04:40 +0100578}
Yann Gautieraaee0612020-12-16 12:04:06 +0100579
580void stm32_get_boot_interface(uint32_t *interface, uint32_t *instance)
581{
582 static uint32_t itf;
583
584 if (itf == 0U) {
585 uint32_t bkpr = tamp_bkpr(TAMP_BOOT_MODE_BACKUP_REG_ID);
586
Yann Gautiera205a5c2021-08-30 15:06:54 +0200587 clk_enable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100588
589 itf = (mmio_read_32(bkpr) & TAMP_BOOT_MODE_ITF_MASK) >>
590 TAMP_BOOT_MODE_ITF_SHIFT;
591
Yann Gautiera205a5c2021-08-30 15:06:54 +0200592 clk_disable(RTCAPB);
Yann Gautieraaee0612020-12-16 12:04:06 +0100593 }
594
595 *interface = itf >> 4;
596 *instance = itf & 0xFU;
597}