]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
tools: mkimage: Add support for initialization table for Zynq and ZynqMP
authorMike Looijmans <mike.looijmans@topic.nl>
Tue, 20 Sep 2016 09:37:24 +0000 (11:37 +0200)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 26 Oct 2016 07:13:58 +0000 (09:13 +0200)
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>
arch/arm/cpu/armv8/zynqmp/Kconfig
arch/arm/mach-zynq/Kconfig
scripts/Makefile.spl
tools/zynqimage.c
tools/zynqmpimage.c

index 17da48e71b080e05687f3355441f7e8410775426..e847cba3f0b26a108e59809a763763c699f6613b 100644 (file)
@@ -17,6 +17,13 @@ config SYS_CONFIG_NAME
          Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
          will be used for board configuration.
 
+config BOOT_INIT_FILE
+       string "boot.bin init register filename"
+       default ""
+       help
+         Add register writes to boot.bin format (max 256 pairs).
+         Expect a table of register-value pairs, e.g. "0x12345678 0x4321"
+
 config ZYNQMP_QSPI
        bool "Configure ZynqMP QSPI"
        select DM_SPI
index db3c5792939e837d9445de839e5e6867d75e50b3..9b04b38207d638d28f15c9cb07f0586d761d9069 100644 (file)
@@ -17,4 +17,14 @@ config SYS_CONFIG_NAME
          Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
          will be used for board configuration.
 
+config SYS_MALLOC_F_LEN
+       default 0x600
+
+config BOOT_INIT_FILE
+       string "boot.bin init register filename"
+       default ""
+       help
+         Add register writes to boot.bin format (max 256 pairs).
+         Expect a table of register-value pairs, e.g. "0x12345678 0x4321"
+
 endif
index 1f26f6e73ba2a504679b1a491e4a84556e0b015c..5005c4642633e31c5436b2a2b91e0631fd525522 100644 (file)
@@ -135,10 +135,10 @@ boot.bin: $(obj)/u-boot-spl.bin FORCE
        $(call if_changed,mkimage)
 else
 ifdef CONFIG_ARCH_ZYNQ
-MKIMAGEFLAGS_boot.bin = -T zynqimage
+MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)
 endif
 ifdef CONFIG_ARCH_ZYNQMP
-MKIMAGEFLAGS_boot.bin = -T zynqmpimage
+MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)
 endif
 
 spl/boot.bin: $(obj)/u-boot-spl.bin FORCE
index c43bd5d48820a1ba9337cc93b85fff08f21d461a..43876e7a302499fed65ac33ef0afdbc09f2376b9 100644 (file)
@@ -222,6 +222,30 @@ static int zynqimage_check_image_types(uint8_t type)
        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 @@ static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd,
        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);
 }
 
index 3f28eb401d9b439007b98083843a97cdb0a9345c..d08144c2bdfd376f991eb2611a7490b0662b6aaa 100644 (file)
@@ -234,6 +234,30 @@ static int zynqmpimage_check_image_types(uint8_t type)
        return EXIT_FAILURE;
 }
 
+static void zynqmpimage_parse_initparams(struct zynqmp_header *zynqhdr,
+       const char *filename)
+{
+       /* Expect a table of register-value pairs, e.g. "0x12345678 0x4321" */
+       FILE *fp = fopen(filename, "r");
+       struct zynqmp_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 zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
                struct image_tool_params *params)
 {
@@ -250,6 +274,10 @@ static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
        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))
+               zynqmpimage_parse_initparams(zynqhdr, params->imagename2);
+
        zynqhdr->checksum = zynqmpimage_checksum(zynqhdr);
 }