arm-trusted-firmware/plat/st/stm32mp2/stm32mp2_private.c
Maxime Méré ae84525f44 feat(stm32mp2): manage DDR FW via FIP
This feature is enabled by default using STM32MP_DDR_FIP_IO_STORAGE.

DDR firmware binary is loaded from FIP to SRAM1 which needs to be
mapped.
Only half of the SRAM1 will be allocated to TF-A.
RISAB3 has to be configured to allow access to SRAM1.
Add image ID and update maximum number on platform side also.

Fill related descriptor information, add policy and update numbers.
DDR_TYPE variable is used to identify binary file, and image is now
added in the fiptool command line.

The DDR PHY firmware is not in TF-A repository. It can be found at
https://github.com/STMicroelectronics/stm32-ddr-phy-binary
To ease the selection of the firmware path, STM32MP_DDR_FW_PATH is added
to platform.mk file.

Change-Id: I09ab0a5c63406055a7b5ccd16d65e443de47ca2f
Signed-off-by: Nicolas Le Bayon <nicolas.le.bayon@st.com>
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Maxime Méré <maxime.mere@foss.st.com>
2024-09-13 17:57:58 +02:00

283 lines
4.8 KiB
C

/*
* Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <platform_def.h>
#define BKPR_BOOT_MODE 96U
#if defined(IMAGE_BL31)
/* BL31 only uses the first half of the SYSRAM */
#define MAP_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
STM32MP_SYSRAM_SIZE / 2U, \
MT_MEMORY | \
MT_RW | \
MT_SECURE | \
MT_EXECUTE_NEVER)
#else
#define MAP_SYSRAM MAP_REGION_FLAT(STM32MP_SYSRAM_BASE, \
STM32MP_SYSRAM_SIZE, \
MT_MEMORY | \
MT_RW | \
MT_SECURE | \
MT_EXECUTE_NEVER)
#endif
#if STM32MP_DDR_FIP_IO_STORAGE
#define MAP_SRAM1 MAP_REGION_FLAT(SRAM1_BASE, \
SRAM1_SIZE_FOR_TFA, \
MT_MEMORY | \
MT_RW | \
MT_SECURE | \
MT_EXECUTE_NEVER)
#endif
#define MAP_DEVICE MAP_REGION_FLAT(STM32MP_DEVICE_BASE, \
STM32MP_DEVICE_SIZE, \
MT_DEVICE | \
MT_RW | \
MT_SECURE | \
MT_EXECUTE_NEVER)
#if defined(IMAGE_BL2)
static const mmap_region_t stm32mp2_mmap[] = {
MAP_SYSRAM,
#if STM32MP_DDR_FIP_IO_STORAGE
MAP_SRAM1,
#endif
MAP_DEVICE,
{0}
};
#endif
#if defined(IMAGE_BL31)
static const mmap_region_t stm32mp2_mmap[] = {
MAP_SYSRAM,
MAP_DEVICE,
{0}
};
#endif
void configure_mmu(void)
{
mmap_add(stm32mp2_mmap);
init_xlat_tables();
enable_mmu_el3(0);
}
uintptr_t stm32_get_gpio_bank_base(unsigned int bank)
{
if (bank == GPIO_BANK_Z) {
return GPIOZ_BASE;
}
assert(bank <= GPIO_BANK_K);
return GPIOA_BASE + (bank * GPIO_BANK_OFFSET);
}
uint32_t stm32_get_gpio_bank_offset(unsigned int bank)
{
if (bank == GPIO_BANK_Z) {
return 0;
}
assert(bank <= GPIO_BANK_K);
return bank * GPIO_BANK_OFFSET;
}
unsigned long stm32_get_gpio_bank_clock(unsigned int bank)
{
if (bank == GPIO_BANK_Z) {
return CK_BUS_GPIOZ;
}
assert(bank <= GPIO_BANK_K);
return CK_BUS_GPIOA + (bank - GPIO_BANK_A);
}
uint32_t stm32mp_get_chip_version(void)
{
static uint32_t rev;
if (rev != 0U) {
return rev;
}
if (stm32_get_otp_value(REVISION_OTP, &rev) != 0) {
panic();
}
return rev;
}
uint32_t stm32mp_get_chip_dev_id(void)
{
return stm32mp_syscfg_get_chip_dev_id();
}
static uint32_t get_part_number(void)
{
static uint32_t part_number;
if (part_number != 0U) {
return part_number;
}
if (stm32_get_otp_value(PART_NUMBER_OTP, &part_number) != 0) {
panic();
}
return part_number;
}
static uint32_t get_cpu_package(void)
{
static uint32_t package = UINT32_MAX;
if (package == UINT32_MAX) {
if (stm32_get_otp_value(PACKAGE_OTP, &package) != 0) {
panic();
}
}
return (package & PACKAGE_OTP_PKG_MASK) >> PACKAGE_OTP_PKG_SHIFT;
}
void stm32mp_get_soc_name(char name[STM32_SOC_NAME_SIZE])
{
char *cpu_s, *cpu_r, *pkg;
/* MPUs Part Numbers */
switch (get_part_number()) {
case STM32MP251A_PART_NB:
cpu_s = "251A";
break;
case STM32MP251C_PART_NB:
cpu_s = "251C";
break;
case STM32MP251D_PART_NB:
cpu_s = "251D";
break;
case STM32MP251F_PART_NB:
cpu_s = "251F";
break;
case STM32MP253A_PART_NB:
cpu_s = "253A";
break;
case STM32MP253C_PART_NB:
cpu_s = "253C";
break;
case STM32MP253D_PART_NB:
cpu_s = "253D";
break;
case STM32MP253F_PART_NB:
cpu_s = "253F";
break;
case STM32MP255A_PART_NB:
cpu_s = "255A";
break;
case STM32MP255C_PART_NB:
cpu_s = "255C";
break;
case STM32MP255D_PART_NB:
cpu_s = "255D";
break;
case STM32MP255F_PART_NB:
cpu_s = "255F";
break;
case STM32MP257A_PART_NB:
cpu_s = "257A";
break;
case STM32MP257C_PART_NB:
cpu_s = "257C";
break;
case STM32MP257D_PART_NB:
cpu_s = "257D";
break;
case STM32MP257F_PART_NB:
cpu_s = "257F";
break;
default:
cpu_s = "????";
break;
}
/* Package */
switch (get_cpu_package()) {
case STM32MP25_PKG_CUSTOM:
pkg = "XX";
break;
case STM32MP25_PKG_AL_VFBGA361:
pkg = "AL";
break;
case STM32MP25_PKG_AK_VFBGA424:
pkg = "AK";
break;
case STM32MP25_PKG_AI_TFBGA436:
pkg = "AI";
break;
default:
pkg = "??";
break;
}
/* REVISION */
switch (stm32mp_get_chip_version()) {
case STM32MP2_REV_A:
cpu_r = "A";
break;
case STM32MP2_REV_B:
cpu_r = "B";
break;
case STM32MP2_REV_X:
cpu_r = "X";
break;
case STM32MP2_REV_Y:
cpu_r = "Y";
break;
case STM32MP2_REV_Z:
cpu_r = "Z";
break;
default:
cpu_r = "?";
break;
}
snprintf(name, STM32_SOC_NAME_SIZE,
"STM32MP%s%s Rev.%s", cpu_s, pkg, cpu_r);
}
void stm32mp_print_cpuinfo(void)
{
char name[STM32_SOC_NAME_SIZE];
stm32mp_get_soc_name(name);
NOTICE("CPU: %s\n", name);
}
void stm32mp_print_boardinfo(void)
{
uint32_t board_id = 0U;
if (stm32_get_otp_value(BOARD_ID_OTP, &board_id) != 0) {
return;
}
if (board_id != 0U) {
stm32_display_board_info(board_id);
}
}
uintptr_t stm32_get_bkpr_boot_mode_addr(void)
{
return tamp_bkpr(BKPR_BOOT_MODE);
}