diff options
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx/fdt.c')
-rw-r--r-- | arch/powerpc/cpu/mpc85xx/fdt.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index c62b12fb1d..8f13cd8ebf 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -639,3 +639,75 @@ void ft_cpu_setup(void *blob, bd_t *bd) do_fixup_by_compat_u32(blob, "fsl,flexcan-v1.0", "clock_freq", gd->bus_clk, 1); } + +/* + * For some CCSR devices, we only have the virtual address, not the physical + * address. This is because we map CCSR as a whole, so we typically don't need + * a macro for the physical address of any device within CCSR. In this case, + * we calculate the physical address of that device using it's the difference + * between the virtual address of the device and the virtual address of the + * beginning of CCSR. + */ +#define CCSR_VIRT_TO_PHYS(x) \ + (CONFIG_SYS_CCSRBAR_PHYS + ((x) - CONFIG_SYS_CCSRBAR)) + +/* + * Verify the device tree + * + * This function compares several CONFIG_xxx macros that contain physical + * addresses with the corresponding nodes in the device tree, to see if + * the physical addresses are all correct. For example, if + * CONFIG_SYS_NS16550_COM1 is defined, then it contains the virtual address + * of the first UART. We convert this to a physical address and compare + * that with the physical address of the first ns16550-compatible node + * in the device tree. If they don't match, then we display a warning. + * + * Returns 1 on success, 0 on failure + */ +int ft_verify_fdt(void *fdt) +{ + uint64_t ccsr = 0; + int aliases; + int off; + + /* First check the CCSR base address */ + off = fdt_node_offset_by_prop_value(fdt, -1, "device_type", "soc", 4); + if (off > 0) + ccsr = fdt_get_base_address(fdt, off); + + if (!ccsr) { + printf("Warning: could not determine base CCSR address in " + "device tree\n"); + /* No point in checking anything else */ + return 0; + } + + if (ccsr != CONFIG_SYS_CCSRBAR_PHYS) { + printf("Warning: U-Boot configured CCSR at address %llx,\n" + "but the device tree has it at %llx\n", + (uint64_t) CONFIG_SYS_CCSRBAR_PHYS, ccsr); + /* No point in checking anything else */ + return 0; + } + + /* + * Get the 'aliases' node. If there isn't one, then there's nothing + * left to do. + */ + aliases = fdt_path_offset(fdt, "/aliases"); + if (aliases > 0) { +#ifdef CONFIG_SYS_NS16550_COM1 + if (!fdt_verify_alias_address(fdt, aliases, "serial0", + CCSR_VIRT_TO_PHYS(CONFIG_SYS_NS16550_COM1))) + return 0; +#endif + +#ifdef CONFIG_SYS_NS16550_COM2 + if (!fdt_verify_alias_address(fdt, aliases, "serial1", + CCSR_VIRT_TO_PHYS(CONFIG_SYS_NS16550_COM2))) + return 0; +#endif + } + + return 1; +} |