board: xilinx: Add FWU boot index support

Add fwu_plat_get_alt_num() and fwu_plat_get_bootidx() platform
callbacks required for FWU multi-bank update on Versal and Versal
Gen 2. The boot index is read from the PMC Global PGGS4 register
which is populated by PLM with a magic number and boot partition
index. Uses firmware IOCTL when CONFIG_ZYNQMP_FIRMWARE is enabled,
otherwise falls back to direct MMIO read.

Signed-off-by: Padmarao Begari <padmarao.begari@amd.com>
Signed-off-by: Michal Simek <michal.simek@amd.com>
Link: https://lore.kernel.org/r/20260514102601.1759779-6-padmarao.begari@amd.com
This commit is contained in:
Padmarao Begari
2026-05-14 15:52:22 +05:30
committed by Michal Simek
parent 818c06faa1
commit edccbc53af

View File

@@ -14,8 +14,12 @@
#include <init.h>
#include <jffs2/load_kernel.h>
#include <log.h>
#include <asm/io.h>
#include <asm/global_data.h>
#include <asm/sections.h>
#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL2)
#include <asm/arch/hardware.h>
#endif
#include <dm/uclass.h>
#include <i2c.h>
#include <linux/sizes.h>
@@ -30,6 +34,8 @@
#include <rng.h>
#include <slre.h>
#include <soc.h>
#include <zynqmp_firmware.h>
#include <linux/bitfield.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <u-boot/uuid.h>
@@ -718,7 +724,74 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
return reg + size;
}
#endif
#if defined(CONFIG_FWU_MULTI_BANK_UPDATE)
#if defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL2)
/*
* The Versal and Versal Gen 2 PMC Global pggs4 register contains below
* information in each byte as:
*
* Byte[3]: Magic number
* Byte[2]: Boot counter value
* Byte[1]: Boot partition value - boot index
* Byte[0]: Rollback counter value
*/
#define MAGIC_NUM 0x1D
#define MAGIC_MASK GENMASK(31, 24)
#define BOOTINDEX_MASK GENMASK(15, 8)
static int plat_get_boot_index(void)
{
u32 val;
if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
val = zynqmp_pm_get_pmc_global_pggs_reg(PMC_GLOBAL_PGGS4_REG);
else
val = readl(PMC_GLOBAL_PGGS4_REG);
if (FIELD_GET(MAGIC_MASK, val) != MAGIC_NUM) {
log_err("FWU requires PMC magic number 0x%x\n", MAGIC_NUM);
return -EINVAL;
}
return FIELD_GET(BOOTINDEX_MASK, val);
}
#endif
int fwu_plat_get_alt_num(struct udevice __always_unused *dev,
efi_guid_t *image_id, u8 *alt_num)
{
int ret;
ret = fwu_mtd_get_alt_num(image_id, alt_num, "nor0");
debug("%s: return %d\n", __func__, ret);
return ret;
}
void fwu_plat_get_bootidx(uint *boot_idx)
{
int ret;
u32 active_idx;
ret = fwu_get_active_index(&active_idx);
if (ret < 0)
printf("%s: failed to read active index\n", __func__);
ret = plat_get_boot_index();
if (ret < 0) {
*boot_idx = 0;
printf("%s: failed and setup boot index to 0\n", __func__);
} else {
*boot_idx = ret;
}
debug("%s: boot_idx: %d, active_idx: %d\n",
__func__, *boot_idx, active_idx);
}
#endif
#if IS_ENABLED(CONFIG_BOARD_RNG_SEED)