[ifxmips] Calculate PCI BARMASK11 register value dynamicly, signed off by Ithamar...
[openwrt-10.03/.git] / target / linux / ifxmips / files / arch / mips / pci / pci-ifxmips.c
index 97efa37dd1403416bdf4e9a7a06d43a52d2fb8eb..64f37d556415c2c9a35181103468cc7be31e994a 100644 (file)
@@ -4,11 +4,11 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
-#include <asm/ifxmips/ifxmips.h>
-#include <asm/ifxmips/ifxmips_irq.h>
-#include <asm/ifxmips/ifxmips_cgu.h>
 #include <asm/addrspace.h>
 #include <linux/vmalloc.h>
+#include <ifxmips.h>
+#include <ifxmips_irq.h>
+#include <ifxmips_cgu.h>
 
 #define IFXMIPS_PCI_MEM_BASE    0x18000000
 #define IFXMIPS_PCI_MEM_SIZE    0x02000000
@@ -49,6 +49,8 @@ static struct pci_controller ifxmips_pci_controller =
        .io_offset      = 0x00000000UL,
 };
 
+/* the cpu can can generate the 33Mhz or rely on an external clock the cgu needs the
+   proper setting, otherwise the cpu hangs. we have no way of runtime detecting this */
 u32 ifxmips_pci_mapped_cfg;
 int ifxmips_pci_external_clock = 0;
 
@@ -87,6 +89,17 @@ pcibios_plat_dev_init(struct pci_dev *dev)
        return 0;
 }
 
+static u32 calc_bar11mask(void)
+{
+       u32 mem, bar11mask;
+
+       /* BAR11MASK value depends on available memory on system. */
+       mem = num_physpages * PAGE_SIZE;
+       bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) -1)) -1)) | 8;
+
+       return bar11mask;
+}
+
 static void __init
 ifxmips_pci_startup(void)
 {
@@ -136,7 +149,7 @@ ifxmips_pci_startup(void)
        ifxmips_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6);
        ifxmips_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
        ifxmips_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
-       ifxmips_w32(0x0e000008, PCI_CR_BAR11MASK);
+       ifxmips_w32(calc_bar11mask(), PCI_CR_BAR11MASK);
        ifxmips_w32(0, PCI_CR_PCI_ADDR_MAP11);
        ifxmips_w32(0, PCI_CS_BASE_ADDR1);
 #ifdef CONFIG_SWAP_IO_SPACE
@@ -173,7 +186,7 @@ pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin){
        }
 }
 
-int
+int __init
 pcibios_init(void)
 {
        extern int pci_probe_only;
@@ -181,7 +194,6 @@ pcibios_init(void)
        pci_probe_only = 0;
        printk("PCI: Probing PCI hardware on host bus 0.\n");
        ifxmips_pci_startup ();
-       //      IFXMIPS_PCI_REG32(PCI_CR_CLK_CTRL_REG) &= (~8);
        ifxmips_pci_mapped_cfg = (u32)ioremap_nocache(0x17000000, 0x800 * 16);
        printk("IFXMips PCI mapped to 0x%08lX\n", (unsigned long)ifxmips_pci_mapped_cfg);
        ifxmips_pci_controller.io_map_base = (unsigned long)ioremap(IFXMIPS_PCI_IO_BASE, IFXMIPS_PCI_IO_SIZE - 1);