tools: mkimage: Add support for initialization table for Zynq and ZynqMP

The Zynq/ZynqMP boot.bin file contains a region for register initialization
data. Filling in proper values in this table can reduce boot time
(e.g. about 50ms faster on QSPI boot) and also reduce the size of
the SPL binary.

The table is a simple text file with register+data on each line. Other
lines are simply skipped. The file can be passed to mkimage using the
"-R" parameter.

It is recommended to add reg init file to board folder.
For example:
CONFIG_BOOT_INIT_FILE="board/xilinx/zynqmp/xilinx_zynqmp_zcu102/reg.int

Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
diff --git a/tools/zynqimage.c b/tools/zynqimage.c
index c43bd5d..43876e7 100644
--- a/tools/zynqimage.c
+++ b/tools/zynqimage.c
@@ -222,6 +222,30 @@
 	return EXIT_FAILURE;
 }
 
+static void zynqimage_parse_initparams(struct zynq_header *zynqhdr,
+	const char *filename)
+{
+	/* Expect a table of register-value pairs, e.g. "0x12345678 0x4321" */
+	FILE *fp = fopen(filename, "r");
+	struct zynq_reginit reginit;
+	unsigned int reg_count = 0;
+	int r;
+
+	if (!fp) {
+		fprintf(stderr, "Cannot open initparams file: %s\n", filename);
+		exit(1);
+	}
+	do {
+		r = fscanf(fp, "%x %x", &reginit.address, &reginit.data);
+		if (r == 2) {
+			zynqhdr->register_init[reg_count] = reginit;
+			++reg_count;
+		}
+		r = fscanf(fp, "%*[^\n]\n"); /* Skip to next line */
+	} while ((r != EOF) && (reg_count < HEADER_REGINITS));
+	fclose(fp);
+}
+
 static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 		struct image_tool_params *params)
 {
@@ -237,6 +261,10 @@
 	if (params->eflag)
 		zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep);
 
+	/* User can pass in text file with init list */
+	if (strlen(params->imagename2))
+		zynqimage_parse_initparams(zynqhdr, params->imagename2);
+
 	zynqhdr->checksum = zynqimage_checksum(zynqhdr);
 }