diff options
author | Yann Gautier <yann.gautier@st.com> | 2019-05-13 18:34:48 +0200 |
---|---|---|
committer | Yann Gautier <yann.gautier@st.com> | 2019-09-02 17:49:35 +0200 |
commit | 10e7a9e904dfddd62ee839098e2d0737a3afad15 (patch) | |
tree | fb111eb679cb7399360fa1fb41d2e1da2409f0c0 /plat/st | |
parent | dec286dd7d7b1aae486a05069a80b8791ab0ba55 (diff) |
stm32mp1: print information about board
On STMicroelectronics boards, the board information is stored in OTP.
This OTP is described in device tree, in BSEC board_id node.
Change-Id: Ieccbdcb048343680faac8dc577b75c67ac106f5b
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
Diffstat (limited to 'plat/st')
-rw-r--r-- | plat/st/common/include/stm32mp_common.h | 3 | ||||
-rw-r--r-- | plat/st/stm32mp1/bl2_plat_setup.c | 2 | ||||
-rw-r--r-- | plat/st/stm32mp1/stm32mp1_def.h | 1 | ||||
-rw-r--r-- | plat/st/stm32mp1/stm32mp1_private.c | 66 |
4 files changed, 72 insertions, 0 deletions
diff --git a/plat/st/common/include/stm32mp_common.h b/plat/st/common/include/stm32mp_common.h index 33638b5a..f0573903 100644 --- a/plat/st/common/include/stm32mp_common.h +++ b/plat/st/common/include/stm32mp_common.h @@ -59,6 +59,9 @@ uint32_t stm32_get_gpio_bank_offset(unsigned int bank); /* 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 1926be31..75ae372a 100644 --- a/plat/st/stm32mp1/bl2_plat_setup.c +++ b/plat/st/stm32mp1/bl2_plat_setup.c @@ -279,6 +279,8 @@ void bl2_el3_plat_arch_setup(void) 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 6ee58843..77a95e68 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -331,6 +331,7 @@ static inline uint32_t tamp_bkpr(uint32_t idx) /******************************************************************************* * 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 08fb815c..c334cd1e 100644 --- a/plat/st/stm32mp1/stm32mp1_private.c +++ b/plat/st/stm32mp1/stm32mp1_private.c @@ -6,11 +6,30 @@ #include <assert.h> +#include <libfdt.h> + #include <platform_def.h> #include <drivers/st/stm32_iwdg.h> #include <lib/xlat_tables/xlat_tables_v2.h> +/* 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 @@ void stm32mp_print_cpuinfo(void) 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) { |