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>
diff --git a/docs/plat/st/stm32mp2.rst b/docs/plat/st/stm32mp2.rst
index 5d4ab4e..87bb6a5 100644
--- a/docs/plat/st/stm32mp2.rst
+++ b/docs/plat/st/stm32mp2.rst
@@ -85,7 +85,8 @@
Boot with FIP
~~~~~~~~~~~~~
-You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) before building FIP binary.
+You need to build BL2, BL31, BL32 (OP-TEE) and BL33 (U-Boot) and retrieve
+DDR PHY firmware before building FIP binary.
U-Boot
______
@@ -106,9 +107,24 @@
ARCH=arm PLATFORM=stm32mp2 \
CFG_EMBED_DTB_SOURCE_FILE=stm32mp257f-ev1.dts
-TF-A BL2 & BL31
-_______________
-To build TF-A BL2 with its STM32 header and BL31 for SD-card boot:
+DDR PHY firmware
+________________
+DDR PHY firmware files may not be delivered inside TF-A repository, especially
+if you build directly from trustedfirmware.org repository. It then needs to be
+retrieved from `STMicroelectronics DDR PHY github`_.
+
+You can either clone the repository to the default directory:
+
+.. code:: bash
+
+ git clone https://github.com/STMicroelectronics/stm32-ddr-phy-binary.git drivers/st/ddr/phy/firmware/bin
+
+Or clone it somewhere else, and add ``STM32MP_DDR_FW_PATH=`` in your make command
+line when building FIP.
+
+TF-A BL2
+________
+To build TF-A BL2 with its STM32 header for SD-card boot:
.. code:: bash
@@ -136,5 +152,6 @@
.. _STM32MP2 Series: https://www.st.com/en/microcontrollers-microprocessors/stm32mp2-series.html
.. _STM32MP2 part number codification: https://wiki.st.com/stm32mpu/wiki/STM32MP25_microprocessor#Part_number_codification
+.. _STMicroelectronics DDR PHY github: https://github.com/STMicroelectronics/stm32-ddr-phy-binary
*Copyright (c) 2023-2024, STMicroelectronics - All Rights Reserved*
diff --git a/fdts/stm32mp25-bl2.dtsi b/fdts/stm32mp25-bl2.dtsi
index 769aab2..e250e3f 100644
--- a/fdts/stm32mp25-bl2.dtsi
+++ b/fdts/stm32mp25-bl2.dtsi
@@ -21,6 +21,9 @@
st-io_policies {
fip-handles {
compatible = "st,io-fip-handle";
+#if STM32MP_DDR_FIP_IO_STORAGE
+ ddr_fw_uuid = "b11249be-92dd-4b10-867c-2c6a4b47a7fb";
+#endif
fw_cfg_uuid = "5807e16a-8459-47be-8ed5-648e8dddab0e";
bl31_uuid = "47d4086d-4cfe-9846-9b95-2950cbbd5a00";
bl32_uuid = "05d0e189-53dc-1347-8d2b-500a4b7a3e38";
diff --git a/plat/st/common/stm32mp_fconf_io.c b/plat/st/common/stm32mp_fconf_io.c
index 7a8cf78..1aecece 100644
--- a/plat/st/common/stm32mp_fconf_io.c
+++ b/plat/st/common/stm32mp_fconf_io.c
@@ -88,9 +88,16 @@
#define TBBR_UUID_NUMBER U(0)
#endif
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define DDR_FW_UUID_NUMBER U(1)
+#else
+#define DDR_FW_UUID_NUMBER U(0)
+#endif
+
#define FCONF_ST_IO_UUID_NUMBER (DEFAULT_UUID_NUMBER + \
BL31_UUID_NUMBER + \
- TBBR_UUID_NUMBER)
+ TBBR_UUID_NUMBER + \
+ DDR_FW_UUID_NUMBER)
static io_uuid_spec_t fconf_stm32mp_uuids[FCONF_ST_IO_UUID_NUMBER];
static OBJECT_POOL_ARRAY(fconf_stm32mp_uuids_pool, fconf_stm32mp_uuids);
@@ -102,6 +109,9 @@
/* image id to property name table */
static const struct policies_load_info load_info[FCONF_ST_IO_UUID_NUMBER] = {
+#if STM32MP_DDR_FIP_IO_STORAGE
+ {DDR_FW_ID, "ddr_fw_uuid"},
+#endif
{FW_CONFIG_ID, "fw_cfg_uuid"},
#ifdef __aarch64__
{BL31_IMAGE_ID, "bl31_uuid"},
diff --git a/plat/st/stm32mp2/bl2_plat_setup.c b/plat/st/stm32mp2/bl2_plat_setup.c
index 7fcaf85..50d19ab 100644
--- a/plat/st/stm32mp2/bl2_plat_setup.c
+++ b/plat/st/stm32mp2/bl2_plat_setup.c
@@ -15,6 +15,7 @@
#include <drivers/mmc.h>
#include <drivers/st/regulator_fixed.h>
#include <drivers/st/stm32mp2_ddr_helpers.h>
+#include <drivers/st/stm32mp_risab_regs.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_dyn_cfg_getter.h>
#include <lib/mmio.h>
@@ -196,6 +197,17 @@
panic();
}
+#if STM32MP_DDR_FIP_IO_STORAGE
+ /*
+ * RISAB3 setup (dedicated for SRAM1)
+ *
+ * Allow secure read/writes data accesses to non-secure
+ * blocks or pages, all RISAB registers are writable.
+ * DDR firmwares are saved there before being loaded in DDRPHY memory.
+ */
+ mmio_write_32(RISAB3_BASE + RISAB_CR, RISAB_CR_SRWIAD);
+#endif
+
stm32_save_boot_info(boot_context);
if (stm32mp_uart_console_setup() != 0) {
diff --git a/plat/st/stm32mp2/include/plat_tbbr_img_def.h b/plat/st/stm32mp2/include/plat_tbbr_img_def.h
index 5dfd41f..830bf88 100644
--- a/plat/st/stm32mp2/include/plat_tbbr_img_def.h
+++ b/plat/st/stm32mp2/include/plat_tbbr_img_def.h
@@ -40,8 +40,16 @@
#define STM32MP_CONFIG_CERT_ID U(24)
#define GPT_IMAGE_ID U(25)
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define DDR_FW_ID U(26)
+/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
+#define MAX_NUMBER_IDS U(27)
+
+#else
/* Increase the MAX_NUMBER_IDS to match the authentication pool required */
#define MAX_NUMBER_IDS U(26)
+#endif
+
#endif /* PLAT_TBBR_IMG_DEF_H */
diff --git a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
index 137ea63..f845560 100644
--- a/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp2/plat_bl2_mem_params_desc.c
@@ -19,6 +19,24 @@
* the next executable image id.
******************************************************************************/
static bl_mem_params_node_t bl2_mem_params_descs[] = {
+#if STM32MP_DDR_FIP_IO_STORAGE
+ /* Fill FW_DDR related information if it exists */
+ {
+ .image_id = DDR_FW_ID,
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+ VERSION_2, image_info_t,
+ 0),
+
+ .image_info.image_base = STM32MP_DDR_FW_BASE,
+ .image_info.image_max_size = STM32MP_DDR_FW_MAX_SIZE,
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+#endif
+
/* Fill FW_CONFIG related information if it exists */
{
.image_id = FW_CONFIG_ID,
diff --git a/plat/st/stm32mp2/platform.mk b/plat/st/stm32mp2/platform.mk
index 015b205..32d6235 100644
--- a/plat/st/stm32mp2/platform.mk
+++ b/plat/st/stm32mp2/platform.mk
@@ -41,6 +41,9 @@
DDR_TYPE := lpddr4
endif
+# DDR features
+STM32MP_DDR_FIP_IO_STORAGE := 1
+
# Device tree
BL2_DTSI := stm32mp25-bl2.dtsi
FDT_SOURCES := $(addprefix ${BUILD_PLAT}/fdts/, $(patsubst %.dtb,%-bl2.dts,$(DTB_FILE_NAME)))
@@ -52,13 +55,23 @@
STM32MP_FW_CONFIG_NAME := $(patsubst %.dtb,%-fw-config.dtb,$(DTB_FILE_NAME))
STM32MP_FW_CONFIG := ${BUILD_PLAT}/fdts/$(STM32MP_FW_CONFIG_NAME)
+ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
+STM32MP_DDR_FW_PATH ?= drivers/st/ddr/phy/firmware/bin/stm32mp2
+STM32MP_DDR_FW_NAME := ${DDR_TYPE}_pmu_train.bin
+STM32MP_DDR_FW := ${STM32MP_DDR_FW_PATH}/${STM32MP_DDR_FW_NAME}
+endif
FDT_SOURCES += $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32MP_FW_CONFIG_NAME)))
# Add the FW_CONFIG to FIP and specify the same to certtool
$(eval $(call TOOL_ADD_PAYLOAD,${STM32MP_FW_CONFIG},--fw-config))
+ifeq (${STM32MP_DDR_FIP_IO_STORAGE},1)
+# Add the FW_DDR to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_IMG,STM32MP_DDR_FW,--ddr-fw))
+endif
# Enable flags for C files
$(eval $(call assert_booleans,\
$(sort \
+ STM32MP_DDR_FIP_IO_STORAGE \
STM32MP_DDR3_TYPE \
STM32MP_DDR4_TYPE \
STM32MP_LPDDR4_TYPE \
@@ -75,9 +88,11 @@
$(eval $(call add_defines,\
$(sort \
DWL_BUFFER_BASE \
+ PLAT_DEF_FIP_UUID \
PLAT_PARTITION_MAX_ENTRIES \
PLAT_TBBR_IMG_DEF \
STM32_TF_A_COPIES \
+ STM32MP_DDR_FIP_IO_STORAGE \
STM32MP_DDR3_TYPE \
STM32MP_DDR4_TYPE \
STM32MP_LPDDR4_TYPE \
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 058616b..d3290c3 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -71,6 +71,8 @@
******************************************************************************/
#define STM32MP_SYSRAM_BASE U(0x0E000000)
#define STM32MP_SYSRAM_SIZE U(0x00040000)
+#define SRAM1_BASE U(0x0E040000)
+#define SRAM1_SIZE_FOR_TFA U(0x00010000)
#define STM32MP_SEC_SYSRAM_SIZE STM32MP_SYSRAM_SIZE
/* DDR configuration */
@@ -144,6 +146,11 @@
#define STM32MP_DTB_BASE STM32MP_BL2_DTB_BASE
#endif
+#if STM32MP_DDR_FIP_IO_STORAGE
+#define STM32MP_DDR_FW_BASE SRAM1_BASE
+#define STM32MP_DDR_FW_MAX_SIZE U(0x8800)
+#endif
+
#define STM32MP_FW_CONFIG_MAX_SIZE PAGE_SIZE
#define STM32MP_FW_CONFIG_BASE STM32MP_SYSRAM_BASE
@@ -364,6 +371,11 @@
#define SYSCFG_BASE U(0x44230000)
/*******************************************************************************
+ * STM32MP RIF
+ ******************************************************************************/
+#define RISAB3_BASE U(0x42110000)
+
+/*******************************************************************************
* STM32MP CA35SSC
******************************************************************************/
#define A35SSC_BASE U(0x48800000)
diff --git a/plat/st/stm32mp2/stm32mp2_private.c b/plat/st/stm32mp2/stm32mp2_private.c
index 06ff7c8..99f6be2 100644
--- a/plat/st/stm32mp2/stm32mp2_private.c
+++ b/plat/st/stm32mp2/stm32mp2_private.c
@@ -29,6 +29,15 @@
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 | \
@@ -39,6 +48,9 @@
#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}
};