summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/44x.c
diff options
context:
space:
mode:
authorDavid Gibson2007-06-13 06:52:59 +0200
committerPaul Mackerras2007-06-14 14:30:16 +0200
commitb2ba34f370a66d9ed4bbd440e45296ecf3e267d3 (patch)
tree9a743c7b356f5ceba15b3008588126fdced94fb8 /arch/powerpc/boot/44x.c
parent[POWERPC] Factor zImage's 44x reset code out of ebony.c (diff)
downloadkernel-qcow2-linux-b2ba34f370a66d9ed4bbd440e45296ecf3e267d3.tar.gz
kernel-qcow2-linux-b2ba34f370a66d9ed4bbd440e45296ecf3e267d3.tar.xz
kernel-qcow2-linux-b2ba34f370a66d9ed4bbd440e45296ecf3e267d3.zip
[POWERPC] Derive ebc ranges property from EBC registers
In the device tree for Ebony, the 'ranges' property in the node for the EBC bridge shows the mappings from the chip select / address lines actually used for the EBC peripherals into the address space of the OPB. At present, these mappings are hardcoded in ebony.dts for the mappings set up by the OpenBIOS firmware when it configures the EBC bridge. This replaces the hardcoded mappings with code in the zImage to read the EBC configuration registers and create an appropriate ranges property based on them. This should make the zImage and kernel more robust to changes in firmware configuration. In particular, some of the Ebony's DIP switches can change the effective address of the Flash and other peripherals in OPB space. With this patch, the kernel will be able to cope with at least some of the possible variations. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/boot/44x.c')
-rw-r--r--arch/powerpc/boot/44x.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/powerpc/boot/44x.c b/arch/powerpc/boot/44x.c
index bc3f570ff9ba..9f64e840bef6 100644
--- a/arch/powerpc/boot/44x.c
+++ b/arch/powerpc/boot/44x.c
@@ -54,3 +54,32 @@ void ibm44x_dbcr_reset(void)
);
}
+
+/* Read 4xx EBC bus bridge registers to get mappings of the peripheral
+ * banks into the OPB address space */
+void ibm4xx_fixup_ebc_ranges(const char *ebc)
+{
+ void *devp;
+ u32 bxcr;
+ u32 ranges[EBC_NUM_BANKS*4];
+ u32 *p = ranges;
+ int i;
+
+ for (i = 0; i < EBC_NUM_BANKS; i++) {
+ mtdcr(DCRN_EBC0_CFGADDR, EBC_BXCR(i));
+ bxcr = mfdcr(DCRN_EBC0_CFGDATA);
+
+ if ((bxcr & EBC_BXCR_BU) != EBC_BXCR_BU_OFF) {
+ *p++ = i;
+ *p++ = 0;
+ *p++ = bxcr & EBC_BXCR_BAS;
+ *p++ = EBC_BXCR_BANK_SIZE(bxcr);
+ }
+ }
+
+ devp = finddevice(ebc);
+ if (! devp)
+ fatal("Couldn't locate EBC node %s\n\r", ebc);
+
+ setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32));
+}