arm: mach-k3: sysfw-loader: Add support to download SYSFW via DFU

Add support to download SYSFW into internal RAM via DFU in DFU boot
mode. Prepare a DFU config entity entry dynamically using buffer address
allocated for SYSFW and start DFU gadget to get SYSFW.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c
index 5903bbe..94dbeb9 100644
--- a/arch/arm/mach-k3/sysfw-loader.c
+++ b/arch/arm/mach-k3/sysfw-loader.c
@@ -11,6 +11,10 @@
 #include <malloc.h>
 #include <remoteproc.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <g_dnl.h>
+#include <usb.h>
+#include <dfu.h>
+
 #include <asm/arch/sys_proto.h>
 #include "common.h"
 
@@ -171,6 +175,27 @@
 		panic("Failed to set board security configuration (%d)\n",
 		      ret);
 }
+
+#if CONFIG_IS_ENABLED(DFU)
+static int k3_sysfw_dfu_download(void *addr)
+{
+	char dfu_str[50];
+	int ret;
+
+	sprintf(dfu_str, "sysfw.itb ram 0x%p 0x%x", addr,
+		CONFIG_K3_SYSFW_IMAGE_SIZE_MAX);
+	ret = dfu_config_entities(dfu_str, "ram", "0");
+	if (ret) {
+		dfu_free_entities();
+		goto exit;
+	}
+
+	run_usb_dnl_gadget(0, "usb_dnl_dfu");
+exit:
+	dfu_free_entities();
+	return ret;
+}
+#endif
 
 void k3_sysfw_loader(void (*config_pm_done_callback)(void))
 {
@@ -236,6 +261,11 @@
 		ret = spl_ymodem_load_image(&spl_image, &bootdev);
 		break;
 #endif
+#if CONFIG_IS_ENABLED(DFU)
+	case BOOT_DEVICE_DFU:
+		ret = k3_sysfw_dfu_download(sysfw_load_address);
+		break;
+#endif
 	default:
 		panic("Loading SYSFW image from device %u not supported!\n",
 		      bootdev.boot_device);