]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/sysdev/fsl_pci.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6-omap-h63xx.git] / arch / powerpc / sysdev / fsl_pci.c
index 10c47b56702ef56c9b6a1d544393632a2d27c0f6..33df4c347ca7cb69cae3d8f945afb168695c011f 100644 (file)
@@ -89,19 +89,34 @@ void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc)
 void __init setup_pci_cmd(struct pci_controller *hose)
 {
        u16 cmd;
+       int cap_x;
+
        early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd);
        cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
                | PCI_COMMAND_IO;
        early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
-       early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
+
+       cap_x = early_find_capability(hose, 0, 0, PCI_CAP_ID_PCIX);
+       if (cap_x) {
+               int pci_x_cmd = cap_x + PCI_X_CMD;
+               cmd = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
+                       | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
+               early_write_config_word(hose, 0, 0, pci_x_cmd, cmd);
+       } else {
+               early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
+       }
 }
 
-static void __devinit quirk_fsl_pcie_transparent(struct pci_dev *dev)
+static void __init quirk_fsl_pcie_transparent(struct pci_dev *dev)
 {
        struct resource *res;
        int i, res_idx = PCI_BRIDGE_RESOURCES;
        struct pci_controller *hose;
 
+       /* if we aren't a PCIe don't bother */
+       if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
+               return ;
+
        /*
         * Make the bridge be transparent.
         */
@@ -114,11 +129,24 @@ static void __devinit quirk_fsl_pcie_transparent(struct pci_dev *dev)
                return;
        }
 
+       /* Clear out any of the virtual P2P bridge registers */
+       pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0);
+       pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, 0);
+       pci_write_config_byte(dev, PCI_IO_BASE, 0x10);
+       pci_write_config_byte(dev, PCI_IO_LIMIT, 0);
+       pci_write_config_word(dev, PCI_MEMORY_BASE, 0x10);
+       pci_write_config_word(dev, PCI_MEMORY_LIMIT, 0);
+       pci_write_config_word(dev, PCI_PREF_BASE_UPPER32, 0x0);
+       pci_write_config_word(dev, PCI_PREF_LIMIT_UPPER32, 0x0);
+       pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x10);
+       pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0);
+
        if (hose->io_resource.flags) {
                res = &dev->resource[res_idx++];
                res->start = hose->io_resource.start;
                res->end = hose->io_resource.end;
                res->flags = hose->io_resource.flags;
+               update_bridge_resource(dev, res);
        }
 
        for (i = 0; i < 3; i++) {
@@ -126,18 +154,33 @@ static void __devinit quirk_fsl_pcie_transparent(struct pci_dev *dev)
                res->start = hose->mem_resources[i].start;
                res->end = hose->mem_resources[i].end;
                res->flags = hose->mem_resources[i].flags;
+               update_bridge_resource(dev, res);
        }
 }
 
 int __init fsl_pcie_check_link(struct pci_controller *hose)
 {
-       u16 val;
-       early_read_config_word(hose, 0, 0, PCIE_LTSSM, &val);
+       u32 val;
+       early_read_config_dword(hose, 0, 0, PCIE_LTSSM, &val);
        if (val < PCIE_LTSSM_L0)
                return 1;
        return 0;
 }
 
+void fsl_pcibios_fixup_bus(struct pci_bus *bus)
+{
+       struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+       int i;
+
+       /* deal with bogus pci_bus when we don't have anything connected on PCIe */
+       if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) {
+               if (bus->parent) {
+                       for (i = 0; i < 4; ++i)
+                               bus->resource[i] = bus->parent->resource[i];
+               }
+       }
+}
+
 int __init fsl_add_bridge(struct device_node *dev, int is_primary)
 {
        int len;
@@ -167,20 +210,17 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
        hose->first_busno = bus_range ? bus_range[0] : 0x0;
        hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
-       /* check PCI express bridge */
-       if (of_device_is_compatible(dev, "fsl,mpc8548-pcie") ||
-               of_device_is_compatible(dev, "fsl,mpc8641-pcie"))
-               hose->indirect_type = PPC_INDIRECT_TYPE_EXT_REG |
-                       PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
-
-       setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4);
+       setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4,
+               PPC_INDIRECT_TYPE_BIG_ENDIAN);
        setup_pci_cmd(hose);
 
        /* check PCI express link status */
-       if (of_device_is_compatible(dev, "fsl,mpc8548-pcie") ||
-               of_device_is_compatible(dev, "fsl,mpc8641-pcie"))
+       if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+               hose->indirect_type |= PPC_INDIRECT_TYPE_EXT_REG |
+                       PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
                if (fsl_pcie_check_link(hose))
-                       return -ENXIO;
+                       hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
+       }
 
        printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx."
                "Firmware bus number: %d->%d\n",
@@ -200,5 +240,23 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
        return 0;
 }
 
-DECLARE_PCI_FIXUP_EARLY(0x1957, 0x7010, quirk_fsl_pcie_transparent);
-DECLARE_PCI_FIXUP_EARLY(0x1957, 0x7011, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_transparent);