Merge tag 'ti-v2020.07-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-ti
[oweals/u-boot.git] / common / spl / spl_fit.c
index 5aeb9528fe4534932a379d7b46139dcad8e71a3b..f581a2242132e29903df4b018a8bc4af5980075e 100644 (file)
@@ -6,11 +6,14 @@
 
 #include <common.h>
 #include <errno.h>
+#include <board.h>
 #include <fpga.h>
 #include <gzip.h>
 #include <image.h>
+#include <log.h>
 #include <malloc.h>
 #include <spl.h>
+#include <asm/cache.h>
 #include <linux/libfdt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -32,6 +35,29 @@ __weak ulong board_spl_fit_size_align(ulong size)
        return size;
 }
 
+static int find_node_from_desc(const void *fit, int node, const char *str)
+{
+       int child;
+
+       if (node < 0)
+               return -EINVAL;
+
+       /* iterate the FIT nodes and find a matching description */
+       for (child = fdt_first_subnode(fit, node); child >= 0;
+            child = fdt_next_subnode(fit, child)) {
+               int len;
+               const char *desc = fdt_getprop(fit, child, "description", &len);
+
+               if (!desc)
+                       continue;
+
+               if (!strcmp(desc, str))
+                       return child;
+       }
+
+       return -ENOENT;
+}
+
 /**
  * spl_fit_get_image_name(): By using the matching configuration subnode,
  * retrieve the name of an image, specified by a property name and an index
@@ -46,12 +72,14 @@ __weak ulong board_spl_fit_size_align(ulong size)
  */
 static int spl_fit_get_image_name(const void *fit, int images,
                                  const char *type, int index,
-                                 char **outname)
+                                 const char **outname)
 {
+       struct udevice *board;
        const char *name, *str;
        __maybe_unused int node;
        int conf_node;
        int len, i;
+       bool found = true;
 
        conf_node = fit_find_config_node(fit);
        if (conf_node < 0) {
@@ -77,12 +105,45 @@ static int spl_fit_get_image_name(const void *fit, int images,
        for (i = 0; i < index; i++) {
                str = strchr(str, '\0') + 1;
                if (!str || (str - name >= len)) {
-                       debug("no string for index %d\n", index);
-                       return -E2BIG;
+                       found = false;
+                       break;
+               }
+       }
+
+       if (!found && !board_get(&board)) {
+               int rc;
+               /*
+                * no string in the property for this index. Check if the board
+                * level code can supply one.
+                */
+               rc = board_get_fit_loadable(board, index - i - 1, type, &str);
+               if (rc && rc != -ENOENT)
+                       return rc;
+
+               if (!rc) {
+                       /*
+                        * The board provided a name for a loadable.
+                        * Try to match it against the description properties
+                        * first. If no matching node is found, use it as a
+                        * node name.
+                        */
+                       int node;
+                       int images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+
+                       node = find_node_from_desc(fit, images, str);
+                       if (node > 0)
+                               str = fdt_get_name(fit, node, NULL);
+
+                       found = true;
                }
        }
 
-       *outname = (char *)str;
+       if (!found) {
+               debug("no string for index %d\n", index);
+               return -E2BIG;
+       }
+
+       *outname = str;
        return 0;
 }
 
@@ -101,7 +162,7 @@ static int spl_fit_get_image_name(const void *fit, int images,
 static int spl_fit_get_image_node(const void *fit, int images,
                                  const char *type, int index)
 {
-       char *str;
+       const char *str;
        int err;
        int node;
 
@@ -200,11 +261,9 @@ static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
                        debug("%s ", genimg_get_type_name(type));
        }
 
-       if (IS_ENABLED(CONFIG_SPL_OS_BOOT) && IS_ENABLED(CONFIG_SPL_GZIP)) {
-               if (fit_image_get_comp(fit, node, &image_comp))
-                       puts("Cannot get image compression format.\n");
-               else
-                       debug("%s ", genimg_get_comp_name(image_comp));
+       if (IS_ENABLED(CONFIG_SPL_GZIP)) {
+               fit_image_get_comp(fit, node, &image_comp);
+               debug("%s ", genimg_get_comp_name(image_comp));
        }
 
        if (fit_image_get_load(fit, node, &load_addr))
@@ -368,8 +427,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image,
                        debug("%s: DT overlay %s applied\n", __func__,
                              fit_get_name(fit, node, NULL));
                }
-               if (tmpbuffer)
-                       free(tmpbuffer);
+               free(tmpbuffer);
                if (ret)
                        return ret;
        }
@@ -387,7 +445,7 @@ static int spl_fit_record_loadable(const void *fit, int images, int index,
 {
        int ret = 0;
 #if !CONFIG_IS_ENABLED(FIT_IMAGE_TINY)
-       char *name;
+       const char *name;
        int node;
 
        ret = spl_fit_get_image_name(fit, images, "loadables",
@@ -589,10 +647,6 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
 
                if (!spl_fit_image_get_os(fit, node, &os_type))
                        debug("Loadable is %s\n", genimg_get_os_name(os_type));
-#if CONFIG_IS_ENABLED(FIT_IMAGE_TINY)
-               else
-                       os_type = IH_OS_U_BOOT;
-#endif
 
                if (os_type == IH_OS_U_BOOT) {
                        spl_fit_append_fdt(&image_info, info, sector,