summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFerass El Hafidi <[email protected]>2025-12-11 15:37:00 +0000
committerNeil Armstrong <[email protected]>2025-12-11 17:27:15 +0100
commit1bb973b4db6c07b7765b92e93e596907e8b8b469 (patch)
treeec47450a4d61e4b00850b655758a009a710fe021
parent8fa0db145f6b38341ac939c1e768ca37446bbaf8 (diff)
arm: meson: add support for EFI capsule updates
Previously, few Amlogic devices supported EFI capsule updates. Generally only the Libre Computer ones with SPI flash supported it, thanks to board-specific code. This commit commonises capsule update support across supported Amlogic boards. Similar to Qualcomm's support for it, the dfu string and firmware name is automatically generated at runtime depending on which device we are booted from. Right now this supports flashing to the eMMC/SD and SPI flash. As usual, the capsule UUID is automatically generated. You can get it by enabling CONFIG_CMD_EFIDEBUG and running: => efidebug capsule esrt ======================================== ESRT: fw_resource_count=1 ESRT: fw_resource_count_max=1 ESRT: fw_resource_version=1 [entry 0]============================== ESRT: fw_class=796180D4-AAB2-50F1-B16A-53DFF9CA89B2 ESRT: fw_type=unknown ESRT: fw_version=0 ESRT: lowest_supported_fw_version=0 ESRT: capsule_flags=0 ESRT: last_attempt_version=0 ESRT: last_attempt_status=success ======================================== Reviewed-by: Evgeny Bachinin <[email protected]> Reviewed-by: Neil Armstrong <[email protected]> Signed-off-by: Ferass El Hafidi <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Neil Armstrong <[email protected]>
-rw-r--r--arch/arm/include/asm/arch-meson/boot.h2
-rw-r--r--arch/arm/mach-meson/Makefile2
-rw-r--r--arch/arm/mach-meson/board-common.c5
-rw-r--r--arch/arm/mach-meson/capsule.c61
4 files changed, 69 insertions, 1 deletions
diff --git a/arch/arm/include/asm/arch-meson/boot.h b/arch/arm/include/asm/arch-meson/boot.h
index a11dfde719e..e66b45983fe 100644
--- a/arch/arm/include/asm/arch-meson/boot.h
+++ b/arch/arm/include/asm/arch-meson/boot.h
@@ -21,6 +21,8 @@ int meson_get_boot_device(void);
int meson_get_soc_rev(char *buff, size_t buff_len);
+void meson_setup_capsule(void);
+
/**
* meson_get_socinfo - retrieve cpu_id of the Amlogic SoC
*
diff --git a/arch/arm/mach-meson/Makefile b/arch/arm/mach-meson/Makefile
index 5b57d63e02d..08a24d4b24f 100644
--- a/arch/arm/mach-meson/Makefile
+++ b/arch/arm/mach-meson/Makefile
@@ -2,7 +2,7 @@
#
# Copyright (c) 2016 Beniamino Galvani <[email protected]>
-obj-y += board-common.o sm.o board-info.o
+obj-y += board-common.o sm.o board-info.o capsule.o
obj-$(CONFIG_MESON_GX) += board-gx.o
ifeq ($(CONFIG_SPL_BUILD),y)
obj-$(CONFIG_MESON_GXBB) += dram-gxbb.o
diff --git a/arch/arm/mach-meson/board-common.c b/arch/arm/mach-meson/board-common.c
index c243c46c0fc..a5afc2d75c0 100644
--- a/arch/arm/mach-meson/board-common.c
+++ b/arch/arm/mach-meson/board-common.c
@@ -147,6 +147,11 @@ int board_late_init(void)
{
meson_set_boot_source();
+ if (CONFIG_IS_ENABLED(DFU) && CONFIG_IS_ENABLED(EFI_LOADER)) {
+ /* Generate dfu_string for EFI capsule updates */
+ meson_setup_capsule();
+ }
+
return meson_board_late_init();
}
diff --git a/arch/arm/mach-meson/capsule.c b/arch/arm/mach-meson/capsule.c
new file mode 100644
index 00000000000..6e968a59c2c
--- /dev/null
+++ b/arch/arm/mach-meson/capsule.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2025, Ferass El Hafidi <[email protected]>
+ */
+
+#include <asm/arch/boot.h>
+#include <dm.h>
+#include <efi_loader.h>
+#include <mmc.h>
+
+/*
+ * To be able to support multiple devices and flash to the correct one we need
+ * to automatically generate the dfu_string and fw_name to match the device we
+ * are booted from. This is done by meson_setup_capsule() which is then called
+ * in board_late_init(). Right now we support EFI capsule updates on SPI flash,
+ * eMMC and SD cards.
+ */
+struct efi_fw_image fw_images[] = {
+ {
+ .image_index = 1,
+ },
+};
+
+struct efi_capsule_update_info update_info = {
+ .dfu_string = NULL, /* to be set in meson_capsule_setup */
+ .num_images = ARRAY_SIZE(fw_images),
+ .images = fw_images,
+};
+
+/*
+ * TODO: Support usecase e.g. FIT image on eMMC + SPL on SD.
+ */
+void meson_setup_capsule(void)
+{
+ static char dfu_string[32] = { 0 };
+ int mmc_devnum = 0; /* mmc0 => SD card */
+ u32 max_size = 0x2000; /* 4 MB (MMC sectors are 512 bytes each) */
+ u32 offset = 0x1; /* offset for flashing to eMMC/SD */
+ int boot_device = meson_get_boot_device();
+
+ switch (boot_device) {
+ case BOOT_DEVICE_EMMC:
+ mmc_devnum = 1; /* mmc1 is always eMMC */
+ fallthrough;
+ case BOOT_DEVICE_SD:
+ snprintf(dfu_string, 32, "mmc %d=u-boot.bin raw %d %d", mmc_devnum, offset, max_size);
+ fw_images[0].fw_name = u"U_BOOT_MESON_MMC";
+ break;
+ case BOOT_DEVICE_SPI:
+ /* We assume there's only one SPI flash */
+ fw_images[0].fw_name = u"U_BOOT_MESON_SPI";
+ snprintf(dfu_string, 32, "sf 0:0=u-boot.bin raw 0 %d", max_size);
+ break;
+ default:
+ debug("setup_capsule: Boot device %d unsupported\n", boot_device);
+ return;
+ }
+ debug("EFI Capsule DFU string: %s", dfu_string);
+
+ update_info.dfu_string = dfu_string;
+}