stm32mp1: print information about SoC

This information is located in DBGMCU registers.

Change-Id: I480aa046fed9992e3d9665b1f0520bc4b6cfdf30
Signed-off-by: Yann Gautier <yann.gautier@st.com>
This commit is contained in:
Yann Gautier 2019-06-04 18:02:37 +02:00
parent 73680c230f
commit dec286dd7d
6 changed files with 192 additions and 0 deletions

View 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

View 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);

View 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.

View File

@ -16,7 +16,13 @@
#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;

View File

@ -22,9 +22,30 @@
#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)

View 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) {