stm32mp1: print information about SoC
authorYann Gautier <yann.gautier@st.com>
Tue, 4 Jun 2019 16:02:37 +0000 (18:02 +0200)
committerYann Gautier <yann.gautier@st.com>
Mon, 2 Sep 2019 15:49:30 +0000 (17:49 +0200)
This information is located in DBGMCU registers.

Change-Id: I480aa046fed9992e3d9665b1f0520bc4b6cfdf30
Signed-off-by: Yann Gautier <yann.gautier@st.com>
plat/st/common/include/stm32mp_common.h
plat/st/stm32mp1/bl2_plat_setup.c
plat/st/stm32mp1/include/stm32mp1_dbgmcu.h
plat/st/stm32mp1/stm32mp1_dbgmcu.c
plat/st/stm32mp1/stm32mp1_def.h
plat/st/stm32mp1/stm32mp1_private.c

index f8b5e7bad4e984f2919b36e8d62cc6803e9c8d6a..33638b5a5528d9eb6d15c7dcea657431d7342418 100644 (file)
@@ -56,6 +56,9 @@ uintptr_t stm32_get_gpio_bank_base(unsigned int bank);
 unsigned long stm32_get_gpio_bank_clock(unsigned int bank);
 uint32_t stm32_get_gpio_bank_offset(unsigned int bank);
 
+/* Print CPU information */
+void stm32mp_print_cpuinfo(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 7de264ba06fab9fd5e97e55967e4fcb715e58099..1926be31373e8c6c298e418fe7256c9fd162448b 100644 (file)
@@ -272,6 +272,8 @@ void bl2_el3_plat_arch_setup(void)
                panic();
        }
 
+       stm32mp_print_cpuinfo();
+
        board_model = dt_get_board_model();
        if (board_model != NULL) {
                NOTICE("Model: %s\n", board_model);
index a878308baf79e8fabb7d75e51cec5281b366d35e..498a4f210c7cc576d6c834189f6f4c8257a7b120 100644 (file)
@@ -7,6 +7,12 @@
 #ifndef STM32MP1_DBGMCU_H
 #define STM32MP1_DBGMCU_H
 
+#include <stdint.h>
+
+/* Get chip version and ID from DBGMCU registers */
+int stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version);
+int stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id);
+
 /*
  * Freeze watchdog when a debugger is attached, if the security configuration
  * allows it.
index a614267db5396d7ae93ac1a837f77845eace0e8f..d0264968c634767a5aab98ce6cab0466caf38b55 100644 (file)
 
 #include <stm32mp1_dbgmcu.h>
 
+#define DBGMCU_IDC             U(0x00)
 #define DBGMCU_APB4FZ1         U(0x2C)
+
+#define DBGMCU_IDC_DEV_ID_MASK GENMASK(11, 0)
+#define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16)
+#define DBGMCU_IDC_REV_ID_SHIFT        16
+
 #define DBGMCU_APB4FZ1_IWDG2   BIT(2)
 
 static uintptr_t get_rcc_base(void)
@@ -47,6 +53,30 @@ static int stm32mp1_dbgmcu_init(void)
        return 0;
 }
 
+int stm32mp1_dbgmcu_get_chip_version(uint32_t *chip_version)
+{
+       if (stm32mp1_dbgmcu_init() != 0) {
+               return -EPERM;
+       }
+
+       *chip_version = (mmio_read_32(DBGMCU_BASE + DBGMCU_IDC) &
+                        DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT;
+
+       return 0;
+}
+
+int stm32mp1_dbgmcu_get_chip_dev_id(uint32_t *chip_dev_id)
+{
+       if (stm32mp1_dbgmcu_init() != 0) {
+               return -EPERM;
+       }
+
+       *chip_dev_id = mmio_read_32(DBGMCU_BASE + DBGMCU_IDC) &
+               DBGMCU_IDC_DEV_ID_MASK;
+
+       return 0;
+}
+
 int stm32mp1_dbgmcu_freeze_iwdg2(void)
 {
        uint32_t dbg_conf;
index 34e6e3cc811d34e9ab3931038f77d65113c20221..6ee58843238d4ed7368a8125f25414be36dc048b 100644 (file)
 #include <stm32mp_common.h>
 #include <stm32mp_dt.h>
 #include <stm32mp_shres_helpers.h>
+#include <stm32mp1_dbgmcu.h>
 #include <stm32mp1_private.h>
 #endif
 
+/*******************************************************************************
+ * CHIP ID
+ ******************************************************************************/
+#define STM32MP157C_PART_NB    U(0x05000000)
+#define STM32MP157A_PART_NB    U(0x05000001)
+#define STM32MP153C_PART_NB    U(0x05000024)
+#define STM32MP153A_PART_NB    U(0x05000025)
+#define STM32MP151C_PART_NB    U(0x0500002E)
+#define STM32MP151A_PART_NB    U(0x0500002F)
+
+#define STM32MP1_REV_B         U(0x2000)
+
+/*******************************************************************************
+ * PACKAGE ID
+ ******************************************************************************/
+#define PKG_AA_LFBGA448                U(4)
+#define PKG_AB_LFBGA354                U(3)
+#define PKG_AC_TFBGA361                U(2)
+#define PKG_AD_TFBGA257                U(1)
+
 /*******************************************************************************
  * STM32MP1 memory map related constants
  ******************************************************************************/
@@ -240,12 +261,22 @@ enum ddr_type {
 
 /* OTP offsets */
 #define DATA0_OTP                      U(0)
+#define PART_NUMBER_OTP                        U(1)
+#define PACKAGE_OTP                    U(16)
 #define HW2_OTP                                U(18)
 
 /* OTP mask */
 /* DATA0 */
 #define DATA0_OTP_SECURED              BIT(6)
 
+/* PART NUMBER */
+#define PART_NUMBER_OTP_PART_MASK      GENMASK_32(7, 0)
+#define PART_NUMBER_OTP_PART_SHIFT     0
+
+/* PACKAGE */
+#define PACKAGE_OTP_PKG_MASK           GENMASK_32(29, 27)
+#define PACKAGE_OTP_PKG_SHIFT          27
+
 /* IWDG OTP */
 #define HW2_OTP_IWDG_HW_POS            U(3)
 #define HW2_OTP_IWDG_FZ_STOP_POS       U(5)
index 886a8f3100b51d1e95f1727ad76f833a72f195a7..08fb815ced8ea8bc7b8e00646414855c4d8da2e4 100644 (file)
@@ -68,6 +68,126 @@ unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
        return GPIOA + (bank - GPIO_BANK_A);
 }
 
+static int get_part_number(uint32_t *part_nb)
+{
+       uint32_t part_number;
+       uint32_t dev_id;
+
+       if (stm32mp1_dbgmcu_get_chip_dev_id(&dev_id) < 0) {
+               return -1;
+       }
+
+       if (bsec_shadow_read_otp(&part_number, PART_NUMBER_OTP) != BSEC_OK) {
+               ERROR("BSEC: PART_NUMBER_OTP Error\n");
+               return -1;
+       }
+
+       part_number = (part_number & PART_NUMBER_OTP_PART_MASK) >>
+               PART_NUMBER_OTP_PART_SHIFT;
+
+       *part_nb = part_number | (dev_id << 16);
+
+       return 0;
+}
+
+static int get_cpu_package(uint32_t *cpu_package)
+{
+       uint32_t package;
+
+       if (bsec_shadow_read_otp(&package, PACKAGE_OTP) != BSEC_OK) {
+               ERROR("BSEC: PACKAGE_OTP Error\n");
+               return -1;
+       }
+
+       *cpu_package = (package & PACKAGE_OTP_PKG_MASK) >>
+               PACKAGE_OTP_PKG_SHIFT;
+
+       return 0;
+}
+
+void stm32mp_print_cpuinfo(void)
+{
+       const char *cpu_s, *cpu_r, *pkg;
+       uint32_t part_number;
+       uint32_t cpu_package;
+       uint32_t chip_dev_id;
+       int ret;
+
+       /* MPUs Part Numbers */
+       ret = get_part_number(&part_number);
+       if (ret < 0) {
+               WARN("Cannot get part number\n");
+               return;
+       }
+
+       switch (part_number) {
+       case STM32MP157C_PART_NB:
+               cpu_s = "157C";
+               break;
+       case STM32MP157A_PART_NB:
+               cpu_s = "157A";
+               break;
+       case STM32MP153C_PART_NB:
+               cpu_s = "153C";
+               break;
+       case STM32MP153A_PART_NB:
+               cpu_s = "153A";
+               break;
+       case STM32MP151C_PART_NB:
+               cpu_s = "151C";
+               break;
+       case STM32MP151A_PART_NB:
+               cpu_s = "151A";
+               break;
+       default:
+               cpu_s = "????";
+               break;
+       }
+
+       /* Package */
+       ret = get_cpu_package(&cpu_package);
+       if (ret < 0) {
+               WARN("Cannot get CPU package\n");
+               return;
+       }
+
+       switch (cpu_package) {
+       case PKG_AA_LFBGA448:
+               pkg = "AA";
+               break;
+       case PKG_AB_LFBGA354:
+               pkg = "AB";
+               break;
+       case PKG_AC_TFBGA361:
+               pkg = "AC";
+               break;
+       case PKG_AD_TFBGA257:
+               pkg = "AD";
+               break;
+       default:
+               pkg = "??";
+               break;
+       }
+
+       /* REVISION */
+       ret = stm32mp1_dbgmcu_get_chip_version(&chip_dev_id);
+       if (ret < 0) {
+               WARN("Cannot get CPU version\n");
+               return;
+       }
+
+       switch (chip_dev_id) {
+       case STM32MP1_REV_B:
+               cpu_r = "B";
+               break;
+       default:
+               cpu_r = "?";
+               break;
+       }
+
+       NOTICE("CPU: STM32MP%s%s Rev.%s\n", cpu_s, pkg, cpu_r);
+}
+
 uint32_t stm32_iwdg_get_instance(uintptr_t base)
 {
        switch (base) {