[PATCH 5/5] board: samsung: e850-96: Load firmwares over USB on USB boot

Sam Protsenko semen.protsenko at linaro.org
Mon Oct 27 06:51:05 CET 2025


During USB boot it's expected that the bootloader (U-Boot) should
download LDFW and TZSW firmware binaries over USB, using corresponding
SMC call. Once it's done, the Boot ROM code can release the USB block,
so that it can be used in U-Boot (e.g. for flashing images to eMMC using
DFU or fastboot). Otherwise USB wouldn't be accessible in U-Boot, and
any attempt to access USB PHY or DWC3 registers will lead to abort.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 board/samsung/e850-96/e850-96.c | 36 +++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c
index 3cf98a01b703..3aa4992a36d5 100644
--- a/board/samsung/e850-96/e850-96.c
+++ b/board/samsung/e850-96/e850-96.c
@@ -11,6 +11,7 @@
 #include <net.h>
 #include <usb.h>
 #include <asm/io.h>
+#include "bootdev.h"
 #include "fw.h"
 #include "pmic.h"
 
@@ -31,6 +32,10 @@
 #define EMMC_DEV_NUM			0
 #define EMMC_ESP_PART			1
 
+/* Firmware size */
+#define LDFW_MAX_SIZE			SZ_4M
+#define SP_MAX_SIZE			SZ_1M
+
 struct efi_fw_image fw_images[] = {
 	{
 		.image_type_id = E850_96_FWBL1_IMAGE_GUID,
@@ -127,11 +132,34 @@ static void setup_ethaddr(void)
 		eth_env_set_enetaddr("ethaddr", mac_addr);
 }
 
+static void load_firmware_usb(void)
+{
+	int err;
+
+	printf("Loading LDFW firmware (over USB)...\n");
+	err = load_image_usb(USB_DN_IMAGE_LDFW, LDFW_NWD_ADDR, LDFW_MAX_SIZE);
+	if (err) {
+		printf("ERROR: LDFW loading failed (%d)\n", err);
+		return;
+	}
+
+	err = init_ldfw(LDFW_NWD_ADDR);
+	if (err) {
+		printf("ERROR: LDFW init failed (%d)\n", err);
+		/* Do not return, still need to download SP */
+	}
+
+	printf("Loading SP firmware (over USB)...\n");
+	err = load_image_usb(USB_DN_IMAGE_SP, LDFW_NWD_ADDR, SP_MAX_SIZE);
+	if (err)
+		printf("ERROR: SP loading failed (%d)\n", err);
+}
+
 /*
  * Call this in board_late_init() to avoid probing block devices before
  * efi_init_early().
  */
-void load_firmware(void)
+static void load_firmware_blk(void)
 {
 	const char *ifname;
 	ulong dev, part;
@@ -175,7 +203,11 @@ int board_late_init(void)
 {
 	setup_serial();
 	setup_ethaddr();
-	load_firmware();
+
+	if (bootdev_is_usb())
+		load_firmware_usb();
+	else
+		load_firmware_blk();
 
 	return 0;
 }
-- 
2.39.5



More information about the U-Boot mailing list