[PATCH 5/9] ARM: Layerscape: LS1046a: add TF-A support
Sascha Hauer
s.hauer at pengutronix.de
Mon Oct 21 00:21:19 PDT 2024
Right now we still use PPA on LS1046a. This has long been deprecated and
replaced with TF-A. Add support for starting the TF-A on LS1046a based
boards as a first step to get rid of PPA.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
arch/arm/boards/ls1046ardb/lowlevel.c | 2 +-
arch/arm/boards/tqmls1046a/lowlevel.c | 2 +-
arch/arm/mach-layerscape/Kconfig | 2 ++
arch/arm/mach-layerscape/Makefile | 1 +
arch/arm/mach-layerscape/tfa.c | 29 +++++++++++++++++++++++++++++
arch/arm/mach-layerscape/xload-qspi.c | 12 ++++++++----
arch/arm/mach-layerscape/xload.c | 6 +++---
drivers/mci/imx-esdhc-pbl.c | 5 ++++-
firmware/Kconfig | 3 +++
firmware/Makefile | 1 +
include/mach/layerscape/xload.h | 8 +++++---
11 files changed, 58 insertions(+), 13 deletions(-)
diff --git a/arch/arm/boards/ls1046ardb/lowlevel.c b/arch/arm/boards/ls1046ardb/lowlevel.c
index 753fca3272..bcc95cc59d 100644
--- a/arch/arm/boards/ls1046ardb/lowlevel.c
+++ b/arch/arm/boards/ls1046ardb/lowlevel.c
@@ -210,7 +210,7 @@ static noinline __noreturn void ls1046ardb_r_entry(void)
ls1046a_errata_post_ddr();
- ls1046a_esdhc_start_image();
+ ls1046a_esdhc_start_image(NULL);
err:
pr_err("Booting failed\n");
diff --git a/arch/arm/boards/tqmls1046a/lowlevel.c b/arch/arm/boards/tqmls1046a/lowlevel.c
index 6531b22bd1..5ccafb2d77 100644
--- a/arch/arm/boards/tqmls1046a/lowlevel.c
+++ b/arch/arm/boards/tqmls1046a/lowlevel.c
@@ -331,7 +331,7 @@ static noinline __noreturn void tqmls1046a_r_entry(bool is_8g)
ls1046a_errata_post_ddr();
- ls1046a_xload_start_image();
+ ls1046a_xload_start_image(NULL);
pr_err("Booting failed\n");
diff --git a/arch/arm/mach-layerscape/Kconfig b/arch/arm/mach-layerscape/Kconfig
index 5658a63b33..9d15ba0173 100644
--- a/arch/arm/mach-layerscape/Kconfig
+++ b/arch/arm/mach-layerscape/Kconfig
@@ -24,6 +24,7 @@ config ARCH_LS1028
config ARCH_LS1046
bool
select CPU_V8
+ select ARM_ATF
select SYS_SUPPORTS_64BIT_KERNEL
if 64BIT
@@ -47,6 +48,7 @@ config MACH_TQMLS1046A
select MCI_IMX_ESDHC_PBL
select DDR_FSL
select DDR_FSL_DDR4
+ select FIRMWARE_LS1046A_ATF
endif
diff --git a/arch/arm/mach-layerscape/Makefile b/arch/arm/mach-layerscape/Makefile
index e4bb1b42f2..ee7df5ea19 100644
--- a/arch/arm/mach-layerscape/Makefile
+++ b/arch/arm/mach-layerscape/Makefile
@@ -14,3 +14,4 @@ lwl-$(CONFIG_ARCH_LS1021) += lowlevel-ls102xa.o
obj-$(CONFIG_ARCH_LS1021) += restart.o ls102xa_stream_id.o
lwl-$(CONFIG_ARCH_LS1028) += lowlevel-ls1028a.o
+pbl-$(CONFIG_FIRMWARE_LS1046A_ATF) += tfa.o
diff --git a/arch/arm/mach-layerscape/tfa.c b/arch/arm/mach-layerscape/tfa.c
new file mode 100644
index 0000000000..c8a8c8bf1d
--- /dev/null
+++ b/arch/arm/mach-layerscape/tfa.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <firmware.h>
+#include <asm/atf_common.h>
+#include <asm/cache.h>
+#include <mach/layerscape/layerscape.h>
+#include <mach/layerscape/xload.h>
+
+void ls1046_start_tfa(void *barebox, struct dram_regions_info *dram_info)
+{
+ void (*bl31)(void) = (void *)0xfbe00000;
+ size_t bl31_size;
+ void *bl31_image;
+ struct bl2_to_bl31_params_mem_v2 *params;
+
+ get_builtin_firmware_ext(ls1046a_bl31_bin, barebox, &bl31_image, &bl31_size);
+ memcpy(bl31, bl31_image, bl31_size);
+
+ sync_caches_for_execution();
+
+ /* Setup an initial stack for EL2 */
+ asm volatile("msr sp_el2, %0" : : "r" ((unsigned long)barebox - 16) : "cc");
+
+ params = bl2_plat_get_bl31_params_v2(0, (uintptr_t)barebox, 0);
+ params->bl31_ep_info.args.arg3 = (unsigned long)dram_info;
+
+ printf("Starting bl31\n");
+
+ bl31_entry_v2((uintptr_t)bl31, ¶ms->bl_params, NULL);
+}
diff --git a/arch/arm/mach-layerscape/xload-qspi.c b/arch/arm/mach-layerscape/xload-qspi.c
index 11119840c3..fa5b699d4a 100644
--- a/arch/arm/mach-layerscape/xload-qspi.c
+++ b/arch/arm/mach-layerscape/xload-qspi.c
@@ -19,7 +19,8 @@ struct layerscape_base_addr {
void *qspi_mem_base;
};
-static int layerscape_qspi_start_image(struct layerscape_base_addr *base)
+static int layerscape_qspi_start_image(struct layerscape_base_addr *base,
+ struct dram_regions_info *dram_info)
{
void (*barebox)(void) = base->membase;
@@ -28,6 +29,9 @@ static int layerscape_qspi_start_image(struct layerscape_base_addr *base)
memcpy(base->membase, base->qspi_mem_base + BAREBOX_START, barebox_image_size);
+ if (IS_ENABLED(CONFIG_FIRMWARE_LS1046A_ATF))
+ ls1046_start_tfa(base->membase, dram_info);
+
sync_caches_for_execution();
printf("Starting barebox\n");
@@ -39,7 +43,7 @@ static int layerscape_qspi_start_image(struct layerscape_base_addr *base)
return -EIO;
}
-int ls1046a_qspi_start_image(void)
+int ls1046a_qspi_start_image(struct dram_regions_info *dram_info)
{
struct layerscape_base_addr base;
@@ -47,7 +51,7 @@ int ls1046a_qspi_start_image(void)
base.membase = IOMEM(LS1046A_DDR_SDRAM_BASE);
base.qspi_mem_base = IOMEM(0x40000000);
- return layerscape_qspi_start_image(&base);
+ return layerscape_qspi_start_image(&base, dram_info);
}
int ls1021a_qspi_start_image(void)
@@ -58,5 +62,5 @@ int ls1021a_qspi_start_image(void)
base.membase = IOMEM(LS1021A_DDR_SDRAM_BASE);
base.qspi_mem_base = IOMEM(0x40000000);
- return layerscape_qspi_start_image(&base);
+ return layerscape_qspi_start_image(&base, NULL);
}
diff --git a/arch/arm/mach-layerscape/xload.c b/arch/arm/mach-layerscape/xload.c
index 9103e8b4bc..cbdf14344e 100644
--- a/arch/arm/mach-layerscape/xload.c
+++ b/arch/arm/mach-layerscape/xload.c
@@ -5,7 +5,7 @@
#include <mach/layerscape/layerscape.h>
#include <mach/layerscape/xload.h>
-int ls1046a_xload_start_image(void)
+int ls1046a_xload_start_image(struct dram_regions_info *dram_info)
{
enum bootsource src;
@@ -13,10 +13,10 @@ int ls1046a_xload_start_image(void)
switch (src) {
case BOOTSOURCE_SPI_NOR:
- return ls1046a_qspi_start_image();
+ return ls1046a_qspi_start_image(dram_info);
#if defined(CONFIG_MCI_IMX_ESDHC_PBL)
case BOOTSOURCE_MMC:
- return ls1046a_esdhc_start_image();
+ return ls1046a_esdhc_start_image(dram_info);
#endif
default:
pr_err("Unknown bootsource\n");
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 3bf3a7ace6..0e4b6114fd 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -352,7 +352,7 @@ static int layerscape_esdhc_load_image(struct fsl_esdhc_host *host, void *adr, u
* Return: If successful, this function does not return. A negative error
* code is returned when this function fails.
*/
-int ls1046a_esdhc_start_image(void)
+int ls1046a_esdhc_start_image(struct dram_regions_info *dram_info)
{
int ret;
struct esdhc_soc_data data = {
@@ -370,6 +370,9 @@ int ls1046a_esdhc_start_image(void)
if (ret)
return ret;
+ if (IS_ENABLED(CONFIG_FIRMWARE_LS1046A_ATF))
+ ls1046_start_tfa(barebox, dram_info);
+
printf("Starting barebox\n");
barebox();
diff --git a/firmware/Kconfig b/firmware/Kconfig
index ae7bbdc71e..d068e6d983 100644
--- a/firmware/Kconfig
+++ b/firmware/Kconfig
@@ -98,4 +98,7 @@ config FIRMWARE_CCBV2_OPTEE
config FIRMWARE_LS1028A_ATF
bool
+config FIRMWARE_LS1046A_ATF
+ bool
+
endmenu
diff --git a/firmware/Makefile b/firmware/Makefile
index 7265c55c42..9351e24e86 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -33,6 +33,7 @@ firmware-$(CONFIG_DRIVER_NET_FSL_FMAN) += fsl_fman_ucode_ls1046_r1.0_106_4_18.bi
firmware-$(CONFIG_ARCH_LAYERSCAPE_PPA) += ppa-ls1046a.bin
fw-external-$(CONFIG_FIRMWARE_LS1028A_ATF) += ls1028a-bl31.bin
+fw-external-$(CONFIG_FIRMWARE_LS1046A_ATF) += ls1046a-bl31.bin
pbl-firmware-$(CONFIG_FIRMWARE_CCBV2_OPTEE) += ccbv2_optee.bin
pbl-firmware-$(CONFIG_FIRMWARE_TQMA6UL_OPTEE) += mba6ul_optee.bin
diff --git a/include/mach/layerscape/xload.h b/include/mach/layerscape/xload.h
index 64990e2ca1..74f095d789 100644
--- a/include/mach/layerscape/xload.h
+++ b/include/mach/layerscape/xload.h
@@ -5,12 +5,14 @@
struct dram_regions_info;
-int ls1046a_esdhc_start_image(void);
+int ls1046a_esdhc_start_image(struct dram_regions_info *dram_info);
int ls1028a_esdhc1_start_image(struct dram_regions_info *dram_info);
int ls1028a_esdhc2_start_image(struct dram_regions_info *dram_info);
-int ls1046a_qspi_start_image(void);
+int ls1046a_qspi_start_image(struct dram_regions_info *dram_info);
int ls1021a_qspi_start_image(void);
-int ls1046a_xload_start_image(void);
+int ls1046a_xload_start_image(struct dram_regions_info *dram_info);
int ls1021a_xload_start_image(void);
+void ls1046_start_tfa(void *barebox, struct dram_regions_info *dram_info);
+
#endif /* __MACH_LAYERSCAPE_XLOAD_H */
--
2.39.5
More information about the barebox
mailing list