[POWERPC] Derive ebc ranges property from EBC registers
authorDavid Gibson <david@gibson.dropbear.id.au>
Wed, 13 Jun 2007 04:52:59 +0000 (14:52 +1000)
committerPaul Mackerras <paulus@samba.org>
Thu, 14 Jun 2007 12:30:16 +0000 (22:30 +1000)
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>
arch/powerpc/boot/44x.c
arch/powerpc/boot/44x.h
arch/powerpc/boot/dcr.h
arch/powerpc/boot/dts/ebony.dts
arch/powerpc/boot/ebony.c

index bc3f570ff9ba51877891a8b0fd66b9697590b94c..9f64e840bef628d062bdef0327afa8b9692b7420 100644 (file)
@@ -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));
+}
index 0da4abf390ada5b1dee0a07462f76f2058db7908..577982c9a3cd6f5de9653c8ee4f5e669cc74998d 100644 (file)
@@ -11,6 +11,7 @@
 #define _PPC_BOOT_44X_H_
 
 void ibm44x_fixup_memsize(void);
+void ibm4xx_fixup_ebc_ranges(const char *ebc);
 
 void ibm44x_dbcr_reset(void);
 void ebony_init(void *mac0, void *mac1);
index 877bc97b1e975752d8513aa0d54bd80dff3b7baf..14b44aa96feaabb42de57f51f87f3d64501488e4 100644 (file)
@@ -26,6 +26,43 @@ static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2C
 #define                        SDRAM_CONFIG_BANK_SIZE(reg)     \
        (0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17))
 
+/* 440GP External Bus Controller (EBC) */
+#define DCRN_EBC0_CFGADDR                              0x012
+#define DCRN_EBC0_CFGDATA                              0x013
+#define   EBC_NUM_BANKS                                          8
+#define   EBC_B0CR                                       0x00
+#define   EBC_B1CR                                       0x01
+#define   EBC_B2CR                                       0x02
+#define   EBC_B3CR                                       0x03
+#define   EBC_B4CR                                       0x04
+#define   EBC_B5CR                                       0x05
+#define   EBC_B6CR                                       0x06
+#define   EBC_B7CR                                       0x07
+#define   EBC_BXCR(n)                                    (n)
+#define            EBC_BXCR_BAS                                    0xfff00000
+#define            EBC_BXCR_BS                                     0x000e0000
+#define            EBC_BXCR_BANK_SIZE(reg) \
+       (0x100000 << (((reg) & EBC_BXCR_BS) >> 17))
+#define            EBC_BXCR_BU                                     0x00018000
+#define              EBC_BXCR_BU_OFF                                 0x00000000
+#define              EBC_BXCR_BU_RO                                  0x00008000
+#define              EBC_BXCR_BU_WO                                  0x00010000
+#define              EBC_BXCR_BU_RW                                  0x00018000
+#define            EBC_BXCR_BW                                     0x00006000
+#define   EBC_B0AP                                       0x10
+#define   EBC_B1AP                                       0x11
+#define   EBC_B2AP                                       0x12
+#define   EBC_B3AP                                       0x13
+#define   EBC_B4AP                                       0x14
+#define   EBC_B5AP                                       0x15
+#define   EBC_B6AP                                       0x16
+#define   EBC_B7AP                                       0x17
+#define   EBC_BXAP(n)                                    (0x10+(n))
+#define   EBC_BEAR                                       0x20
+#define   EBC_BESR                                       0x21
+#define   EBC_CFG                                        0x23
+#define   EBC_CID                                        0x24
+
 /* 440GP Clock, PM, chip control */
 #define DCRN_CPC0_SR                                   0x0b0
 #define DCRN_CPC0_ER                                   0x0b1
index 0ec02f4726b592f545dd387a13c152f71607e7cf..586a2fc13c638bf001e415096b624d268761d15b 100644 (file)
                                #address-cells = <2>;
                                #size-cells = <1>;
                                clock-frequency = <0>; // Filled in by zImage
-                               ranges = <0 00000000 fff00000 100000
-                                         1 00000000 48000000 100000
-                                         2 00000000 ff800000 400000
-                                         3 00000000 48200000 100000
-                                         7 00000000 48300000 100000>;
+                               // ranges property is supplied by zImage
+                               // based on firmware's configuration of the
+                               // EBC bridge
                                interrupts = <5 4>;
                                interrupt-parent = <&UIC1>;
 
index 634985802006c6b8921d3d21bb7077d7adec998b..75daedafd0a4d3c48f6924d54e7f6c8fbd3d656a 100644 (file)
@@ -100,6 +100,7 @@ static void ebony_fixups(void)
        ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
        ibm44x_fixup_memsize();
        dt_fixup_mac_addresses(ebony_mac0, ebony_mac1);
+       ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
 }
 
 void ebony_init(void *mac0, void *mac1)