summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Simek <[email protected]>2026-06-23 14:53:27 +0200
committerMichal Simek <[email protected]>2026-07-08 08:55:51 +0200
commitda4783f7835630141d684369518141d1b0e86fe1 (patch)
tree90e6698ebd67c4e47edd4f31e5dfbe1891b21381
parent5979d3d44e5fe1e4f8827b585b92a0c17532edd9 (diff)
arm64: versal2: Decouple multiboot register access from firmware
versal2_multi_boot() in board code selected between the firmware call zynqmp_pm_get_pmc_multi_boot_reg() and a direct readl() based on an IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE) check. Generic board code should not carry firmware-specific ifdefs, and this becomes harder to maintain once SCMI introduces yet another access method. Introduce an overridable accessor versal2_pmc_multi_boot(). The weak default lives in arch/arm/mach-versal2 and performs the plain MMIO read (used at EL3 and when no firmware is present). When CONFIG_ZYNQMP_FIRMWARE is enabled, firmware-zynqmp.c provides a strong definition that issues the firmware call, falling back to the direct read at EL3 where the SMC path to firmware is unavailable. The shared MMIO read is factored into versal2_multi_boot_reg() so the firmware override does not duplicate it. versal2_multi_boot() keeps the generic JTAG/QEMU workaround and simply calls the accessor, so board code no longer references the firmware interface and the now unused zynqmp_firmware.h include is dropped. The firmware-vs-MMIO decision is selected at link time, and adding SCMI later only requires a third strong definition with no board-code changes. Signed-off-by: Michal Simek <[email protected]> Link: https://patch.msgid.link/0033a1fa8efb4ae0c3ac6a6f5c5c1b4e0f22f02c.1782219202.git.michal.simek@amd.com
-rw-r--r--arch/arm/mach-versal2/cpu.c10
-rw-r--r--arch/arm/mach-versal2/include/mach/sys_proto.h5
-rw-r--r--board/amd/versal2/board.c9
-rw-r--r--drivers/firmware/firmware-zynqmp.c13
4 files changed, 29 insertions, 8 deletions
diff --git a/arch/arm/mach-versal2/cpu.c b/arch/arm/mach-versal2/cpu.c
index d66109abd78..9991d6bbab0 100644
--- a/arch/arm/mach-versal2/cpu.c
+++ b/arch/arm/mach-versal2/cpu.c
@@ -127,6 +127,16 @@ u64 get_page_table_size(void)
}
#endif
+u32 versal2_multi_boot_reg(void)
+{
+ return readl(PMC_MULTI_BOOT_REG) & PMC_MULTI_BOOT_MASK;
+}
+
+u32 __weak versal2_pmc_multi_boot(void)
+{
+ return versal2_multi_boot_reg();
+}
+
U_BOOT_DRVINFO(soc_amd_versal2) = {
.name = "soc_amd_versal2",
};
diff --git a/arch/arm/mach-versal2/include/mach/sys_proto.h b/arch/arm/mach-versal2/include/mach/sys_proto.h
index 3ed0b25be80..e0576754836 100644
--- a/arch/arm/mach-versal2/include/mach/sys_proto.h
+++ b/arch/arm/mach-versal2/include/mach/sys_proto.h
@@ -13,4 +13,9 @@
void mem_map_fill(struct mm_region *bank_info, u32 num_banks);
void fill_bd_mem_info(void);
+/* Overridable PMC multiboot accessor: weak MMIO default, firmware override */
+u32 versal2_pmc_multi_boot(void);
+/* Direct MMIO read of the multiboot register (EL3 / no-firmware path) */
+u32 versal2_multi_boot_reg(void);
+
#endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/board/amd/versal2/board.c b/board/amd/versal2/board.c
index 6e4f0c6e9b8..06d144db4f0 100644
--- a/board/amd/versal2/board.c
+++ b/board/amd/versal2/board.c
@@ -29,7 +29,6 @@
#include <dm/device.h>
#include <dm/uclass.h>
#include <versalpl.h>
-#include <zynqmp_firmware.h>
#include "../../xilinx/common/board.h"
#include <linux/bitfield.h>
@@ -195,18 +194,12 @@ static u8 versal2_get_bootmode(void)
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;
+ return versal2_pmc_multi_boot();
}
static int boot_targets_setup(void)
diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c
index ea14ed4ef95..70d205ff3ef 100644
--- a/drivers/firmware/firmware-zynqmp.c
+++ b/drivers/firmware/firmware-zynqmp.c
@@ -7,6 +7,7 @@
*/
#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
#include <asm/io.h>
#include <cpu_func.h>
#include <dm.h>
@@ -16,6 +17,7 @@
#include <zynqmp_firmware.h>
#include <asm/cache.h>
#include <asm/ptrace.h>
+#include <asm/system.h>
#include <linux/bitfield.h>
#if defined(CONFIG_ZYNQMP_IPI)
@@ -326,6 +328,17 @@ u32 zynqmp_pm_get_pmc_multi_boot_reg(void)
}
#endif
+#if defined(CONFIG_ARCH_VERSAL2)
+u32 versal2_pmc_multi_boot(void)
+{
+ /* At EL3 the SMC path to firmware is unavailable, read directly */
+ if (current_el() == 3)
+ return versal2_multi_boot_reg();
+
+ return zynqmp_pm_get_pmc_multi_boot_reg() & PMC_MULTI_BOOT_MASK;
+}
+#endif
+
int zynqmp_pm_feature(const u32 api_id)
{
int ret;