diff options
Diffstat (limited to 'arch/powerpc/platforms/chrp/pci.c')
-rw-r--r-- | arch/powerpc/platforms/chrp/pci.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 6802cdc3168a..0f4340506c75 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c | |||
@@ -214,11 +214,11 @@ void __init | |||
214 | chrp_find_bridges(void) | 214 | chrp_find_bridges(void) |
215 | { | 215 | { |
216 | struct device_node *dev; | 216 | struct device_node *dev; |
217 | int *bus_range; | 217 | const int *bus_range; |
218 | int len, index = -1; | 218 | int len, index = -1; |
219 | struct pci_controller *hose; | 219 | struct pci_controller *hose; |
220 | unsigned int *dma; | 220 | const unsigned int *dma; |
221 | char *model, *machine; | 221 | const char *model, *machine; |
222 | int is_longtrail = 0, is_mot = 0, is_pegasos = 0; | 222 | int is_longtrail = 0, is_mot = 0, is_pegasos = 0; |
223 | struct device_node *root = find_path_device("/"); | 223 | struct device_node *root = find_path_device("/"); |
224 | struct resource r; | 224 | struct resource r; |
@@ -246,7 +246,7 @@ chrp_find_bridges(void) | |||
246 | dev->full_name); | 246 | dev->full_name); |
247 | continue; | 247 | continue; |
248 | } | 248 | } |
249 | bus_range = (int *) get_property(dev, "bus-range", &len); | 249 | bus_range = get_property(dev, "bus-range", &len); |
250 | if (bus_range == NULL || len < 2 * sizeof(int)) { | 250 | if (bus_range == NULL || len < 2 * sizeof(int)) { |
251 | printk(KERN_WARNING "Can't get bus-range for %s\n", | 251 | printk(KERN_WARNING "Can't get bus-range for %s\n", |
252 | dev->full_name); | 252 | dev->full_name); |
@@ -257,7 +257,7 @@ chrp_find_bridges(void) | |||
257 | else | 257 | else |
258 | printk(KERN_INFO "PCI buses %d..%d", | 258 | printk(KERN_INFO "PCI buses %d..%d", |
259 | bus_range[0], bus_range[1]); | 259 | bus_range[0], bus_range[1]); |
260 | printk(" controlled by %s", dev->type); | 260 | printk(" controlled by %s", dev->full_name); |
261 | if (!is_longtrail) | 261 | if (!is_longtrail) |
262 | printk(" at %llx", (unsigned long long)r.start); | 262 | printk(" at %llx", (unsigned long long)r.start); |
263 | printk("\n"); | 263 | printk("\n"); |
@@ -289,6 +289,19 @@ chrp_find_bridges(void) | |||
289 | setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); | 289 | setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); |
290 | } else if (is_pegasos == 2) { | 290 | } else if (is_pegasos == 2) { |
291 | setup_peg2(hose, dev); | 291 | setup_peg2(hose, dev); |
292 | } else if (!strncmp(model, "IBM,CPC710", 10)) { | ||
293 | setup_indirect_pci(hose, | ||
294 | r.start + 0x000f8000, | ||
295 | r.start + 0x000f8010); | ||
296 | if (index == 0) { | ||
297 | dma = get_property(dev, "system-dma-base",&len); | ||
298 | if (dma && len >= sizeof(*dma)) { | ||
299 | dma = (unsigned int *) | ||
300 | (((unsigned long)dma) + | ||
301 | len - sizeof(*dma)); | ||
302 | pci_dram_offset = *dma; | ||
303 | } | ||
304 | } | ||
292 | } else { | 305 | } else { |
293 | printk("No methods for %s (model %s), using RTAS\n", | 306 | printk("No methods for %s (model %s), using RTAS\n", |
294 | dev->full_name, model); | 307 | dev->full_name, model); |
@@ -299,15 +312,35 @@ chrp_find_bridges(void) | |||
299 | 312 | ||
300 | /* check the first bridge for a property that we can | 313 | /* check the first bridge for a property that we can |
301 | use to set pci_dram_offset */ | 314 | use to set pci_dram_offset */ |
302 | dma = (unsigned int *) | 315 | dma = get_property(dev, "ibm,dma-ranges", &len); |
303 | get_property(dev, "ibm,dma-ranges", &len); | ||
304 | if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { | 316 | if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { |
305 | pci_dram_offset = dma[2] - dma[3]; | 317 | pci_dram_offset = dma[2] - dma[3]; |
306 | printk("pci_dram_offset = %lx\n", pci_dram_offset); | 318 | printk("pci_dram_offset = %lx\n", pci_dram_offset); |
307 | } | 319 | } |
308 | } | 320 | } |
321 | } | ||
322 | |||
323 | /* SL82C105 IDE Control/Status Register */ | ||
324 | #define SL82C105_IDECSR 0x40 | ||
325 | |||
326 | /* Fixup for Winbond ATA quirk, required for briq */ | ||
327 | void chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105) | ||
328 | { | ||
329 | u8 progif; | ||
309 | 330 | ||
310 | /* Do not fixup interrupts from OF tree on pegasos */ | 331 | /* If non-briq machines need that fixup too, please speak up */ |
311 | if (is_pegasos) | 332 | if (!machine_is(chrp) || _chrp_type != _CHRP_briq) |
312 | ppc_md.pcibios_fixup = NULL; | 333 | return; |
334 | |||
335 | if ((sl82c105->class & 5) != 5) { | ||
336 | printk("W83C553: Switching SL82C105 IDE to PCI native mode\n"); | ||
337 | /* Enable SL82C105 PCI native IDE mode */ | ||
338 | pci_read_config_byte(sl82c105, PCI_CLASS_PROG, &progif); | ||
339 | pci_write_config_byte(sl82c105, PCI_CLASS_PROG, progif | 0x05); | ||
340 | sl82c105->class |= 0x05; | ||
341 | /* Disable SL82C105 second port */ | ||
342 | pci_write_config_word(sl82c105, SL82C105_IDECSR, 0x0003); | ||
343 | } | ||
313 | } | 344 | } |
345 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, | ||
346 | chrp_pci_fixup_winbond_ata); | ||