stm32mp1: print information about board
authorYann Gautier <yann.gautier@st.com>
Mon, 13 May 2019 16:34:48 +0000 (18:34 +0200)
committerYann Gautier <yann.gautier@st.com>
Mon, 2 Sep 2019 15:49:35 +0000 (17:49 +0200)
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>
plat/st/common/include/stm32mp_common.h
plat/st/stm32mp1/bl2_plat_setup.c
plat/st/stm32mp1/stm32mp1_def.h
plat/st/stm32mp1/stm32mp1_private.c

index 33638b5a5528d9eb6d15c7dcea657431d7342418..f0573903de5f920967612cdc470f05998e76a30b 100644 (file)
@@ -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
index 1926be31373e8c6c298e418fe7256c9fd162448b..75ae372aee7a4aa2dd37460f1a7ad7e28a5bba83 100644 (file)
@@ -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();
index 6ee58843238d4ed7368a8125f25414be36dc048b..77a95e68aa5eaf97a647643d042f5324a43b511f 100644 (file)
@@ -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"
index 08fb815ced8ea8bc7b8e00646414855c4d8da2e4..c334cd1e0f6c24c8d8569ff197ddf7b266f55a9b 100644 (file)
@@ -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) {