diff mbox series

[01/11] mach-snapdragon: refactor board_fdt_blob_setup()

Message ID 20240809-b4-snapdragon-improvements-v1-1-7c353f3e8f74@linaro.org
State New
Headers show
Series mach-snapdragon: various improvements for newer boards | expand

Commit Message

Caleb Connolly Aug. 8, 2024, 11:59 p.m. UTC
If U-Boot has a DTB built in (appended to the image directly) then this
was likely intentional, we should prioritise it over one provided by ABL
(if there was one).

Make this behaviour explicit, and panic if no valid DTB could be found
anywhere. Returning an error is not useful in this case as U-Boot would
just crash later in a more confusing way.

Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
---
 arch/arm/mach-snapdragon/board.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c
index b439a19ec7eb..2881de28a0a3 100644
--- a/arch/arm/mach-snapdragon/board.c
+++ b/arch/arm/mach-snapdragon/board.c
@@ -17,8 +17,9 @@ 
 #include <dm/uclass-internal.h>
 #include <dm/read.h>
 #include <power/regulator.h>
 #include <env.h>
+#include <fdt_support.h>
 #include <init.h>
 #include <linux/arm-smccc.h>
 #include <linux/bug.h>
 #include <linux/psci.h>
@@ -84,28 +85,37 @@  static void show_psci_version(void)
 	      PSCI_VERSION_MAJOR(res.a0),
 	      PSCI_VERSION_MINOR(res.a0));
 }
 
+/* We support booting U-Boot with an internal DT when running as a first-stage bootloader
+ * or for supporting quirky devices where it's easier to leave the downstream DT in place
+ * to improve ABL compatibility. Otherwise, we use the DT provided by ABL.
+ */
 void *board_fdt_blob_setup(int *err)
 {
-	phys_addr_t fdt;
-	/* Return DTB pointer passed by ABL */
+	struct fdt_header *fdt;
+	bool internal_valid, external_valid;
+
 	*err = 0;
-	fdt = get_prev_bl_fdt_addr();
+	fdt = (struct fdt_header *)get_prev_bl_fdt_addr();
+	external_valid = fdt && !fdt_check_header(fdt);
+	internal_valid = !fdt_check_header(gd->fdt_blob);
 
 	/*
-	 * If we bail then the board will simply not boot, instead let's
-	 * try and use the FDT built into U-Boot if there is one...
-	 * This avoids having a hard dependency on the previous stage bootloader
+	 * There is no point returning an error here, U-Boot can't do anything useful in this situation.
+	 * Bail out while we can still print a useful error message.
 	 */
+	if (!internal_valid && !external_valid)
+		panic("Internal FDT is invalid and no external FDT was provided! (fdt=%#llx)\n",
+		      (phys_addr_t)fdt);
 
-	if (IS_ENABLED(CONFIG_OF_SEPARATE) && (!fdt || fdt != ALIGN(fdt, SZ_4K) ||
-					       fdt_check_header((void *)fdt))) {
-		debug("%s: Using built in FDT, bootloader gave us %#llx\n", __func__, fdt);
+	if (internal_valid) {
+		debug("Using built in FDT\n");
 		return (void *)gd->fdt_blob;
+	} else {
+		debug("Using external FDT\n");
+		return (void *)fdt;
 	}
-
-	return (void *)fdt;
 }
 
 void reset_cpu(void)
 {