diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index c15d564e40..fa1f55f838 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -349,6 +349,15 @@ config ROCKCHIP_VENDOR_PARTITION This enable support to read/write vendor configuration data from/to this partition. +config USING_KERNEL_DTB + bool "Using dtb from Kernel/resource for U-Boot" + depends on RKIMG_BOOTLOADER && OF_LIVE + default y + help + This enable support to read dtb from resource and use it for U-Boot, + the uart and emmc will still using U-Boot dtb, but other devices like + regulator/pmic, display, usb will use dts node from kernel. + config ROCKCHIP_CRC bool "Rockchip CRC verify images" help diff --git a/common/board_r.c b/common/board_r.c index 09167c13cc..8055c72581 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -103,6 +103,41 @@ static int initr_reloc(void) return 0; } +#ifdef CONFIG_USING_KERNEL_DTB +#include +#define DTB_FILE "rk-kernel.dtb" +int get_fdt_from_resource(void) +{ + int ret = 0; + struct mmc *mmc; + ulong fdt_addr = 0; + + mmc_initialize(gd->bd); + mmc = find_mmc_device(0); + if (!mmc) { + printf("no mmc device at slot 0\n"); + return -1; + } + ret = mmc_init(mmc); + if (ret) + printf("%s mmc init fail %d\n", __func__, ret); + + fdt_addr = env_get_ulong("fdt_addr_r", 16, 0); + if (!fdt_addr) { + printf("No Found FDT Load Address.\n"); + return -1; + } + + ret = rockchip_read_resource_file((void *)fdt_addr, DTB_FILE, 0, 0); + if (ret < 0) { + printf("%s dtb in resource read fail\n", __func__); + return 0; + } + gd->kernel_fdt = (void *)fdt_addr; + + return 0; +} +#endif #ifdef CONFIG_ARM /* @@ -698,6 +733,9 @@ static init_fnc_t init_sequence_r[] = { initr_noncached, #endif bootstage_relocate, +#ifdef CONFIG_USING_KERNEL_DTB + get_fdt_from_resource, +#endif #ifdef CONFIG_OF_LIVE initr_of_live, #endif diff --git a/drivers/core/root.c b/drivers/core/root.c index 976e2c4fdd..5525d74bc3 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -306,8 +306,20 @@ int dm_scan_fdt(const void *blob, bool pre_reloc_only) { #if CONFIG_IS_ENABLED(OF_LIVE) if (of_live_active()) +#ifndef CONFIG_USING_KERNEL_DTB return dm_scan_fdt_live(gd->dm_root, gd->of_root, pre_reloc_only); +#else + { + dm_scan_fdt_live(gd->dm_root, gd->of_root, + pre_reloc_only); + if (!gd->kernel_of_root) + return 0; + + return dm_scan_fdt_live(gd->dm_root, gd->kernel_of_root, + pre_reloc_only); + } +#endif else #endif return dm_scan_fdt_node(gd->dm_root, blob, 0, pre_reloc_only); diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 5aaa78b06a..591a431cf3 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -81,6 +81,10 @@ typedef struct global_data { unsigned long fdt_size; /* Space reserved for relocated FDT */ #ifdef CONFIG_OF_LIVE struct device_node *of_root; +#ifdef CONFIG_USING_KERNEL_DTB + void *kernel_fdt; /* Kernel FDT */ + struct device_node *kernel_of_root; +#endif #endif struct jt_funcs *jt; /* jump table */ char env_buf[32]; /* buffer for env_get() before reloc. */ diff --git a/lib/of_live.c b/lib/of_live.c index f351483387..12c9abcf89 100644 --- a/lib/of_live.c +++ b/lib/of_live.c @@ -332,6 +332,15 @@ int of_live_build(const void *fdt_blob, struct device_node **rootp) debug("Failed to scan live tree aliases: err=%d\n", ret); return ret; } +#ifdef CONFIG_USING_KERNEL_DTB + ret = unflatten_device_tree(gd->kernel_fdt, + (struct device_node **)&gd->kernel_of_root); + if (ret) { + printf("%s fail to build live dt from kernel dtb.\n", __func__); + return 0; + } + gd->fdt_blob = gd->kernel_fdt; +#endif debug("%s: stop\n", __func__); return ret;