aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/86xx/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/86xx/pci.c')
-rw-r--r--arch/powerpc/platforms/86xx/pci.c67
1 files changed, 50 insertions, 17 deletions
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index 8235c562661f..73cd5b05a84e 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -122,7 +122,6 @@ static void __init
122mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) 122mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
123{ 123{
124 u16 cmd; 124 u16 cmd;
125 unsigned int temps;
126 125
127 DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", 126 DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n",
128 pcie_offset, pcie_size); 127 pcie_offset, pcie_size);
@@ -133,22 +132,49 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
133 early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd); 132 early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
134 133
135 early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80); 134 early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
136
137 /* PCIE Bus, Fix the MPC8641D host bridge's location to bus 0xFF. */
138 early_read_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, &temps);
139 temps = (temps & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
140 early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps);
141} 135}
142 136
143int mpc86xx_exclude_device(u_char bus, u_char devfn) 137static void __devinit quirk_fsl_pcie_transparent(struct pci_dev *dev)
144{ 138{
145 if (bus == 0 && PCI_SLOT(devfn) == 0) 139 struct resource *res;
146 return PCIBIOS_DEVICE_NOT_FOUND; 140 int i, res_idx = PCI_BRIDGE_RESOURCES;
141 struct pci_controller *hose;
147 142
148 return PCIBIOS_SUCCESSFUL; 143 /*
144 * Make the bridge be transparent.
145 */
146 dev->transparent = 1;
147
148 hose = pci_bus_to_host(dev->bus);
149 if (!hose) {
150 printk(KERN_ERR "Can't find hose for bus %d\n",
151 dev->bus->number);
152 return;
153 }
154
155 if (hose->io_resource.flags) {
156 res = &dev->resource[res_idx++];
157 res->start = hose->io_resource.start;
158 res->end = hose->io_resource.end;
159 res->flags = hose->io_resource.flags;
160 }
161
162 for (i = 0; i < 3; i++) {
163 res = &dev->resource[res_idx + i];
164 res->start = hose->mem_resources[i].start;
165 res->end = hose->mem_resources[i].end;
166 res->flags = hose->mem_resources[i].flags;
167 }
149} 168}
150 169
151int __init add_bridge(struct device_node *dev) 170
171DECLARE_PCI_FIXUP_EARLY(0x1957, 0x7010, quirk_fsl_pcie_transparent);
172DECLARE_PCI_FIXUP_EARLY(0x1957, 0x7011, quirk_fsl_pcie_transparent);
173
174#define PCIE_LTSSM 0x404 /* PCIe Link Training and Status */
175#define PCIE_LTSSM_L0 0x16 /* L0 state */
176
177int __init mpc86xx_add_bridge(struct device_node *dev)
152{ 178{
153 int len; 179 int len;
154 struct pci_controller *hose; 180 struct pci_controller *hose;
@@ -156,6 +182,7 @@ int __init add_bridge(struct device_node *dev)
156 const int *bus_range; 182 const int *bus_range;
157 int has_address = 0; 183 int has_address = 0;
158 int primary = 0; 184 int primary = 0;
185 u16 val;
159 186
160 DBG("Adding PCIE host bridge %s\n", dev->full_name); 187 DBG("Adding PCIE host bridge %s\n", dev->full_name);
161 188
@@ -168,17 +195,23 @@ int __init add_bridge(struct device_node *dev)
168 printk(KERN_WARNING "Can't get bus-range for %s, assume" 195 printk(KERN_WARNING "Can't get bus-range for %s, assume"
169 " bus 0\n", dev->full_name); 196 " bus 0\n", dev->full_name);
170 197
171 hose = pcibios_alloc_controller(); 198 pci_assign_all_buses = 1;
199 hose = pcibios_alloc_controller(dev);
172 if (!hose) 200 if (!hose)
173 return -ENOMEM; 201 return -ENOMEM;
174 hose->arch_data = dev;
175 hose->set_cfg_type = 1;
176 202
177 /* last_busno = 0xfe cause by MPC8641 PCIE bug */ 203 hose->indirect_type = PPC_INDIRECT_TYPE_EXT_REG |
204 PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
205
178 hose->first_busno = bus_range ? bus_range[0] : 0x0; 206 hose->first_busno = bus_range ? bus_range[0] : 0x0;
179 hose->last_busno = bus_range ? bus_range[1] : 0xfe; 207 hose->last_busno = bus_range ? bus_range[1] : 0xff;
208
209 setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4);
180 210
181 setup_indirect_pcie(hose, rsrc.start, rsrc.start + 0x4); 211 /* Probe the hose link training status */
212 early_read_config_word(hose, 0, 0, PCIE_LTSSM, &val);
213 if (val < PCIE_LTSSM_L0)
214 return -ENXIO;
182 215
183 /* Setup the PCIE host controller. */ 216 /* Setup the PCIE host controller. */
184 mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1); 217 mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1);