From: Simon Glass <s...@chromium.org>

Standard passage provides for a bloblist to be passed from one firmware
phase to the next. That can be used to pass the devicetree along as well.
If CONFIG_OF_BOARD is defined, a board custom routine will provide a
bloblist or a specified memory address to retrieve the devicetree at
runtime.
A devicetree from a bloblist is prioritized than the one from specified
memory region.

Tests for this will be added as part of the Universal Payload work.

Signed-off-by: Simon Glass <s...@chromium.org>
Co-developed-by: Raymond Mao <raymond....@linaro.org>
Signed-off-by: Raymond Mao <raymond....@linaro.org>
---
Changes in v2
- New patch file created for v2.
  Amended from the original patch
  "[v2,30/32] fdt: Allow the devicetree to come from a bloblist".
  Remove CONFIG_OF_BLOBLIST and FDTSRC_BLOBLIST, a DTB from a previous
  loader is defined by CONFIG_OF_BOARD. The DTB can be located either in the
  bloblist or from a specified memory address.

 doc/develop/devicetree/control.rst |  8 +++--
 dts/Kconfig                        |  9 ++++--
 include/fdtdec.h                   |  3 +-
 lib/fdtdec.c                       | 52 +++++++++++++++++++++++-------
 4 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/doc/develop/devicetree/control.rst 
b/doc/develop/devicetree/control.rst
index cbb65c9b17..a7f0f87841 100644
--- a/doc/develop/devicetree/control.rst
+++ b/doc/develop/devicetree/control.rst
@@ -104,9 +104,11 @@ in u-boot.bin so you can still just flash u-boot.bin onto 
your board. If you are
 using CONFIG_SPL_FRAMEWORK, then u-boot.img will be built to include the device
 tree binary.
 
-If CONFIG_OF_BOARD is defined, a board-specific routine will provide the
-devicetree at runtime, for example if an earlier bootloader stage creates
-it and passes it to U-Boot.
+If CONFIG_OF_BOARD is defined, a board-specific routine will provide a bloblist
+or a specified memory region to retrieve the devicetree at runtime, for example
+if an earlier bootloader stage creates it and passes it to U-Boot.
+A devicetree from a bloblist is prioritized than the one from a specified 
memory
+region.
 
 If CONFIG_SANDBOX is defined, then it will be read from a file on
 startup. Use the -d flag to U-Boot to specify the file to read, -D for the
diff --git a/dts/Kconfig b/dts/Kconfig
index 00c0aeff89..4faf4ba633 100644
--- a/dts/Kconfig
+++ b/dts/Kconfig
@@ -110,8 +110,13 @@ config OF_BOARD
        default y if SANDBOX || OF_HAS_PRIOR_STAGE
        help
          If this option is enabled, the device tree is provided at runtime by
-         a custom function called board_fdt_blob_setup(). The board must
-         implement this function if it wishes to provide special behaviour.
+         bloblist via a custom function called board_bloblist_from_boot_arg()
+         or a memory region from a custom function called
+         board_fdt_blob_setup(). The board must implement either these
+         functions if it wishes to provide special behaviour.
+
+         A devicetree from a bloblist is prioritized then the one from a
+         specified memory region if the board provides both methods.
 
          With this option, the device tree build by U-Boot may be overridden or
          ignored. See OF_HAS_PRIOR_STAGE.
diff --git a/include/fdtdec.h b/include/fdtdec.h
index bd1149f46d..0824fe1359 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -72,14 +72,13 @@ struct bd_info;
  *     U-Boot is packaged as an ELF file, e.g. for debugging purposes
  * @FDTSRC_ENV: Provided by the fdtcontroladdr environment variable. This 
should
  *     be used for debugging/development only
- * @FDTSRC_NONE: No devicetree at all
  */
 enum fdt_source_t {
        FDTSRC_SEPARATE,
        FDTSRC_FIT,
        FDTSRC_BOARD,
        FDTSRC_EMBED,
-       FDTSRC_ENV,
+       FDTSRC_ENV
 };
 
 /*
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 7a69167648..025baca4a4 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -7,7 +7,11 @@
  */
 
 #ifndef USE_HOSTCC
+
+#define LOG_CATEGORY   LOGC_DT
+
 #include <common.h>
+#include <bloblist.h>
 #include <boot_fit.h>
 #include <display_options.h>
 #include <dm.h>
@@ -86,7 +90,7 @@ static const char *const fdt_src_name[] = {
        [FDTSRC_FIT] = "fit",
        [FDTSRC_BOARD] = "board",
        [FDTSRC_EMBED] = "embed",
-       [FDTSRC_ENV] = "env",
+       [FDTSRC_ENV] = "env"
 };
 
 const char *fdtdec_get_srcname(void)
@@ -1665,21 +1669,45 @@ int fdtdec_setup(void)
 {
        int ret;
 
-       /* The devicetree is typically appended to U-Boot */
-       if (IS_ENABLED(CONFIG_OF_SEPARATE)) {
-               gd->fdt_blob = fdt_find_separate();
-               gd->fdt_src = FDTSRC_SEPARATE;
-       } else { /* embed dtb in ELF file for testing / development */
-               gd->fdt_blob = dtb_dt_embedded();
-               gd->fdt_src = FDTSRC_EMBED;
-       }
-
-       /* Allow the board to override the fdt address. */
+       /*
+        * The devicetree is typically appended to U-Boot.
+        * Option 1: From bloblist.
+        * Option 2: From a specified memory address.
+        */
        if (IS_ENABLED(CONFIG_OF_BOARD)) {
-               gd->fdt_blob = board_fdt_blob_setup(&ret);
+               /*
+                * DTB is from board.
+                * Either from bloblist or a platform specified memory.
+                */
+               ret = bloblist_maybe_init();
                if (ret)
                        return ret;
+
+               /* Check if a DTB exists in bloblist first */
+               if (IS_ENABLED(CONFIG_BLOBLIST)) {
+                       gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0);
+                       if (gd->fdt_blob) {
+                               log_info("Fdt from bloblist at 0x%lx\n",
+                                        (unsigned long)gd->fdt_blob);
+                       }
+               }
+               if (!gd->fdt_blob) {
+                       /* Apply DTB from a platform specified memory */
+                       gd->fdt_blob = board_fdt_blob_setup(&ret);
+                       if (ret)
+                               return ret;
+                       log_info("Fdt from memory at 0x%lx\n",
+                                (unsigned long)gd->fdt_blob);
+               }
                gd->fdt_src = FDTSRC_BOARD;
+       } else {
+               if (IS_ENABLED(CONFIG_OF_SEPARATE)) {
+                       gd->fdt_blob = fdt_find_separate();
+                       gd->fdt_src = FDTSRC_SEPARATE;
+               } else { /* embed dtb in ELF file for testing / development */
+                       gd->fdt_blob = dtb_dt_embedded();
+                       gd->fdt_src = FDTSRC_EMBED;
+               }
        }
 
        /* Allow the early environment to override the fdt address */
-- 
2.25.1

Reply via email to