diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index 33638b5..f057390 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -59,6 +59,9 @@ /* Print CPU information */ void stm32mp_print_cpuinfo(void); +/* Print board information */ +void stm32mp_print_boardinfo(void); + /* * Util for clock gating and to get clock rate for stm32 and platform drivers * @id: Target clock ID, ID used in clock DT bindings diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c index 1926be3..75ae372 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -279,6 +279,8 @@ NOTICE("Model: %s\n", board_model); } + stm32mp_print_boardinfo(); + skip_console_init: if (stm32_iwdg_init() < 0) { panic(); diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index 6ee5884..77a95e6 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -331,6 +331,7 @@ /******************************************************************************* * Device Tree defines ******************************************************************************/ +#define DT_BSEC_COMPAT "st,stm32mp15-bsec" #define DT_IWDG_COMPAT "st,stm32mp1-iwdg" #define DT_PWR_COMPAT "st,stm32mp1-pwr" #define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc" diff --git a/plat/st/stm32mp1/stm32mp1_private.c b/plat/st/stm32mp1/stm32mp1_private.c index 08fb815..c334cd1 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -6,11 +6,30 @@ #include +#include + #include #include #include +/* Internal layout of the 32bit OTP word board_id */ +#define BOARD_ID_BOARD_NB_MASK GENMASK(31, 16) +#define BOARD_ID_BOARD_NB_SHIFT 16 +#define BOARD_ID_VARIANT_MASK GENMASK(15, 12) +#define BOARD_ID_VARIANT_SHIFT 12 +#define BOARD_ID_REVISION_MASK GENMASK(11, 8) +#define BOARD_ID_REVISION_SHIFT 8 +#define BOARD_ID_BOM_MASK GENMASK(3, 0) + +#define BOARD_ID2NB(_id) (((_id) & BOARD_ID_BOARD_NB_MASK) >> \ + BOARD_ID_BOARD_NB_SHIFT) +#define BOARD_ID2VAR(_id) (((_id) & BOARD_ID_VARIANT_MASK) >> \ + BOARD_ID_VARIANT_SHIFT) +#define BOARD_ID2REV(_id) (((_id) & BOARD_ID_REVISION_MASK) >> \ + BOARD_ID_REVISION_SHIFT) +#define BOARD_ID2BOM(_id) ((_id) & BOARD_ID_BOM_MASK) + #define MAP_SRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \ STM32MP_SYSRAM_SIZE, \ MT_MEMORY | \ @@ -188,6 +207,53 @@ NOTICE("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r); } +void stm32mp_print_boardinfo(void) +{ + uint32_t board_id; + uint32_t board_otp; + int bsec_node, bsec_board_id_node; + void *fdt; + const fdt32_t *cuint; + + if (fdt_get_address(&fdt) == 0) { + panic(); + } + + bsec_node = fdt_node_offset_by_compatible(fdt, -1, DT_BSEC_COMPAT); + if (bsec_node < 0) { + return; + } + + bsec_board_id_node = fdt_subnode_offset(fdt, bsec_node, "board_id"); + if (bsec_board_id_node <= 0) { + return; + } + + cuint = fdt_getprop(fdt, bsec_board_id_node, "reg", NULL); + if (cuint == NULL) { + panic(); + } + + board_otp = fdt32_to_cpu(*cuint) / sizeof(uint32_t); + + if (bsec_shadow_read_otp(&board_id, board_otp) != BSEC_OK) { + ERROR("BSEC: PART_NUMBER_OTP Error\n"); + return; + } + + if (board_id != 0U) { + char rev[2]; + + rev[0] = BOARD_ID2REV(board_id) - 1 + 'A'; + rev[1] = '\0'; + NOTICE("Board: MB%04x Var%d Rev.%s-%02d\n", + BOARD_ID2NB(board_id), + BOARD_ID2VAR(board_id), + rev, + BOARD_ID2BOM(board_id)); + } +} + uint32_t stm32_iwdg_get_instance(uintptr_t base) { switch (base) {