blob: 0165cfedf5261450991bce786f6d1d7ebaf5fda8 [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 Gautier35dc0772019-05-13 18:34:48 +02009#include <libfdt.h>
10
Yann Gautieree8f5422019-02-14 11:13:25 +010011#include <platform_def.h>
12
Yann Gautier091eab52019-06-04 18:06:34 +020013#include <drivers/st/stm32_iwdg.h>
Yann Gautieree8f5422019-02-14 11:13:25 +010014#include <lib/xlat_tables/xlat_tables_v2.h>
15
Yann Gautier35dc0772019-05-13 18:34:48 +020016/* Internal layout of the 32bit OTP word board_id */
17#define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16)
18#define BOARD_ID_BOARD_NB_SHIFT 16
Patrick Delaunay7704f162020-01-08 10:05:14 +010019#define BOARD_ID_VARCPN_MASK GENMASK(15, 12)
20#define BOARD_ID_VARCPN_SHIFT 12
Yann Gautier35dc0772019-05-13 18:34:48 +020021#define BOARD_ID_REVISION_MASK GENMASK(11, 8)
22#define BOARD_ID_REVISION_SHIFT 8
Patrick Delaunay7704f162020-01-08 10:05:14 +010023#define BOARD_ID_VARFG_MASK GENMASK(7, 4)
24#define BOARD_ID_VARFG_SHIFT 4
Yann Gautier35dc0772019-05-13 18:34:48 +020025#define BOARD_ID_BOM_MASK GENMASK(3, 0)
26
27#define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \
28 BOARD_ID_BOARD_NB_SHIFT)
Patrick Delaunay7704f162020-01-08 10:05:14 +010029#define BOARD_ID2VARCPN(_id) (((_id) & BOARD_ID_VARCPN_MASK) >> \
30 BOARD_ID_VARCPN_SHIFT)
Yann Gautier35dc0772019-05-13 18:34:48 +020031#define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \
32 BOARD_ID_REVISION_SHIFT)
Patrick Delaunay7704f162020-01-08 10:05:14 +010033#define BOARD_ID2VARFG(_id) (((_id) & BOARD_ID_VARFG_MASK) >> \
34 BOARD_ID_VARFG_SHIFT)
Yann Gautier35dc0772019-05-13 18:34:48 +020035#define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK)
36
Etienne Carriere72369b12019-12-08 08:17:56 +010037#if defined(IMAGE_BL2)
38#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
Yann Gautiera2e2a302019-02-14 11:13:39 +010039 STM32MP_SYSRAM_SIZE, \
Yann Gautieree8f5422019-02-14 11:13:25 +010040 MT_MEMORY | \
41 MT_RW | \
42 MT_SECURE | \
43 MT_EXECUTE_NEVER)
Etienne Carriere72369b12019-12-08 08:17:56 +010044#elif defined(IMAGE_BL32)
45#define MAP_SEC_SYSRAM MAP_REGION_FLAT(STM32MP_SEC_SYSRAM_BASE, \
46 STM32MP_SEC_SYSRAM_SIZE, \
47 MT_MEMORY | \
48 MT_RW | \
49 MT_SECURE | \
50 MT_EXECUTE_NEVER)
Yann Gautieree8f5422019-02-14 11:13:25 +010051
Etienne Carriere72369b12019-12-08 08:17:56 +010052/* Non-secure SYSRAM is used a uncached memory for SCMI message transfer */
53#define MAP_NS_SYSRAM MAP_REGION_FLAT(STM32MP_NS_SYSRAM_BASE, \
54 STM32MP_NS_SYSRAM_SIZE, \
55 MT_DEVICE | \
56 MT_RW | \
57 MT_NS | \
58 MT_EXECUTE_NEVER)
59#endif
60
Yann Gautieree8f5422019-02-14 11:13:25 +010061#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
62 STM32MP1_DEVICE1_SIZE, \
63 MT_DEVICE | \
64 MT_RW | \
65 MT_SECURE | \
66 MT_EXECUTE_NEVER)
67
68#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
69 STM32MP1_DEVICE2_SIZE, \
70 MT_DEVICE | \
71 MT_RW | \
72 MT_SECURE | \
73 MT_EXECUTE_NEVER)
74
75#if defined(IMAGE_BL2)
76static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010077 MAP_SEC_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +010078 MAP_DEVICE1,
79 MAP_DEVICE2,
80 {0}
81};
82#endif
83#if defined(IMAGE_BL32)
84static const mmap_region_t stm32mp1_mmap[] = {
Etienne Carriere72369b12019-12-08 08:17:56 +010085 MAP_SEC_SYSRAM,
86 MAP_NS_SYSRAM,
Yann Gautieree8f5422019-02-14 11:13:25 +010087 MAP_DEVICE1,
88 MAP_DEVICE2,
89 {0}
90};
91#endif
92
93void configure_mmu(void)
94{
95 mmap_add(stm32mp1_mmap);
96 init_xlat_tables();
97
98 enable_mmu_svc_mon(0);
99}
Yann Gautiere3bf9132019-05-07 18:52:17 +0200100
Etienne Carriere66b04522019-12-02 10:05:02 +0100101uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
102{
103 if (bank == GPIO_BANK_Z) {
104 return GPIOZ_BASE;
105 }
106
107 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
108
109 return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
110}
111
112uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
113{
114 if (bank == GPIO_BANK_Z) {
115 return 0;
116 }
117
118 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
119
120 return bank * GPIO_BANK_OFFSET;
121}
122
Yann Gautiere3bf9132019-05-07 18:52:17 +0200123unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
124{
125 if (bank == GPIO_BANK_Z) {
126 return GPIOZ;
127 }
128
129 assert(GPIO_BANK_A == 0 && bank <= GPIO_BANK_K);
130
131 return GPIOA + (bank - GPIO_BANK_A);
132}
Yann Gautier091eab52019-06-04 18:06:34 +0200133
Etienne Carriered81dadf2020-04-25 11:14:45 +0200134int stm32_get_gpio_bank_pinctrl_node(void *fdt, unsigned int bank)
135{
136 switch (bank) {
137 case GPIO_BANK_A:
138 case GPIO_BANK_B:
139 case GPIO_BANK_C:
140 case GPIO_BANK_D:
141 case GPIO_BANK_E:
142 case GPIO_BANK_F:
143 case GPIO_BANK_G:
144 case GPIO_BANK_H:
145 case GPIO_BANK_I:
146 case GPIO_BANK_J:
147 case GPIO_BANK_K:
148 return fdt_path_offset(fdt, "/soc/pin-controller");
149 case GPIO_BANK_Z:
150 return fdt_path_offset(fdt, "/soc/pin-controller-z");
151 default:
152 panic();
153 }
154}
155
Patrick Delaunaye50571b2021-10-28 13:48:52 +0200156#if STM32MP_UART_PROGRAMMER
157/*
158 * UART Management
159 */
160static const uintptr_t stm32mp1_uart_addresses[8] = {
161 USART1_BASE,
162 USART2_BASE,
163 USART3_BASE,
164 UART4_BASE,
165 UART5_BASE,
166 USART6_BASE,
167 UART7_BASE,
168 UART8_BASE,
169};
170
171uintptr_t get_uart_address(uint32_t instance_nb)
172{
173 if ((instance_nb == 0U) ||
174 (instance_nb > ARRAY_SIZE(stm32mp1_uart_addresses))) {
175 return 0U;
176 }
177
178 return stm32mp1_uart_addresses[instance_nb - 1U];
179}
180#endif
181
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200182uint32_t stm32mp_get_chip_version(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200183{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200184 uint32_t version = 0U;
185
186 if (stm32mp1_dbgmcu_get_chip_version(&version) < 0) {
187 INFO("Cannot get CPU version, debug disabled\n");
188 return 0U;
189 }
190
191 return version;
192}
Yann Gautierc7374052019-06-04 18:02:37 +0200193
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200194uint32_t stm32mp_get_chip_dev_id(void)
195{
196 uint32_t dev_id;
Nicolas Le Bayon98f4ea02019-09-23 11:18:32 +0200197
Yann Gautierc7374052019-06-04 18:02:37 +0200198 if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200199 INFO("Use default chip ID, debug disabled\n");
200 dev_id = STM32MP1_CHIP_ID;
Yann Gautierc7374052019-06-04 18:02:37 +0200201 }
202
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200203 return dev_id;
204}
205
206static uint32_t get_part_number(void)
207{
208 static uint32_t part_number;
209
210 if (part_number != 0U) {
211 return part_number;
212 }
213
Yann Gautierc7374052019-06-04 18:02:37 +0200214 if (bsec_shadow_read_otp(&part_number, PART_NUMBER_OTP) != BSEC_OK) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200215 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200216 }
217
218 part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
219 PART_NUMBER_OTP_PART_SHIFT;
220
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200221 part_number |= stm32mp_get_chip_dev_id() << 16;
Yann Gautierc7374052019-06-04 18:02:37 +0200222
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200223 return part_number;
Yann Gautierc7374052019-06-04 18:02:37 +0200224}
225
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200226static uint32_t get_cpu_package(void)
Yann Gautierc7374052019-06-04 18:02:37 +0200227{
228 uint32_t package;
229
230 if (bsec_shadow_read_otp(&package, PACKAGE_OTP) != BSEC_OK) {
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200231 panic();
Yann Gautierc7374052019-06-04 18:02:37 +0200232 }
233
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200234 package = (package & PACKAGE_OTP_PKG_MASK) >>
Yann Gautierc7374052019-06-04 18:02:37 +0200235 PACKAGE_OTP_PKG_SHIFT;
236
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200237 return package;
Yann Gautierc7374052019-06-04 18:02:37 +0200238}
239
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200240void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
Yann Gautierc7374052019-06-04 18:02:37 +0200241{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200242 char *cpu_s, *cpu_r, *pkg;
Yann Gautierc7374052019-06-04 18:02:37 +0200243
244 /* MPUs Part Numbers */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200245 switch (get_part_number()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200246 case STM32MP157C_PART_NB:
247 cpu_s = "157C";
248 break;
249 case STM32MP157A_PART_NB:
250 cpu_s = "157A";
251 break;
252 case STM32MP153C_PART_NB:
253 cpu_s = "153C";
254 break;
255 case STM32MP153A_PART_NB:
256 cpu_s = "153A";
257 break;
258 case STM32MP151C_PART_NB:
259 cpu_s = "151C";
260 break;
261 case STM32MP151A_PART_NB:
262 cpu_s = "151A";
263 break;
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200264 case STM32MP157F_PART_NB:
265 cpu_s = "157F";
266 break;
267 case STM32MP157D_PART_NB:
268 cpu_s = "157D";
269 break;
270 case STM32MP153F_PART_NB:
271 cpu_s = "153F";
272 break;
273 case STM32MP153D_PART_NB:
274 cpu_s = "153D";
275 break;
276 case STM32MP151F_PART_NB:
277 cpu_s = "151F";
278 break;
279 case STM32MP151D_PART_NB:
280 cpu_s = "151D";
281 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200282 default:
283 cpu_s = "????";
284 break;
285 }
286
287 /* Package */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200288 switch (get_cpu_package()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200289 case PKG_AA_LFBGA448:
290 pkg = "AA";
291 break;
292 case PKG_AB_LFBGA354:
293 pkg = "AB";
294 break;
295 case PKG_AC_TFBGA361:
296 pkg = "AC";
297 break;
298 case PKG_AD_TFBGA257:
299 pkg = "AD";
300 break;
301 default:
302 pkg = "??";
303 break;
304 }
305
306 /* REVISION */
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200307 switch (stm32mp_get_chip_version()) {
Yann Gautierc7374052019-06-04 18:02:37 +0200308 case STM32MP1_REV_B:
309 cpu_r = "B";
310 break;
Lionel Debieve2d64b532019-06-25 10:40:37 +0200311 case STM32MP1_REV_Z:
312 cpu_r = "Z";
313 break;
Yann Gautierc7374052019-06-04 18:02:37 +0200314 default:
315 cpu_r = "?";
316 break;
317 }
318
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200319 snprintf(name, STM32_SOC_NAME_SIZE,
320 "STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
321}
322
323void stm32mp_print_cpuinfo(void)
324{
325 char name[STM32_SOC_NAME_SIZE];
326
327 stm32mp_get_soc_name(name);
328 NOTICE("CPU: %s\n", name);
Yann Gautierc7374052019-06-04 18:02:37 +0200329}
330
Yann Gautier35dc0772019-05-13 18:34:48 +0200331void stm32mp_print_boardinfo(void)
332{
333 uint32_t board_id;
334 uint32_t board_otp;
335 int bsec_node, bsec_board_id_node;
336 void *fdt;
337 const fdt32_t *cuint;
338
339 if (fdt_get_address(&fdt) == 0) {
340 panic();
341 }
342
343 bsec_node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT);
344 if (bsec_node < 0) {
345 return;
346 }
347
348 bsec_board_id_node = fdt_subnode_offset(fdt, bsec_node, "board_id");
349 if (bsec_board_id_node <= 0) {
350 return;
351 }
352
353 cuint = fdt_getprop(fdt, bsec_board_id_node, "reg", NULL);
354 if (cuint == NULL) {
355 panic();
356 }
357
358 board_otp = fdt32_to_cpu(*cuint) / sizeof(uint32_t);
359
360 if (bsec_shadow_read_otp(&board_id, board_otp) != BSEC_OK) {
361 ERROR("BSEC: PART_NUMBER_OTP Error\n");
362 return;
363 }
364
365 if (board_id != 0U) {
366 char rev[2];
367
368 rev[0] = BOARD_ID2REV(board_id) - 1 + 'A';
369 rev[1] = '\0';
Yann Gautier36e9d382020-10-13 18:03:31 +0200370 NOTICE("Board: MB%04x Var%u.%u Rev.%s-%02u\n",
Yann Gautier35dc0772019-05-13 18:34:48 +0200371 BOARD_ID2NB(board_id),
Patrick Delaunay7704f162020-01-08 10:05:14 +0100372 BOARD_ID2VARCPN(board_id),
373 BOARD_ID2VARFG(board_id),
Yann Gautier35dc0772019-05-13 18:34:48 +0200374 rev,
375 BOARD_ID2BOM(board_id));
376 }
377}
378
Yann Gautieraf19ff92019-06-04 18:23:10 +0200379/* Return true when SoC provides a single Cortex-A7 core, and false otherwise */
380bool stm32mp_is_single_core(void)
381{
Yann Gautiera0a6ff62021-05-10 16:05:18 +0200382 switch (get_part_number()) {
Yann Gautieraf19ff92019-06-04 18:23:10 +0200383 case STM32MP151A_PART_NB:
384 case STM32MP151C_PART_NB:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200385 case STM32MP151D_PART_NB:
386 case STM32MP151F_PART_NB:
387 return true;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200388 default:
Lionel Debieve7b64e3e2019-05-17 16:01:18 +0200389 return false;
Yann Gautieraf19ff92019-06-04 18:23:10 +0200390 }
Yann Gautieraf19ff92019-06-04 18:23:10 +0200391}
392
Lionel Debieve0e73d732019-09-16 12:17:09 +0200393/* Return true when device is in closed state */
394bool stm32mp_is_closed_device(void)
395{
396 uint32_t value;
397
398 if ((bsec_shadow_register(DATA0_OTP) != BSEC_OK) ||
399 (bsec_read_otp(&value, DATA0_OTP) != BSEC_OK)) {
400 return true;
401 }
402
403 return (value & DATA0_OTP_SECURED) == DATA0_OTP_SECURED;
404}
405
Yann Gautier091eab52019-06-04 18:06:34 +0200406uint32_t stm32_iwdg_get_instance(uintptr_t base)
407{
408 switch (base) {
409 case IWDG1_BASE:
410 return IWDG1_INST;
411 case IWDG2_BASE:
412 return IWDG2_INST;
413 default:
414 panic();
415 }
416}
417
418uint32_t stm32_iwdg_get_otp_config(uint32_t iwdg_inst)
419{
420 uint32_t iwdg_cfg = 0U;
421 uint32_t otp_value;
422
423#if defined(IMAGE_BL2)
424 if (bsec_shadow_register(HW2_OTP) != BSEC_OK) {
425 panic();
426 }
427#endif
428
429 if (bsec_read_otp(&otp_value, HW2_OTP) != BSEC_OK) {
430 panic();
431 }
432
433 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_HW_POS)) != 0U) {
434 iwdg_cfg |= IWDG_HW_ENABLED;
435 }
436
437 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS)) != 0U) {
438 iwdg_cfg |= IWDG_DISABLE_ON_STOP;
439 }
440
441 if ((otp_value & BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS)) != 0U) {
442 iwdg_cfg |= IWDG_DISABLE_ON_STANDBY;
443 }
444
445 return iwdg_cfg;
446}
447
448#if defined(IMAGE_BL2)
449uint32_t stm32_iwdg_shadow_update(uint32_t iwdg_inst, uint32_t flags)
450{
451 uint32_t otp;
452 uint32_t result;
453
454 if (bsec_shadow_read_otp(&otp, HW2_OTP) != BSEC_OK) {
455 panic();
456 }
457
458 if ((flags & IWDG_DISABLE_ON_STOP) != 0U) {
459 otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STOP_POS);
460 }
461
462 if ((flags & IWDG_DISABLE_ON_STANDBY) != 0U) {
463 otp |= BIT(iwdg_inst + HW2_OTP_IWDG_FZ_STANDBY_POS);
464 }
465
466 result = bsec_write_otp(otp, HW2_OTP);
467 if (result != BSEC_OK) {
468 return result;
469 }
470
471 /* Sticky lock OTP_IWDG (read and write) */
472 if (!bsec_write_sr_lock(HW2_OTP, 1U) ||
473 !bsec_write_sw_lock(HW2_OTP, 1U)) {
474 return BSEC_LOCK_FAIL;
475 }
476
477 return BSEC_OK;
478}
479#endif
Yann Gautier8f268c82020-02-26 13:39:44 +0100480
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200481#if STM32MP_USE_STM32IMAGE
Yann Gautier8f268c82020-02-26 13:39:44 +0100482/* Get the non-secure DDR size */
483uint32_t stm32mp_get_ddr_ns_size(void)
484{
485 static uint32_t ddr_ns_size;
486 uint32_t ddr_size;
487
488 if (ddr_ns_size != 0U) {
489 return ddr_ns_size;
490 }
491
492 ddr_size = dt_get_ddr_size();
493 if ((ddr_size <= (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE)) ||
494 (ddr_size > STM32MP_DDR_MAX_SIZE)) {
495 panic();
496 }
497
498 ddr_ns_size = ddr_size - (STM32MP_DDR_S_SIZE + STM32MP_DDR_SHMEM_SIZE);
499
500 return ddr_ns_size;
501}
Lionel Debieve1dc5e2e2020-09-27 21:13:53 +0200502#endif /* STM32MP_USE_STM32IMAGE */