stm32mp: stm32prog: add support of RAM target

Add support of RAM target in flashlayout to load kernel image
("system") and device tree ("filesystem") in DDR with DFU and
start these images.

The flashlayout.tsv is:

-	0x01	fsbl		Binary		none	0x00000000	tf-a.stm32
-	0x03	ssbl		Binary		none	0x00000000	u-boot.stm32
P	0x10	kernel		System		ram0	0xC2000000	uImage.bin
P	0x11	dtb		FileSystem	ram0	0xC4000000	dtb.bin

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Reviewed-by: Patrice Chotard <patrice.chotard@st.com>
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
index baf9b6b..6bebea7 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c
@@ -47,6 +47,7 @@
 	bool reset = false;
 	struct image_header_s header;
 	struct stm32prog_data *data;
+	u32 uimage, dtb;
 
 	if (argc < 3 ||  argc > 5)
 		return CMD_RET_USAGE;
@@ -118,11 +119,38 @@
 		goto cleanup;
 	}
 
+	uimage = data->uimage;
+	dtb = data->dtb;
+
 	stm32prog_clean(data);
 	free(stm32prog_data);
 	stm32prog_data = NULL;
 
 	puts("Download done\n");
+
+	if (uimage) {
+		char boot_addr_start[20];
+		char dtb_addr[20];
+		char *bootm_argv[5] = {
+			"bootm", boot_addr_start, "-", dtb_addr, NULL
+		};
+		if (!dtb)
+			bootm_argv[3] = env_get("fdtcontroladdr");
+		else
+			snprintf(dtb_addr, sizeof(dtb_addr) - 1,
+				 "0x%x", dtb);
+
+		snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
+			 "0x%x", uimage);
+		printf("Booting kernel at %s - %s...\n\n\n",
+		       boot_addr_start, bootm_argv[3]);
+		/* Try bootm for legacy and FIT format image */
+		if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID)
+			do_bootm(cmdtp, 0, 4, bootm_argv);
+		else if CONFIG_IS_ENABLED(CMD_BOOTZ)
+			do_bootz(cmdtp, 0, 4, bootm_argv);
+	}
+
 	if (reset) {
 		puts("Reset...\n");
 		run_command("reset", 0);
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
index 0967bbc..cc30321 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c
@@ -272,6 +272,9 @@
 	} else if (!strncmp(p, "spi-nand", 8)) {
 		part->target = STM32PROG_SPI_NAND;
 		len = 8;
+	} else if (!strncmp(p, "ram", 3)) {
+		part->target = STM32PROG_RAM;
+		len = 0;
 	} else {
 		result = -EINVAL;
 	}
@@ -610,6 +613,11 @@
 		dev->mtd = mtd;
 		break;
 #endif
+	case STM32PROG_RAM:
+		first_addr = gd->bd->bi_dram[0].start;
+		last_addr = first_addr + gd->bd->bi_dram[0].size;
+		dev->erase_size = 1;
+		break;
 	default:
 		stm32prog_err("unknown device type = %d", dev->target);
 		return -ENODEV;
@@ -1022,7 +1030,11 @@
 			  part->name, part->id,
 			  size, multiplier, type);
 
-	if (part->part_type == RAW_IMAGE) {
+	if (part->target == STM32PROG_RAM) {
+		offset += snprintf(buf + offset, ALT_BUF_LEN - offset,
+				   "ram 0x%llx 0x%llx",
+				   part->addr, part->size);
+	} else if (part->part_type == RAW_IMAGE) {
 		u64 dfu_size;
 
 		if (part->dev->target == STM32PROG_MMC)
@@ -1073,6 +1085,10 @@
 		get_mtd_by_target(devstr, part->target, part->dev_id);
 		break;
 #endif
+	case STM32PROG_RAM:
+		sprintf(dfustr, "ram");
+		sprintf(devstr, "0");
+		break;
 	default:
 		stm32prog_err("invalid target: %d", part->target);
 		return -ENODEV;
@@ -1440,6 +1456,13 @@
 	if (!data->cur_part)
 		return;
 
+	if (data->cur_part->target == STM32PROG_RAM) {
+		if (data->cur_part->part_type == PART_SYSTEM)
+			data->uimage = data->cur_part->addr;
+		if (data->cur_part->part_type == PART_FILESYSTEM)
+			data->dtb = data->cur_part->addr;
+	}
+
 	if (CONFIG_IS_ENABLED(MMC) &&
 	    data->cur_part->part_id < 0) {
 		char cmdbuf[60];
@@ -1569,6 +1592,10 @@
 		}
 		break;
 #endif
+	case STM32PROG_RAM:
+		printf("on ram: ");
+		memset((void *)(uintptr_t)part->addr, 0, (size_t)part->size);
+		break;
 	default:
 		ret = -1;
 		stm32prog_err("%s (0x%x): erase invalid", part->name, part->id);
diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
index c4fdb5b..bae4e91 100644
--- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
+++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h
@@ -27,7 +27,8 @@
 	STM32PROG_MMC,
 	STM32PROG_NAND,
 	STM32PROG_NOR,
-	STM32PROG_SPI_NAND
+	STM32PROG_SPI_NAND,
+	STM32PROG_RAM
 };
 
 enum stm32prog_link_t {
@@ -136,6 +137,10 @@
 	u8	*buffer; /* size = USART_RAM_BUFFER_SIZE*/
 	int	dfu_seq;
 	u8	read_phase;
+
+	/* bootm information */
+	u32	uimage;
+	u32	dtb;
 };
 
 extern struct stm32prog_data *stm32prog_data;