[PATCH] arm64: versal2: Read and show multiboot value

Michal Simek michal.simek at amd.com
Thu Nov 27 09:28:46 CET 2025


SOC can boot from different boot medias and also different offsets that's
why by default show multiboot value to be aware which image system is
booting out of. It is especially useful for systems with A/B update
enabled.
Also limit zynqmp_pm_get_pmc_multi_boot_reg() usage only for Versal and
Versal Gen 2.

Signed-off-by: Michal Simek <michal.simek at amd.com>
---

 arch/arm/mach-versal2/include/mach/hardware.h |  4 +++-
 board/amd/versal2/board.c                     | 22 +++++++++++++++++++
 drivers/firmware/firmware-zynqmp.c            |  2 ++
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-versal2/include/mach/hardware.h b/arch/arm/mach-versal2/include/mach/hardware.h
index 7ca2bbb7550f..81a0df893574 100644
--- a/arch/arm/mach-versal2/include/mach/hardware.h
+++ b/arch/arm/mach-versal2/include/mach/hardware.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (C) 2016 - 2022, Xilinx, Inc.
- * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc.
+ * Copyright (C) 2022 - 2025, Advanced Micro Devices, Inc.
  */
 
 #ifndef __ASSEMBLY__
@@ -73,6 +73,8 @@ struct crp_regs {
 #define JTAG_MODE	0x00000000
 #define BOOT_MODE_USE_ALT	0x100
 #define BOOT_MODE_ALT_SHIFT	12
+#define PMC_MULTI_BOOT_REG	0xF1110004
+#define PMC_MULTI_BOOT_MASK	0x1FFF
 
 enum versal2_platform {
 	VERSAL2_SILICON = 0,
diff --git a/board/amd/versal2/board.c b/board/amd/versal2/board.c
index 7d91d288d2ed..1fd05a1157ab 100644
--- a/board/amd/versal2/board.c
+++ b/board/amd/versal2/board.c
@@ -21,6 +21,7 @@
 #include <dm/device.h>
 #include <dm/uclass.h>
 #include <versalpl.h>
+#include <zynqmp_firmware.h>
 #include "../../xilinx/common/board.h"
 
 #include <linux/bitfield.h>
@@ -180,6 +181,23 @@ static u8 versal2_get_bootmode(void)
 	return bootmode;
 }
 
+static u32 versal2_multi_boot(void)
+{
+	u8 bootmode = versal2_get_bootmode();
+	u32 reg = 0;
+
+	/* Mostly workaround for QEMU CI pipeline */
+	if (bootmode == JTAG_MODE)
+		return 0;
+
+	if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE) && current_el() != 3)
+		reg = zynqmp_pm_get_pmc_multi_boot_reg();
+	else
+		reg = readl(PMC_MULTI_BOOT_REG);
+
+	return reg & PMC_MULTI_BOOT_MASK;
+}
+
 static int boot_targets_setup(void)
 {
 	u8 bootmode;
@@ -319,6 +337,7 @@ static int boot_targets_setup(void)
 int board_late_init(void)
 {
 	int ret;
+	u32 multiboot;
 
 	if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
 		debug("Saved variables - Skipping\n");
@@ -328,6 +347,9 @@ int board_late_init(void)
 	if (!IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG))
 		return 0;
 
+	multiboot = versal2_multi_boot();
+	env_set_hex("multiboot", multiboot);
+
 	if (IS_ENABLED(CONFIG_DISTRO_DEFAULTS)) {
 		ret = boot_targets_setup();
 		if (ret)
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index 2ef499bf4084..f8a9945c1daa 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -248,6 +248,7 @@ u32 zynqmp_pm_get_bootmode_reg(void)
 	return ret_payload[1];
 }
 
+#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL2)
 u32 zynqmp_pm_get_pmc_multi_boot_reg(void)
 {
 	int ret;
@@ -271,6 +272,7 @@ u32 zynqmp_pm_get_pmc_multi_boot_reg(void)
 
 	return ret_payload[1];
 }
+#endif
 
 int zynqmp_pm_feature(const u32 api_id)
 {
-- 
2.43.0

base-commit: 3fd0641a164a4d628fdf28a94771829f3bf9cb0c
branch: debian-sent3


More information about the U-Boot mailing list