summaryrefslogtreecommitdiff
path: root/arch/powerpc/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/cpu')
-rw-r--r--arch/powerpc/cpu/mpc85xx/fdt.c72
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;
+}