[U-Boot] [PATCH v2 4/6] PPC 85xx: Find CCSRBAR on ppce500 from device tree

Alexander Graf agraf at suse.de
Fri Jan 31 12:16:07 CET 2014


The definition of our ppce500 PV machine is that every address is dynamically
determined through device tree bindings.

So don't hardcode where CCSR is in our physical memory layout but instead
read it dynamically from the device tree we get passed on boot.

Signed-off-by: Alexander Graf <agraf at suse.de>
---
 arch/powerpc/cpu/mpc85xx/start.S            |    2 +
 board/freescale/qemu-ppce500/qemu-ppce500.c |   83 +++++++++++++++++++++++++++
 include/configs/qemu-ppce500.h              |   12 +++-
 3 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/cpu/mpc85xx/start.S b/arch/powerpc/cpu/mpc85xx/start.S
index 0e593d2..2672c20 100644
--- a/arch/powerpc/cpu/mpc85xx/start.S
+++ b/arch/powerpc/cpu/mpc85xx/start.S
@@ -519,6 +519,7 @@ nexti:	mflr	r1		/* R1 = our PC */
  * As a general rule, TLB0 is used for short-term TLBs, and TLB1 is used for
  * long-term TLBs, so we use TLB0 here.
  */
+#if !defined(CONFIG_DYNAMIC_CCSRBAR)
 #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS)
 
 #if !defined(CONFIG_SYS_CCSRBAR_PHYS_HIGH) || !defined(CONFIG_SYS_CCSRBAR_PHYS_LOW)
@@ -703,6 +704,7 @@ delete_temp_tlbs:
 	delete_tlb0_entry 1, CONFIG_SYS_CCSRBAR + 0x1000, MAS2_I|MAS2_G, r3
 
 #endif /* #if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) */
+#endif /* #if !defined(CONFIG_DYNAMIC_CCSRBAR) */
 
 #if defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && defined(CONFIG_E6500)
 create_ccsr_l2_tlb:
diff --git a/board/freescale/qemu-ppce500/qemu-ppce500.c b/board/freescale/qemu-ppce500/qemu-ppce500.c
index b33b6b1..6491ae9 100644
--- a/board/freescale/qemu-ppce500/qemu-ppce500.c
+++ b/board/freescale/qemu-ppce500/qemu-ppce500.c
@@ -26,6 +26,89 @@ static const void *get_fdt(void)
 	return gd->fdt_blob;
 }
 
+uint64_t get_phys_ccsrbar_addr(void)
+{
+	const void *fdt = get_fdt();
+	int root_node = fdt_path_offset(fdt, "/");
+	int soc_node = fdt_path_offset(fdt, "/soc");
+	const uint32_t *prop;
+	const uint64_t *prop64;
+	int len;
+	int root_address_cells = 1;
+	int address_cells = 1;
+	uint64_t r = 0;
+
+	/* Read CCSRBAR address length and size from device tree */
+	prop = fdt_getprop(fdt, root_node, "#address-cells", &len);
+	if (prop && (len >= 4))
+		root_address_cells = prop[0];
+
+	prop = fdt_getprop(fdt, soc_node, "#address-cells", &len);
+	if (prop && (len >= 4))
+		address_cells = prop[0];
+
+	/* Read CCSRBAR address from device tree */
+	prop = fdt_getprop(fdt, soc_node, "ranges", &len);
+	if (prop && (len >= ((address_cells + root_address_cells) * 4))) {
+		/* The physical address starts after the child's offset */
+		prop += address_cells;
+		prop64 = (const uint64_t *)prop;
+
+		if (root_address_cells == 1)
+			r = prop[0];
+		else if (root_address_cells == 2)
+			r = prop64[0];
+	}
+
+	if (!r)
+		panic("Couldn't find CCSR in FDT");
+
+	return r;
+}
+
+uint64_t get_phys_ccsrbar_addr_early(void)
+{
+	u32 mas0, mas1, mas2, mas3, mas7;
+	ulong fdt = (ulong)get_fdt();
+	uint64_t r;
+
+	/*
+	 * To be able to read the FDT we need to create a temporary TLB
+	 * map for it.
+	 */
+
+	mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(10);
+	mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_1M);
+	mas2 = FSL_BOOKE_MAS2(fdt, 0);
+	mas3 = FSL_BOOKE_MAS3(fdt, 0, MAS3_SW|MAS3_SR);
+	mas7 = FSL_BOOKE_MAS7(fdt);
+
+	write_tlb(mas0, mas1, mas2, mas3, mas7);
+
+	r = get_phys_ccsrbar_addr();
+
+	disable_tlb(10);
+
+	return r;
+}
+
+int board_early_init_f(void)
+{
+	u32 mas0, mas1, mas2, mas3, mas7;
+	uint64_t phys_ccsr_address = get_phys_ccsrbar_addr();
+
+	/* Extend the CCSR map from cpu_init_early_f() */
+	mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(13);
+	mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TSIZE(BOOKE_PAGESZ_64M);
+	mas2 = FSL_BOOKE_MAS2(CONFIG_SYS_CCSRBAR, MAS2_I|MAS2_G);
+	mas3 = FSL_BOOKE_MAS3(phys_ccsr_address, 0, MAS3_SW|MAS3_SR);
+	mas7 = FSL_BOOKE_MAS7(phys_ccsr_address);
+
+	write_tlb(mas0, mas1, mas2, mas3, mas7);
+
+	return 0;
+}
+
 int checkboard(void)
 {
 	return 0;
diff --git a/include/configs/qemu-ppce500.h b/include/configs/qemu-ppce500.h
index 1ebaf51..7ef7235 100644
--- a/include/configs/qemu-ppce500.h
+++ b/include/configs/qemu-ppce500.h
@@ -44,8 +44,18 @@
 #define CONFIG_SYS_ALT_MEMTEST
 #define CONFIG_PANIC_HANG	/* do not reset board on panic */
 
+/* Needed to fill the ccsrbar pointer */
+#define CONFIG_BOARD_EARLY_INIT_F
+
+/* Virtual address to CCSRBAR */
 #define CONFIG_SYS_CCSRBAR		0xe0000000
-#define CONFIG_SYS_CCSRBAR_PHYS_LOW	CONFIG_SYS_CCSRBAR
+/* Physical address should be a function call */
+#ifndef __ASSEMBLY__
+extern unsigned long long get_phys_ccsrbar_addr_early(void);
+#endif
+#define CONFIG_SYS_CCSRBAR_PHYS_LOW	((uint32_t)get_phys_ccsrbar_addr_early())
+#define CONFIG_SYS_CCSRBAR_PHYS_HIGH	(get_phys_ccsrbar_addr_early() >> 32)
+#define CONFIG_DYNAMIC_CCSRBAR
 
 /*
  * DDR Setup
-- 
1.7.10.4



More information about the U-Boot mailing list