From: Julien Masson <[email protected]>

Genio 510 and 700 need a way to provision blank eMMC and recover from
unusable boot firmware without relying on the installed bootloader.
Add a BootROM-loaded fastboot agent that also prepares the eMMC boot
settings so newly flashed firmware can boot.

U-Boot proper is preferred when the complete agent fits BootROM's SRAM
download area before DRAM initialization. Provide the SPL alternative
for tighter payload budgets, avoiding the space required by BL31 and
U-Boot proper. An external DDR loader is still required.

Signed-off-by: Julien Masson <[email protected]>
Signed-off-by: Carlo Caione <[email protected]>
---
 arch/arm/dts/mt8370-genio-510-evk-u-boot.dtsi      |  4 ++
 arch/arm/dts/mt8370-genio-da-u-boot.dtsi           | 61 +++++++++++++++++++
 arch/arm/dts/mt8390-genio-700-evk-u-boot.dtsi      |  4 ++
 arch/arm/dts/mtk-genio-da-binman-u-boot.dtsi       | 17 ++++++
 .../dts/mtk-genio-loader-spl-binman-u-boot.dtsi    |  2 +-
 arch/arm/mach-mediatek/Kconfig                     | 28 +++++++++
 arch/arm/mach-mediatek/Makefile                    |  3 +
 arch/arm/mach-mediatek/spl_fastboot.c              | 68 ++++++++++++++++++++++
 board/mediatek/MAINTAINERS                         |  5 ++
 common/spl/Kconfig                                 |  2 +-
 configs/mt8370-genio-da-spl-fastboot.config        | 21 +++++++
 configs/mt8370-genio-da.config                     | 12 ++++
 configs/mt8370_genio_510_evk_da_spl_defconfig      |  2 +
 configs/mt8390_genio_700_evk_da_spl_defconfig      |  2 +
 drivers/usb/mtu3/mtu3_core.c                       |  5 +-
 15 files changed, 233 insertions(+), 3 deletions(-)

diff --git a/arch/arm/dts/mt8370-genio-510-evk-u-boot.dtsi 
b/arch/arm/dts/mt8370-genio-510-evk-u-boot.dtsi
index 10b9a142f37..2ee7fb1f40c 100644
--- a/arch/arm/dts/mt8370-genio-510-evk-u-boot.dtsi
+++ b/arch/arm/dts/mt8370-genio-510-evk-u-boot.dtsi
@@ -14,3 +14,7 @@
 #include "mtk-genio-mtk-boot-binman-u-boot.dtsi"
 #include "mtk-genio-bootloaders-binman-u-boot.dtsi"
 #endif
+
+#ifdef CONFIG_MTK_BROM_DOWNLOAD_AGENT
+#include "mt8370-genio-da-u-boot.dtsi"
+#endif
diff --git a/arch/arm/dts/mt8370-genio-da-u-boot.dtsi 
b/arch/arm/dts/mt8370-genio-da-u-boot.dtsi
new file mode 100644
index 00000000000..9d0d057cfc9
--- /dev/null
+++ b/arch/arm/dts/mt8370-genio-da-u-boot.dtsi
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (c) 2026 BayLibre, SAS.
+ * Author: Carlo Caione <[email protected]>
+ */
+
+/*
+ * Download agents (DAs) run from RAM to provision or recover eMMC.
+ * Both variants expose USB0 as a peripheral and leave unused USB
+ * controllers disabled, independently of the normal boot USB setup.
+ */
+
+#include "mtk-genio-binman-u-boot.dtsi"
+#include "mtk-genio-da-binman-u-boot.dtsi"
+
+&ssusb0 {
+       dr_mode = "peripheral";
+};
+
+&ssusb1 {
+       status = "disabled";
+};
+
+&ssusb2 {
+       status = "disabled";
+};
+
+/* Only the SPL fastboot variant needs these USB dependencies in SPL. */
+#ifdef CONFIG_MTK_BROM_DOWNLOAD_AGENT_SPL_FASTBOOT
+&pericfg_ao {
+       bootph-pre-ram;
+};
+
+&ssusb0 {
+       bootph-pre-ram;
+};
+
+&u3phy0 {
+       bootph-pre-ram;
+};
+
+&u2port0 {
+       bootph-pre-ram;
+};
+
+&usb_default_pins {
+       bootph-pre-ram;
+
+       pins-iddig {
+               bootph-pre-ram;
+       };
+
+       pins-valid {
+               bootph-pre-ram;
+       };
+
+       pins-vbus {
+               bootph-pre-ram;
+       };
+};
+#endif
diff --git a/arch/arm/dts/mt8390-genio-700-evk-u-boot.dtsi 
b/arch/arm/dts/mt8390-genio-700-evk-u-boot.dtsi
index 6230b016ca0..4fedbda9b3f 100644
--- a/arch/arm/dts/mt8390-genio-700-evk-u-boot.dtsi
+++ b/arch/arm/dts/mt8390-genio-700-evk-u-boot.dtsi
@@ -14,3 +14,7 @@
 #include "mtk-genio-mtk-boot-binman-u-boot.dtsi"
 #include "mtk-genio-bootloaders-binman-u-boot.dtsi"
 #endif
+
+#ifdef CONFIG_MTK_BROM_DOWNLOAD_AGENT
+#include "mt8370-genio-da-u-boot.dtsi"
+#endif
diff --git a/arch/arm/dts/mtk-genio-da-binman-u-boot.dtsi 
b/arch/arm/dts/mtk-genio-da-binman-u-boot.dtsi
new file mode 100644
index 00000000000..9627785cc56
--- /dev/null
+++ b/arch/arm/dts/mtk-genio-da-binman-u-boot.dtsi
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
+/*
+ * Copyright (c) 2026 BayLibre, SAS.
+ * Author: Carlo Caione <[email protected]>
+ */
+
+&binman {
+       da: da {
+               filename = "da.bin";
+               pad-byte = <0>;
+
+/* DA authentication is handled by the BootROM download tooling. */
+#define MTK_GENIO_SPL_NO_FIT_KEYS
+#include "mtk-genio-loader-spl-binman-u-boot.dtsi"
+#undef MTK_GENIO_SPL_NO_FIT_KEYS
+       };
+};
diff --git a/arch/arm/dts/mtk-genio-loader-spl-binman-u-boot.dtsi 
b/arch/arm/dts/mtk-genio-loader-spl-binman-u-boot.dtsi
index 2dd13d261a0..6c99d0926c4 100644
--- a/arch/arm/dts/mtk-genio-loader-spl-binman-u-boot.dtsi
+++ b/arch/arm/dts/mtk-genio-loader-spl-binman-u-boot.dtsi
@@ -12,7 +12,7 @@ ddr-loader {
        size = <CONFIG_MTK_GENIO_DDR_LOADER_SIZE>;
 };
 
-#ifdef CONFIG_SPL_FIT_SIGNATURE
+#if defined(CONFIG_SPL_FIT_SIGNATURE) && !defined(MTK_GENIO_SPL_NO_FIT_KEYS)
 u-boot-spl {
        type = "section";
        size = <CONFIG_SPL_MAX_SIZE>;
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index e572cfe8571..eece6456e43 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -249,6 +249,34 @@ config MTK_GENIO_BL31_LOAD_ADDR
 
 endif
 
+config MTK_BROM_DOWNLOAD_AGENT
+       bool
+       depends on TARGET_MT8188 && SPL
+       select BINMAN
+       select MTK_GENIO_IMAGE_CONTRACT
+
+choice
+       prompt "MediaTek BootROM download agent"
+       optional
+       depends on TARGET_MT8188 && SPL && SUPPORT_EMMC_BOOT
+       depends on !MTK_GENIO_BOOT_IMAGES
+       help
+         Select where to run fastboot after the BootROM downloads the agent
+         into RAM. Leave this disabled for normal storage boot.
+         Download agents cannot also build the normal storage-boot images.
+
+config MTK_BROM_DOWNLOAD_AGENT_SPL_FASTBOOT
+       bool "Run download-agent fastboot from SPL"
+       depends on SPL_FASTBOOT_FLASH_MMC
+       select MTK_BROM_DOWNLOAD_AGENT
+       select SPL_BOARD_INIT
+       help
+         Build an SPL which enters USB fastboot after the MediaTek BootROM
+         downloads it into RAM. The download agent also configures the eMMC
+         boot partition so that a newly flashed board can boot normally.
+
+endchoice
+
 config MTK_TZ_MOVABLE
        select ARCH_MISC_INIT
        select OF_SYSTEM_SETUP
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
index 35f748a70d6..2a371664d1d 100644
--- a/arch/arm/mach-mediatek/Makefile
+++ b/arch/arm/mach-mediatek/Makefile
@@ -4,6 +4,9 @@ obj-$(CONFIG_ARM64) += armv8-mem-map.o
 obj-y  += cpu.o
 obj-$(CONFIG_MTK_TZ_MOVABLE)   += tzcfg.o
 obj-$(CONFIG_XPL_BUILD)        += spl.o
+ifdef CONFIG_XPL_BUILD
+obj-$(CONFIG_MTK_BROM_DOWNLOAD_AGENT_SPL_FASTBOOT)     += spl_fastboot.o
+endif
 
 obj-$(CONFIG_TARGET_MT7622) += mt7622/
 obj-$(CONFIG_TARGET_MT7623) += mt7623/
diff --git a/arch/arm/mach-mediatek/spl_fastboot.c 
b/arch/arm/mach-mediatek/spl_fastboot.c
new file mode 100644
index 00000000000..73744946314
--- /dev/null
+++ b/arch/arm/mach-mediatek/spl_fastboot.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026 BayLibre, SAS.
+ * Author: Julien Masson <[email protected]>
+ */
+
+#include <dm/uclass.h>
+#include <fastboot.h>
+#include <mmc.h>
+#include <stdio.h>
+#include <linux/errno.h>
+
+static int mtk_mmc_boot_prepare(void)
+{
+       struct udevice *dev;
+       struct mmc *mmc;
+       int ret;
+
+       /* No storage loader has run yet, so probe the device here. */
+       ret = uclass_get_device_by_seq(UCLASS_MMC,
+                                      CONFIG_VAL(FASTBOOT_FLASH_MMC_DEV), 
&dev);
+       if (ret) {
+               printf("Cannot load MMC device: %d\n", ret);
+               return ret;
+       }
+
+       mmc = mmc_get_mmc_dev(dev);
+       if (!mmc)
+               return -ENODEV;
+
+       ret = mmc_init(mmc);
+       if (ret) {
+               printf("MMC init failed: %d\n", ret);
+               return ret;
+       }
+
+       /* Enable BOOT1 and boot acknowledgment for normal BootROM startup. */
+       ret = mmc_set_part_conf(mmc, 1, 1, 0);
+       if (ret)
+               printf("Cannot configure the eMMC boot partition: %d\n", ret);
+
+       /* Reset to x1 SDR, backward-compatible timing for each boot. */
+       ret = mmc_set_boot_bus_width(mmc, 0, 0, 0);
+       if (ret)
+               printf("Cannot configure the eMMC boot bus: %d\n", ret);
+
+       if (!mmc->ext_csd[EXT_CSD_RST_N_FUNCTION]) {
+               ret = mmc_set_rst_n_function(mmc, 1);
+               if (ret)
+                       printf("Cannot enable the eMMC reset function: %d\n", 
ret);
+       }
+
+       return 0;
+}
+
+void spl_board_init(void)
+{
+       int ret;
+
+       ret = mtk_mmc_boot_prepare();
+       if (ret)
+               printf("MMC boot preparation failed: %d\n", ret);
+
+       puts("Waiting for fastboot commands...\n");
+       ret = fastboot_usb_run(0, NULL, 0);
+       if (ret)
+               printf("Fastboot failed: %d\n", ret);
+}
diff --git a/board/mediatek/MAINTAINERS b/board/mediatek/MAINTAINERS
index 20befdba0e2..61fefcf9a34 100644
--- a/board/mediatek/MAINTAINERS
+++ b/board/mediatek/MAINTAINERS
@@ -18,13 +18,18 @@ MT8188/MT8370/MT8390
 M:     Macpaul Lin <[email protected]>
 M:     Julien Stephan <[email protected]>
 S:     Maintained
+F:     arch/arm/dts/mt8370-genio-da-u-boot.dtsi
 F:     arch/arm/dts/mt8370-genio-510-evk-u-boot.dtsi
 F:     arch/arm/dts/mt8390-genio-700-evk-u-boot.dtsi
 F:     arch/arm/dts/mt8390-genio-common-u-boot.dtsi
 F:     arch/arm/dts/mtk-genio-*-binman-u-boot.dtsi
 F:     arch/arm/dts/mtk-genio-binman-u-boot.dtsi
+F:     configs/mt8370-genio-da-spl-fastboot.config
+F:     configs/mt8370-genio-da.config
 F:     configs/mt8188.config
+F:     configs/mt8370_genio_510_evk_da_spl_defconfig
 F:     configs/mt8370_genio_510_evk_defconfig
+F:     configs/mt8390_genio_700_evk_da_spl_defconfig
 F:     configs/mt8390_genio_700_evk_defconfig
 F:     doc/board/mediatek/mt8188-genio-evk.rst
 
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 9bce4ab3955..c6fa647670b 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -194,7 +194,7 @@ config SPL_SHOW_ERRORS
 config SPL_BINMAN_SYMBOLS
        bool "Declare binman symbols in SPL"
        depends on SPL_FRAMEWORK && BINMAN
-       default n if MTK_GENIO_BOOT_IMAGES
+       default n if MTK_GENIO_IMAGE_CONTRACT
        default y
        help
          This enables use of symbols in SPL which refer to other entries in
diff --git a/configs/mt8370-genio-da-spl-fastboot.config 
b/configs/mt8370-genio-da-spl-fastboot.config
new file mode 100644
index 00000000000..6ba12f7d282
--- /dev/null
+++ b/configs/mt8370-genio-da-spl-fastboot.config
@@ -0,0 +1,21 @@
+#include <configs/mt8370-genio-da.config>
+
+CONFIG_MTK_BROM_DOWNLOAD_AGENT_SPL_FASTBOOT=y
+# Sparse writes need an 8 MiB DMA buffer in addition to the fastboot state.
+CONFIG_SPL_SYS_MALLOC_SIZE=0x1000000
+# dlmalloc also caps individual SPL allocations at SYS_MALLOC_LEN.
+CONFIG_SYS_MALLOC_LEN=0x1000000
+# Resume from the user-area FIT after fastboot continue.
+CONFIG_SUPPORT_EMMC_BOOT_OVERRIDE_PART_CONFIG=y
+CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION=0
+CONFIG_SPL_MMC_WRITE=y
+CONFIG_SPL_PHY=y
+CONFIG_SPL_DM_USB_GADGET=y
+CONFIG_SPL_USB_GADGET=y
+CONFIG_SPL_USB_MTU3=y
+CONFIG_SPL_FASTBOOT=y
+CONFIG_SPL_FASTBOOT_REBOOT=y
+CONFIG_SPL_FASTBOOT_FLASH_MMC=y
+CONFIG_SPL_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_SPL_FASTBOOT_MMC_BOOT_SUPPORT=y
+CONFIG_SPL_FASTBOOT_MMC_USER_SUPPORT=y
diff --git a/configs/mt8370-genio-da.config b/configs/mt8370-genio-da.config
new file mode 100644
index 00000000000..46cb42b37ba
--- /dev/null
+++ b/configs/mt8370-genio-da.config
@@ -0,0 +1,12 @@
+# USB identity and transfer buffer shared by both download-agent modes.
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_PHY=y
+CONFIG_PHY_MTK_TPHY=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_MTU3=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VENDOR_NUM=0x0e8d
+CONFIG_USB_GADGET_PRODUCT_NUM=0x201c
+CONFIG_FASTBOOT_BUF_ADDR=0x65000000
+CONFIG_FASTBOOT_BUF_SIZE=0x15000000
diff --git a/configs/mt8370_genio_510_evk_da_spl_defconfig 
b/configs/mt8370_genio_510_evk_da_spl_defconfig
new file mode 100644
index 00000000000..bb537616b53
--- /dev/null
+++ b/configs/mt8370_genio_510_evk_da_spl_defconfig
@@ -0,0 +1,2 @@
+#include <configs/mt8370_genio_510_evk_defconfig>
+#include <configs/mt8370-genio-da-spl-fastboot.config>
diff --git a/configs/mt8390_genio_700_evk_da_spl_defconfig 
b/configs/mt8390_genio_700_evk_da_spl_defconfig
new file mode 100644
index 00000000000..7f1ba02c6e7
--- /dev/null
+++ b/configs/mt8390_genio_700_evk_da_spl_defconfig
@@ -0,0 +1,2 @@
+#include <configs/mt8390_genio_700_evk_defconfig>
+#include <configs/mt8370-genio-da-spl-fastboot.config>
diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c
index f296a72cf18..d8ef6e6afba 100644
--- a/drivers/usb/mtu3/mtu3_core.c
+++ b/drivers/usb/mtu3/mtu3_core.c
@@ -843,7 +843,10 @@ int ssusb_gadget_init(struct ssusb_mtk *ssusb)
        mtu->mac_base = ssusb->mac_base;
        mtu->ssusb = ssusb;
        mtu->max_speed = usb_get_maximum_speed(dev_ofnode(ssusb->dev));
-       mtu->force_vbus = dev_read_bool(ssusb->dev, "mediatek,force-vbus");
+       /* Fixed peripheral mode must not depend on OTG session detection. */
+       mtu->force_vbus =
+               usb_get_dr_mode(dev_ofnode(ssusb->dev)) == 
USB_DR_MODE_PERIPHERAL ||
+               dev_read_bool(ssusb->dev, "mediatek,force-vbus");
 
        ret = mtu3_hw_init(mtu);
        if (ret) {

-- 
2.55.0

Reply via email to