[POWERPC] cuboot-pq2: PCI fixes
authorScott Wood <scottwood@freescale.com>
Tue, 15 Apr 2008 16:02:31 +0000 (11:02 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Thu, 17 Apr 2008 06:01:40 +0000 (01:01 -0500)
1. Detect (and bail out on) more conditions that violate the
assumptions of the setup code -- we assume in such cases that the device
tree is correct and reflects what the firmware did.

2. The inbound memory mask calculation was wrong.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
arch/powerpc/boot/cuboot-pq2.c

index f56ac6cae9f3b291c1744a21958dc27d2e487a28..9c7d13428293cb9ff90cb35ef6cdebc1a3fabccb 100644 (file)
@@ -128,7 +128,7 @@ static void fixup_pci(void)
        u8 *soc_regs;
        int i, len;
        void *node, *parent_node;
-       u32 naddr, nsize, mem_log2;
+       u32 naddr, nsize, mem_pow2, mem_mask;
 
        node = finddevice("/pci");
        if (!node || !dt_is_compatible(node, "fsl,pq2-pci"))
@@ -141,7 +141,7 @@ static void fixup_pci(void)
 
        soc_regs = (u8 *)fsl_get_immr();
        if (!soc_regs)
-               goto err;
+               goto unhandled;
 
        dt_get_reg_format(node, &naddr, &nsize);
        if (naddr != 3 || nsize != 2)
@@ -153,7 +153,7 @@ static void fixup_pci(void)
 
        dt_get_reg_format(parent_node, &naddr, &nsize);
        if (naddr != 1 || nsize != 1)
-               goto err;
+               goto unhandled;
 
        len = getprop(node, "ranges", pci_ranges_buf,
                      sizeof(pci_ranges_buf));
@@ -170,14 +170,20 @@ static void fixup_pci(void)
        }
 
        if (!mem || !mmio || !io)
-               goto err;
+               goto unhandled;
+       if (mem->size[1] != mmio->size[1])
+               goto unhandled;
+       if (mem->size[1] & (mem->size[1] - 1))
+               goto unhandled;
+       if (io->size[1] & (io->size[1] - 1))
+               goto unhandled;
 
        if (mem->phys_addr + mem->size[1] == mmio->phys_addr)
                mem_base = mem;
        else if (mmio->phys_addr + mmio->size[1] == mem->phys_addr)
                mem_base = mmio;
        else
-               goto err;
+               goto unhandled;
 
        out_be32(&pci_regs[1][0], mem_base->phys_addr | 1);
        out_be32(&pci_regs[2][0], ~(mem->size[1] + mmio->size[1] - 1));
@@ -201,8 +207,9 @@ static void fixup_pci(void)
        out_le32(&pci_regs[0][58], 0);
        out_le32(&pci_regs[0][60], 0);
 
-       mem_log2 = 1 << (__ilog2_u32(bd.bi_memsize - 1) + 1);
-       out_le32(&pci_regs[0][62], 0xa0000000 | ~((1 << (mem_log2 - 12)) - 1));
+       mem_pow2 = 1 << (__ilog2_u32(bd.bi_memsize - 1) + 1);
+       mem_mask = ~(mem_pow2 - 1) >> 12;
+       out_le32(&pci_regs[0][62], 0xa0000000 | mem_mask);
 
        /* If PCI is disabled, drive RST high to enable. */
        if (!(in_le32(&pci_regs[0][32]) & 1)) {
@@ -228,7 +235,11 @@ static void fixup_pci(void)
        return;
 
 err:
-       printf("Bad PCI node\r\n");
+       printf("Bad PCI node -- using existing firmware setup.\r\n");
+       return;
+
+unhandled:
+       printf("Unsupported PCI node -- using existing firmware setup.\r\n");
 }
 
 static void pq2_platform_fixups(void)