From: João Paulo Gonçalves <joao.goncal...@toradex.com> In some use cases, board-specific device tree changes must not be overwritten by system fixups. Although U-Boot provides ft_board_setup_ex() for this purpose, it is currently only used on TI Keystone. Make ft_board_setup_ex() to be a generic option, allowing its use by other architectures/boards. To maintain backward compatibility, enable it by default on TI Keystone.
Signed-off-by: João Paulo Gonçalves <joao.goncal...@toradex.com> --- arch/arm/Kconfig | 1 + boot/Kconfig | 10 ++++++++++ boot/image-fdt.c | 27 +++++++++++++-------------- cmd/fdt.c | 6 +++--- include/fdt_support.h | 15 ++++++++++----- 5 files changed, 37 insertions(+), 22 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9a22c7f6ceaae9796b130a038c01617d87ad258c..da67f20675a5d5a56ed524e1e6f8154f28b27f8f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -810,6 +810,7 @@ config ARCH_KEYSTONE imply CMD_SAVES imply DM_I2C imply FIT + imply OF_BOARD_SETUP_EXTENDED imply SOC_TI imply TI_KEYSTONE_SERDES diff --git a/boot/Kconfig b/boot/Kconfig index 1f5ecb60c77d56b36840eb4449d9ea71b4c402cd..b0548358e8b9c21ac8054c4c574718219f77b8c4 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -1839,6 +1839,16 @@ config OF_BOARD_SETUP board-specific information in the device tree for use by the OS. The device tree is then passed to the OS. +config OF_BOARD_SETUP_EXTENDED + bool "Set up latest board-specific details in device tree before boot" + imply OF_BOARD_SETUP + help + This causes U-Boot to call ft_board_setup_ex() before booting into + the Operating System. Similar function as ft_board_setup(). However, + its modifications are not overwritten by other system changes and are + applied to the device tree as the very last step before boot. + The device tree is then passed to the OS. + config OF_SYSTEM_SETUP bool "Set up system-specific details in device tree before boot" help diff --git a/boot/image-fdt.c b/boot/image-fdt.c index 8f718ad29f6b7af9cb1d0cedc8e4c038eb3020fc..1c5d9426b869ca4ad5babf8398d41abe0f02437d 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -571,6 +571,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb) { ulong *initrd_start = &images->initrd_start; ulong *initrd_end = &images->initrd_end; + bool skip_board_fixup = false; int ret, fdt_ret, of_size; if (IS_ENABLED(CONFIG_OF_ENV_SETUP)) { @@ -621,18 +622,18 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb) fdt_fixup_pstore(blob); #endif if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) { - const char *skip_board_fixup; + skip_board_fixup = (env_get_ulong("skip_board_fixup", 10, 0) == 1); - skip_board_fixup = env_get("skip_board_fixup"); - if (skip_board_fixup && ((int)simple_strtol(skip_board_fixup, NULL, 10) == 1)) { - printf("skip board fdt fixup\n"); - } else { - fdt_ret = ft_board_setup(blob, gd->bd); - if (fdt_ret) { - printf("ERROR: board-specific fdt fixup failed: %s\n", - fdt_strerror(fdt_ret)); - goto err; - } + if (skip_board_fixup) + printf("skip all board fdt fixup\n"); + } + + if (IS_ENABLED(CONFIG_OF_BOARD_SETUP) && !skip_board_fixup) { + fdt_ret = ft_board_setup(blob, gd->bd); + if (fdt_ret) { + printf("ERROR: board-specific fdt fixup failed: %s\n", + fdt_strerror(fdt_ret)); + goto err; } } if (IS_ENABLED(CONFIG_OF_SYSTEM_SETUP)) { @@ -685,10 +686,8 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb) if (CONFIG_IS_ENABLED(LMB) && lmb) lmb_reserve(map_to_sysmem(blob), of_size, LMB_NONE); -#if defined(CONFIG_ARCH_KEYSTONE) - if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) + if (IS_ENABLED(CONFIG_OF_BOARD_SETUP_EXTENDED) && !skip_board_fixup) ft_board_setup_ex(blob, gd->bd); -#endif return 0; err: diff --git a/cmd/fdt.c b/cmd/fdt.c index d16b141ce32d2173b08e64a8084b7b2b0f5a5192..a67c30b21d55dced7dba72e8ccdfbe3466ed820c 100644 --- a/cmd/fdt.c +++ b/cmd/fdt.c @@ -691,9 +691,9 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) fdt_strerror(err)); return CMD_RET_FAILURE; } -#ifdef CONFIG_ARCH_KEYSTONE - ft_board_setup_ex(working_fdt, gd->bd); -#endif + + if (IS_ENABLED(CONFIG_OF_BOARD_SETUP_EXTENDED)) + ft_board_setup_ex(working_fdt, gd->bd); } #endif /* Create a chosen node */ diff --git a/include/fdt_support.h b/include/fdt_support.h index 049190cf3d701db1f63d82c9a0223417ac9edc75..47b8b63d13dc515add480d1805c5e97998ecfc2b 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -240,11 +240,16 @@ int board_rng_seed(struct abuf *buf); */ const char *board_fdt_chosen_bootargs(const struct fdt_property *fdt_ba); -/* - * The keystone2 SOC requires all 32 bit aliased addresses to be converted - * to their 36 physical format. This has to happen after all fdt nodes - * are added or modified by the image_setup_libfdt(). The ft_board_setup_ex() - * called at the end of the image_setup_libfdt() is to do that convertion. +/** + * ft_board_setup_ex() - Latest board-specific FDT changes + * + * @blob: FDT blob to update + * @bd: Pointer to board data + * + * Execute board-specific device tree modifications that must be the latest FDT + * changes and cannot be overwritten by other system fixups. + * + * This function is called if CONFIG_OF_BOARD_SETUP_EXTENDED is defined. */ void ft_board_setup_ex(void *blob, struct bd_info *bd); -- 2.43.0