tree-wide: fix assorted typos all over the place
[safe/jmp/linux-2.6] / arch / powerpc / platforms / powermac / pci.c
index 6bbf3c8..ab2027c 100644 (file)
@@ -40,8 +40,6 @@
 static int has_uninorth;
 #ifdef CONFIG_PPC64
 static struct pci_controller *u3_agp;
-static struct pci_controller *u4_pcie;
-static struct pci_controller *u3_ht;
 #else
 static int has_second_ohare;
 #endif /* CONFIG_PPC64 */
@@ -304,7 +302,7 @@ static void __init setup_chaos(struct pci_controller *hose,
  *  1 -> Skip the device but act as if the access was successfull
  *       (return 0xff's on reads, eventually, cache config space
  *       accesses in a later version)
- * -1 -> Hide the device (unsuccessful acess)
+ * -1 -> Hide the device (unsuccessful access)
  */
 static int u3_ht_skip_device(struct pci_controller *hose,
                             struct pci_bus *bus, unsigned int devfn)
@@ -314,10 +312,13 @@ static int u3_ht_skip_device(struct pci_controller *hose,
 
        /* We only allow config cycles to devices that are in OF device-tree
         * as we are apparently having some weird things going on with some
-        * revs of K2 on recent G5s
+        * revs of K2 on recent G5s, except for the host bridge itself, which
+        * is missing from the tree but we know we can probe.
         */
        if (bus->self)
                busdn = pci_device_to_OF_node(bus->self);
+       else if (devfn == 0)
+               return 0;
        else
                busdn = hose->dn;
        for (dn = busdn->child; dn; dn = dn->sibling)
@@ -344,14 +345,15 @@ static int u3_ht_skip_device(struct pci_controller *hose,
                + (((unsigned int)bus) << 16) \
                + 0x01000000UL)
 
-static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose,
-                                            u8 bus, u8 devfn, u8 offset)
+static void __iomem *u3_ht_cfg_access(struct pci_controller *hose, u8 bus,
+                                     u8 devfn, u8 offset, int *swap)
 {
+       *swap = 1;
        if (bus == hose->first_busno) {
-               /* For now, we don't self probe U3 HT bridge */
-               if (PCI_SLOT(devfn) == 0)
-                       return NULL;
-               return hose->cfg_data + U3_HT_CFA0(devfn, offset);
+               if (devfn != 0)
+                       return hose->cfg_data + U3_HT_CFA0(devfn, offset);
+               *swap = 0;
+               return ((void __iomem *)hose->cfg_addr) + (offset << 2);
        } else
                return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
 }
@@ -360,14 +362,15 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
                                    int offset, int len, u32 *val)
 {
        struct pci_controller *hose;
-       volatile void __iomem *addr;
+       void __iomem *addr;
+       int swap;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
        if (offset >= 0x100)
                return  PCIBIOS_BAD_REGISTER_NUMBER;
-       addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+       addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap);
        if (!addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -397,10 +400,10 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
                *val = in_8(addr);
                break;
        case 2:
-               *val = in_le16(addr);
+               *val = swap ? in_le16(addr) : in_be16(addr);
                break;
        default:
-               *val = in_le32(addr);
+               *val = swap ? in_le32(addr) : in_be32(addr);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -410,14 +413,15 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
        struct pci_controller *hose;
-       volatile void __iomem *addr;
+       void __iomem *addr;
+       int swap;
 
        hose = pci_bus_to_host(bus);
        if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
        if (offset >= 0x100)
                return  PCIBIOS_BAD_REGISTER_NUMBER;
-       addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
+       addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap);
        if (!addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -439,10 +443,10 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
                out_8(addr, val);
                break;
        case 2:
-               out_le16(addr, val);
+               swap ? out_le16(addr, val) : out_be16(addr, val);
                break;
        default:
-               out_le32((u32 __iomem *)addr, val);
+               swap ? out_le32(addr, val) : out_be32(addr, val);
                break;
        }
        return PCIBIOS_SUCCESSFUL;
@@ -657,6 +661,7 @@ static void __init init_second_ohare(void)
                        pci_find_hose_for_OF_device(np);
                if (!hose) {
                        printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
+                       of_node_put(np);
                        return;
                }
                early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
@@ -665,6 +670,7 @@ static void __init init_second_ohare(void)
                early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
        }
        has_second_ohare = 1;
+       of_node_put(np);
 }
 
 /*
@@ -725,7 +731,7 @@ static void __init setup_bandit(struct pci_controller *hose,
 static int __init setup_uninorth(struct pci_controller *hose,
                                 struct resource *addr)
 {
-       ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+       ppc_pci_add_flags(PPC_PCI_REASSIGN_ALL_BUS);
        has_uninorth = 1;
        hose->ops = &macrisc_pci_ops;
        hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
@@ -773,31 +779,72 @@ static void __init setup_u4_pcie(struct pci_controller* hose)
         */
        hose->first_busno = 0x00;
        hose->last_busno = 0xff;
-       u4_pcie = hose;
+}
+
+static void __init parse_region_decode(struct pci_controller *hose,
+                                      u32 decode)
+{
+       unsigned long base, end, next = -1;
+       int i, cur = -1;
+
+       /* Iterate through all bits. We ignore the last bit as this region is
+        * reserved for the ROM among other niceties
+        */
+       for (i = 0; i < 31; i++) {
+               if ((decode & (0x80000000 >> i)) == 0)
+                       continue;
+               if (i < 16) {
+                       base = 0xf0000000 | (((u32)i) << 24);
+                       end = base + 0x00ffffff;
+               } else {
+                       base = ((u32)i-16) << 28;
+                       end = base + 0x0fffffff;
+               }
+               if (base != next) {
+                       if (++cur >= 3) {
+                               printk(KERN_WARNING "PCI: Too many ranges !\n");
+                               break;
+                       }
+                       hose->mem_resources[cur].flags = IORESOURCE_MEM;
+                       hose->mem_resources[cur].name = hose->dn->full_name;
+                       hose->mem_resources[cur].start = base;
+                       hose->mem_resources[cur].end = end;
+                       DBG("  %d: 0x%08lx-0x%08lx\n", cur, base, end);
+               } else {
+                       DBG("   :           -0x%08lx\n", end);
+                       hose->mem_resources[cur].end = end;
+               }
+               next = end + 1;
+       }
 }
 
 static void __init setup_u3_ht(struct pci_controller* hose)
 {
        struct device_node *np = hose->dn;
-       struct pci_controller *other = NULL;
-       int i, cur;
-
+       struct resource cfg_res, self_res;
+       u32 decode;
 
        hose->ops = &u3_ht_pci_ops;
 
-       /* We hard code the address because of the different size of
-        * the reg address cell, we shall fix that by killing struct
-        * reg_property and using some accessor functions instead
+       /* Get base addresses from OF tree
         */
-       hose->cfg_data = ioremap(0xf2000000, 0x02000000);
+       if (of_address_to_resource(np, 0, &cfg_res) ||
+           of_address_to_resource(np, 1, &self_res)) {
+               printk(KERN_ERR "PCI: Failed to get U3/U4 HT resources !\n");
+               return;
+       }
+
+       /* Map external cfg space access into cfg_data and self registers
+        * into cfg_addr
+        */
+       hose->cfg_data = ioremap(cfg_res.start, 0x02000000);
+       hose->cfg_addr = ioremap(self_res.start,
+                                self_res.end - self_res.start + 1);
 
        /*
-        * /ht node doesn't expose a "ranges" property, so we "remove"
-        * regions that have been allocated to AGP. So far, this version of
-        * the code doesn't assign any of the 0xfxxxxxxx "fine" memory regions
-        * to /ht. We need to fix that sooner or later by either parsing all
-        * child "ranges" properties or figuring out the U3 address space
-        * decoding logic and then read its configuration register (if any).
+        * /ht node doesn't expose a "ranges" property, we read the register
+        * that controls the decoding logic and use that for memory regions.
+        * The IO region is hard coded since it is fixed in HW as well.
         */
        hose->io_base_phys = 0xf4000000;
        hose->pci_io_size = 0x00400000;
@@ -808,76 +855,33 @@ static void __init setup_u3_ht(struct pci_controller* hose)
        hose->pci_mem_offset = 0;
        hose->first_busno = 0;
        hose->last_busno = 0xef;
-       hose->mem_resources[0].name = np->full_name;
-       hose->mem_resources[0].start = 0x80000000;
-       hose->mem_resources[0].end = 0xefffffff;
-       hose->mem_resources[0].flags = IORESOURCE_MEM;
-
-       u3_ht = hose;
 
-       if (u3_agp != NULL)
-               other = u3_agp;
-       else if (u4_pcie != NULL)
-               other = u4_pcie;
-
-       if (other == NULL) {
-               DBG("U3/4 has no AGP/PCIE, using full resource range\n");
-               return;
-       }
+       /* Note: fix offset when cfg_addr becomes a void * */
+       decode = in_be32(hose->cfg_addr + 0x80);
 
-       /* Fixup bus range vs. PCIE */
-       if (u4_pcie)
-               hose->last_busno = u4_pcie->first_busno - 1;
+       DBG("PCI: Apple HT bridge decode register: 0x%08x\n", decode);
 
-       /* We "remove" the AGP resources from the resources allocated to HT,
-        * that is we create "holes". However, that code does assumptions
-        * that so far happen to be true (cross fingers...), typically that
-        * resources in the AGP node are properly ordered
+       /* NOTE: The decode register setup is a bit weird... region
+        * 0xf8000000 for example is marked as enabled in there while it's
+        & actually the memory controller registers.
+        * That means that we are incorrectly attributing it to HT.
+        *
+        * In a similar vein, region 0xf4000000 is actually the HT IO space but
+        * also marked as enabled in here and 0xf9000000 is used by some other
+        * internal bits of the northbridge.
+        *
+        * Unfortunately, we can't just mask out those bit as we would end
+        * up with more regions than we can cope (linux can only cope with
+        * 3 memory regions for a PHB at this stage).
+        *
+        * So for now, we just do a little hack. We happen to -know- that
+        * Apple firmware doesn't assign things below 0xfa000000 for that
+        * bridge anyway so we mask out all bits we don't want.
         */
-       cur = 0;
-       for (i=0; i<3; i++) {
-               struct resource *res = &other->mem_resources[i];
-               if (res->flags != IORESOURCE_MEM)
-                       continue;
-               /* We don't care about "fine" resources */
-               if (res->start >= 0xf0000000)
-                       continue;
-               /* Check if it's just a matter of "shrinking" us in one
-                * direction
-                */
-               if (hose->mem_resources[cur].start == res->start) {
-                       DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
-                           cur, hose->mem_resources[cur].start,
-                           res->end + 1);
-                       hose->mem_resources[cur].start = res->end + 1;
-                       continue;
-               }
-               if (hose->mem_resources[cur].end == res->end) {
-                       DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
-                           cur, hose->mem_resources[cur].end,
-                           res->start - 1);
-                       hose->mem_resources[cur].end = res->start - 1;
-                       continue;
-               }
-               /* No, it's not the case, we need a hole */
-               if (cur == 2) {
-                       /* not enough resources for a hole, we drop part
-                        * of the range
-                        */
-                       printk(KERN_WARNING "Running out of resources"
-                              " for /ht host !\n");
-                       hose->mem_resources[cur].end = res->start - 1;
-                       continue;
-               }
-               cur++;
-               DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
-                   cur-1, res->start - 1, cur, res->end + 1);
-               hose->mem_resources[cur].name = np->full_name;
-               hose->mem_resources[cur].flags = IORESOURCE_MEM;
-               hose->mem_resources[cur].start = res->end + 1;
-               hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
-               hose->mem_resources[cur-1].end = res->start - 1;
-       }
+       decode &= 0x003fffff;
+
+       /* Now parse the resulting bits and build resources */
+       parse_region_decode(hose, decode);
 }
 #endif /* CONFIG_PPC64 */
 
@@ -994,7 +998,7 @@ void __init pmac_pci_init(void)
        struct device_node *np, *root;
        struct device_node *ht = NULL;
 
-       ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN;
+       ppc_pci_set_flags(PPC_PCI_CAN_SKIP_ISA_ALIGN);
 
        root = of_find_node_by_path("/");
        if (root == NULL) {
@@ -1041,8 +1045,8 @@ void __init pmac_pci_init(void)
        }
        /* pmac_check_ht_link(); */
 
-       /* Tell pci.c to not use the common resource allocation mechanism */
-       pci_probe_only = 1;
+       /* We can allocate missing resources if any */
+       pci_probe_only = 0;
 
 #else /* CONFIG_PPC64 */
        init_p2pbridge();
@@ -1053,13 +1057,13 @@ void __init pmac_pci_init(void)
         * some offset between bus number and domains for now when we
         * assign all busses should help for now
         */
-       if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
+       if (ppc_pci_has_flag(PPC_PCI_REASSIGN_ALL_BUS))
                pcibios_assign_bus_offset = 0x10;
 #endif
 }
 
-int
-pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
+#ifdef CONFIG_PPC32
+int pmac_pci_enable_device_hook(struct pci_dev *dev)
 {
        struct device_node* node;
        int updatecfg = 0;
@@ -1101,24 +1105,21 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
                updatecfg = 1;
        }
 
+       /*
+        * Fixup various header fields on 32 bits. We don't do that on
+        * 64 bits as some of these have strange values behind the HT
+        * bridge and we must not, for example, enable MWI or set the
+        * cache line size on them.
+        */
        if (updatecfg) {
                u16 cmd;
 
-               /*
-                * Make sure PCI is correctly configured
-                *
-                * We use old pci_bios versions of the function since, by
-                * default, gmac is not powered up, and so will be absent
-                * from the kernel initial PCI lookup.
-                *
-                * Should be replaced by 2.4 new PCI mechanisms and really
-                * register the device.
-                */
                pci_read_config_word(dev, PCI_COMMAND, &cmd);
                cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
                        | PCI_COMMAND_INVALIDATE;
                pci_write_config_word(dev, PCI_COMMAND, cmd);
                pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
+
                pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
                                      L1_CACHE_BYTES >> 2);
        }
@@ -1126,6 +1127,18 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
        return 0;
 }
 
+void __devinit pmac_pci_fixup_ohci(struct pci_dev *dev)
+{
+       struct device_node *node = pci_device_to_OF_node(dev);
+
+       /* We don't want to assign resources to USB controllers
+        * absent from the OF tree (iBook second controller)
+        */
+       if (dev->class == PCI_CLASS_SERIAL_USB_OHCI && !node)
+               dev->resource[0].flags = 0;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_ANY_ID, pmac_pci_fixup_ohci);
+
 /* We power down some devices after they have been probed. They'll
  * be powered back on later on
  */
@@ -1133,28 +1146,6 @@ void __init pmac_pcibios_after_init(void)
 {
        struct device_node* nd;
 
-#ifdef CONFIG_BLK_DEV_IDE
-       struct pci_dev *dev = NULL;
-
-       /* OF fails to initialize IDE controllers on macs
-        * (and maybe other machines)
-        *
-        * Ideally, this should be moved to the IDE layer, but we need
-        * to check specifically with Andre Hedrick how to do it cleanly
-        * since the common IDE code seem to care about the fact that the
-        * BIOS may have disabled a controller.
-        *
-        * -- BenH
-        */
-       for_each_pci_dev(dev) {
-               if ((dev->class >> 16) != PCI_BASE_CLASS_STORAGE)
-                       continue;
-               if (pci_enable_device(dev))
-                       printk(KERN_WARNING
-                              "pci: Failed to enable %s\n", pci_name(dev));
-       }
-#endif /* CONFIG_BLK_DEV_IDE */
-
        for_each_node_by_name(nd, "firewire") {
                if (nd->parent && (of_device_is_compatible(nd, "pci106b,18") ||
                                   of_device_is_compatible(nd, "pci106b,30") ||
@@ -1173,7 +1164,6 @@ void __init pmac_pcibios_after_init(void)
        of_node_put(nd);
 }
 
-#ifdef CONFIG_PPC32
 void pmac_pci_fixup_cardbus(struct pci_dev* dev)
 {
        if (!machine_is(powermac))
@@ -1261,7 +1251,7 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev)
        }
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
-#endif
+#endif /* CONFIG_PPC32 */
 
 /*
  * Disable second function on K2-SATA, it's broken
@@ -1296,3 +1286,64 @@ static void fixup_k2_sata(struct pci_dev* dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
 
+/*
+ * On U4 (aka CPC945) the PCIe root complex "P2P" bridge resource ranges aren't
+ * configured by the firmware. The bridge itself seems to ignore them but it
+ * causes problems with Linux which then re-assigns devices below the bridge,
+ * thus changing addresses of those devices from what was in the device-tree,
+ * which sucks when those are video cards using offb
+ *
+ * We could just mark it transparent but I prefer fixing up the resources to
+ * properly show what's going on here, as I have some doubts about having them
+ * badly configured potentially being an issue for DMA.
+ *
+ * We leave PIO alone, it seems to be fine
+ *
+ * Oh and there's another funny bug. The OF properties advertize the region
+ * 0xf1000000..0xf1ffffff as being forwarded as memory space. But that's
+ * actually not true, this region is the memory mapped config space. So we
+ * also need to filter it out or we'll map things in the wrong place.
+ */
+static void fixup_u4_pcie(struct pci_dev* dev)
+{
+       struct pci_controller *host = pci_bus_to_host(dev->bus);
+       struct resource *region = NULL;
+       u32 reg;
+       int i;
+
+       /* Only do that on PowerMac */
+       if (!machine_is(powermac))
+               return;
+
+       /* Find the largest MMIO region */
+       for (i = 0; i < 3; i++) {
+               struct resource *r = &host->mem_resources[i];
+               if (!(r->flags & IORESOURCE_MEM))
+                       continue;
+               /* Skip the 0xf0xxxxxx..f2xxxxxx regions, we know they
+                * are reserved by HW for other things
+                */
+               if (r->start >= 0xf0000000 && r->start < 0xf3000000)
+                       continue;
+               if (!region || (r->end - r->start) >
+                   (region->end - region->start))
+                       region = r;
+       }
+       /* Nothing found, bail */
+       if (region == 0)
+               return;
+
+       /* Print things out */
+       printk(KERN_INFO "PCI: Fixup U4 PCIe bridge range: %pR\n", region);
+
+       /* Fixup bridge config space. We know it's a Mac, resource aren't
+        * offset so let's just blast them as-is. We also know that they
+        * fit in 32 bits
+        */
+       reg = ((region->start >> 16) & 0xfff0) | (region->end & 0xfff00000);
+       pci_write_config_dword(dev, PCI_MEMORY_BASE, reg);
+       pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0);
+       pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
+       pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U4_PCIE, fixup_u4_pcie);