summaryrefslogtreecommitdiff
path: root/plat/st
diff options
context:
space:
mode:
authorYann Gautier <yann.gautier@st.com>2019-05-13 18:34:48 +0200
committerYann Gautier <yann.gautier@st.com>2019-09-02 17:49:35 +0200
commit10e7a9e904dfddd62ee839098e2d0737a3afad15 (patch)
treefb111eb679cb7399360fa1fb41d2e1da2409f0c0 /plat/st
parentdec286dd7d7b1aae486a05069a80b8791ab0ba55 (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.h3
-rw-r--r--plat/st/stm32mp1/bl2_plat_setup.c2
-rw-r--r--plat/st/stm32mp1/stm32mp1_def.h1
-rw-r--r--plat/st/stm32mp1/stm32mp1_private.c66
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) {