]> git.ipfire.org Git - people/ms/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>
Tue, 15 Nov 2016 14:27:37 +0000 (15:27 +0100)
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 1eedb39aa5a864ca91462efd8c1c12b3c23343f6..a3baae4f740ca15e37906ce86b8b8ff900632953 100644 (file)
@@ -41,6 +41,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_USB
        bool "Configure ZynqMP USB"
 
index a1175eea6ebb432ec2eb440e5f1caf6be78db1a1..44e16af863d700559638b1d1765376dd20e4d075 100644 (file)
@@ -44,4 +44,11 @@ config SYS_CONFIG_NAME
 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 e0b0117dc9b6c35df0af6b421987c9ba0da04095..03a2f061a46cf2a72d0e6dbaaee4651f24364b7a 100644 (file)
@@ -146,10 +146,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);
 }