rockchip: add support to load and use kernel dtb

We are going to use a tiny dtb(with 'u-boot,dm-pre-reloc') in pre-relocate,
and then read kernel dtb and use it after relocate.
This feature only works with CONFIG_OF_LIVE enabled now.

Change-Id: I429ccd90ef562a96f2f7916255e7e427ce8f451d
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
This commit is contained in:
Kever Yang 2018-01-24 14:45:14 +08:00
parent d8a49a2f32
commit af586a3812
5 changed files with 72 additions and 0 deletions

View File

@ -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

View File

@ -103,6 +103,41 @@ static int initr_reloc(void)
return 0;
}
#ifdef CONFIG_USING_KERNEL_DTB
#include <asm/arch/resource_img.h>
#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

View File

@ -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);

View File

@ -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. */

View File

@ -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;