patch-2.4.1 linux/arch/ppc/kernel/chrp_pci.c
Next file: linux/arch/ppc/kernel/chrp_setup.c
Previous file: linux/arch/ppc/kernel/apus_setup.c
Back to the patch index
Back to the overall index
- Lines: 750
- Date:
Mon Jan 22 15:41:15 2001
- Orig file:
v2.4.0/linux/arch/ppc/kernel/chrp_pci.c
- Orig date:
Sun Sep 17 09:48:06 2000
diff -u --recursive --new-file v2.4.0/linux/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c
@@ -8,8 +8,8 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/openpic.h>
#include <linux/ide.h>
+#include <linux/bootmem.h>
#include <asm/io.h>
#include <asm/pgtable.h>
@@ -19,16 +19,19 @@
#include <asm/gg2.h>
#include <asm/machdep.h>
#include <asm/init.h>
+#include <asm/pci-bridge.h>
+#include "open_pic.h"
#include "pci.h"
+
#ifdef CONFIG_POWER4
-static unsigned long pci_address_offset(int, unsigned int);
+extern unsigned long pci_address_offset(int, unsigned int);
#endif /* CONFIG_POWER4 */
/* LongTrail */
-#define pci_config_addr(bus, dev, offset) \
-(GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset))
+#define pci_config_addr(dev, offset) \
+(GG2_PCI_CONFIG_BASE | ((dev->bus->number)<<16) | ((dev->devfn)<<8) | (offset))
volatile struct Hydra *Hydra = NULL;
@@ -37,205 +40,127 @@
* limit the bus number to 3 bits
*/
-int __chrp gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- if (bus > 7) {
- *val = 0xff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_8((unsigned char *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- if (bus > 7) {
- *val = 0xffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
-}
-
+#define cfg_read(val, addr, type, op) *val = op((type)(addr))
+#define cfg_write(val, addr, type, op) op((type *)(addr), (val))
-int __chrp gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- if (bus > 7) {
- *val = 0xffffffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- *val = in_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset));
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_8((unsigned char *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
-}
+#define cfg_read_bad(val, size) *val = bad_##size;
+#define cfg_write_bad(val, size)
-int __chrp gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
-{
- if (bus > 7)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset), val);
- return PCIBIOS_SUCCESSFUL;
-}
+#define bad_byte 0xff
+#define bad_word 0xffff
+#define bad_dword 0xffffffffU
+
+#define GG2_PCI_OP(rw, size, type, op) \
+int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) \
+{ \
+ if (dev->bus->number > 7) { \
+ cfg_##rw##_bad(val, size) \
+ return PCIBIOS_DEVICE_NOT_FOUND; \
+ } \
+ cfg_##rw(val, pci_config_addr(dev, off), type, op); \
+ return PCIBIOS_SUCCESSFUL; \
+}
+
+GG2_PCI_OP(read, byte, u8 *, in_8)
+GG2_PCI_OP(read, word, u16 *, in_le16)
+GG2_PCI_OP(read, dword, u32 *, in_le32)
+GG2_PCI_OP(write, byte, u8, out_8)
+GG2_PCI_OP(write, word, u16, out_le16)
+GG2_PCI_OP(write, dword, u32, out_le32)
+
+static struct pci_ops gg2_pci_ops =
+{
+ gg2_read_config_byte,
+ gg2_read_config_word,
+ gg2_read_config_dword,
+ gg2_write_config_byte,
+ gg2_write_config_word,
+ gg2_write_config_dword
+};
-#define python_config_address(bus) (unsigned *)((0xfef00000+0xf8000)-(bus*0x100000))
-#define python_config_data(bus) ((0xfef00000+0xf8010)-(bus*0x100000))
-#define PYTHON_CFA(b, d, o) (0x80 | ((b<<6) << 8) | ((d) << 16) \
+/*
+ * Access functions for PCI config space on IBM "python" host bridges.
+ */
+#define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
| (((o) & ~3) << 24))
-unsigned int python_busnr = 0;
-
-int __chrp python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- if (bus > python_busnr) {
- *val = 0xff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- *val = in_8((unsigned char *)python_config_data(bus) + (offset&3));
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- if (bus > python_busnr) {
- *val = 0xffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- *val = in_le16((unsigned short *)(python_config_data(bus) + (offset&3)));
- return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- if (bus > python_busnr) {
- *val = 0xffffffff;
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- *val = in_le32((unsigned *)python_config_data(bus));
- return PCIBIOS_SUCCESSFUL;
-}
-int __chrp python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- if (bus > python_busnr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- out_8((volatile unsigned char *)python_config_data(bus) + (offset&3), val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- if (bus > python_busnr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- out_le16((volatile unsigned short *)python_config_data(bus) + (offset&3),
- val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
-{
- if (bus > python_busnr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset));
- out_le32((unsigned *)python_config_data(bus) + (offset&3), val);
- return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char *val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- unsigned long ret;
-
- if (call_rtas( "read-pci-config", 2, 2, &ret, addr, 1) != 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = ret;
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short *val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- unsigned long ret;
-
- if (call_rtas("read-pci-config", 2, 2, &ret, addr, 2) != 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = ret;
- return PCIBIOS_SUCCESSFUL;
-}
-
-
-int __chrp rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int *val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- unsigned long ret;
-
- if (call_rtas("read-pci-config", 2, 2, &ret, addr, 4) != 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- *val = ret;
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned char val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 1, (ulong)val ) != 0 )
- return PCIBIOS_DEVICE_NOT_FOUND;
- return PCIBIOS_SUCCESSFUL;
-}
-
-int __chrp rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned short val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 2, (ulong)val ) != 0 )
- return PCIBIOS_DEVICE_NOT_FOUND;
- return PCIBIOS_SUCCESSFUL;
-}
+#define PYTHON_PCI_OP(rw, size, type, op, mask) \
+int __chrp \
+python_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ struct pci_controller *hose = dev->sysdata; \
+ \
+ out_be32(hose->cfg_addr, \
+ PYTHON_CFA(dev->bus->number, dev->devfn, offset)); \
+ cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \
+ return PCIBIOS_SUCCESSFUL; \
+}
+
+PYTHON_PCI_OP(read, byte, u8 *, in_8, 3)
+PYTHON_PCI_OP(read, word, u16 *, in_le16, 2)
+PYTHON_PCI_OP(read, dword, u32 *, in_le32, 0)
+PYTHON_PCI_OP(write, byte, u8, out_8, 3)
+PYTHON_PCI_OP(write, word, u16, out_le16, 2)
+PYTHON_PCI_OP(write, dword, u32, out_le32, 0)
+
+static struct pci_ops python_pci_ops =
+{
+ python_read_config_byte,
+ python_read_config_word,
+ python_read_config_dword,
+ python_write_config_byte,
+ python_write_config_word,
+ python_write_config_dword
+};
-int __chrp rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
- unsigned char offset, unsigned int val)
-{
- unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16);
- if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 4, (ulong)val ) != 0 )
- return PCIBIOS_DEVICE_NOT_FOUND;
- return PCIBIOS_SUCCESSFUL;
-}
+#ifdef CONFIG_POWER4
+/*
+ * Access functions for PCI config space using RTAS calls.
+ */
+#define RTAS_PCI_READ_OP(size, type, nbytes) \
+int __chrp \
+rtas_read_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
+ | ((dev->bus->number & 0xff) << 16); \
+ unsigned long ret = ~0UL; \
+ int rval; \
+ \
+ rval = call_rtas("read-pci-config", 2, 2, &ret, addr, nbytes); \
+ *val = ret; \
+ return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \
+}
+
+#define RTAS_PCI_WRITE_OP(size, type, nbytes) \
+int __chrp \
+rtas_write_config_##size(struct pci_dev *dev, int offset, type val) \
+{ \
+ unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
+ | ((dev->bus->number & 0xff) << 16); \
+ int rval; \
+ \
+ rval = call_rtas("write-pci-config", 3, 1, NULL, \
+ addr, nbytes, (ulong)val); \
+ return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \
+}
+
+RTAS_PCI_READ_OP(byte, u8 *, 1)
+RTAS_PCI_READ_OP(word, u16 *, 2)
+RTAS_PCI_READ_OP(dword, u32 *, 4)
+RTAS_PCI_WRITE_OP(byte, u8, 1)
+RTAS_PCI_WRITE_OP(word, u16, 2)
+RTAS_PCI_WRITE_OP(dword, u32, 4)
+
+static struct pci_ops rtas_pci_ops =
+{
+ rtas_read_config_byte,
+ rtas_read_config_word,
+ rtas_read_config_dword,
+ rtas_write_config_byte,
+ rtas_write_config_word,
+ rtas_write_config_dword
+};
+#endif /* CONFIG_POWER4 */
/*
* Temporary fixes for PCI devices. These should be replaced by OF query
@@ -278,7 +203,7 @@
HYDRA_FC_MPIC_ENABLE |
HYDRA_FC_SLOW_SCC_PCLK |
HYDRA_FC_MPIC_IS_MASTER));
- OpenPIC = (volatile struct OpenPIC *)&Hydra->OpenPIC;
+ OpenPIC_Addr = &Hydra->OpenPIC;
OpenPIC_InitSenses = hydra_openpic_initsenses;
OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses);
return 1;
@@ -316,54 +241,25 @@
chrp_pcibios_fixup(void)
{
struct pci_dev *dev;
- int *brp;
struct device_node *np;
- extern struct pci_ops generic_pci_ops;
-
-#ifndef CONFIG_POWER4
- np = find_devices("device-tree");
- if (np != 0) {
- for (np = np->child; np != NULL; np = np->sibling) {
- if (np->type == NULL || strcmp(np->type, "pci") != 0)
- continue;
- if ((brp = (int *) get_property(np, "bus-range", NULL)) == 0)
- continue;
- if (brp[0] != 0) /* bus 0 is already done */
- pci_scan_bus(brp[0], &generic_pci_ops, NULL);
- }
- }
-#else
- /* XXX kludge for now because we can't properly handle
- physical addresses > 4GB. -- paulus */
- pci_scan_bus(0x1e, &generic_pci_ops, NULL);
-#endif /* CONFIG_POWER4 */
/* PCI interrupts are controlled by the OpenPIC */
pci_for_each_dev(dev) {
- np = find_pci_device_OFnode(dev->bus->number, dev->devfn);
+ np = pci_device_to_OF_node(dev);
if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
dev->irq = np->intrs[0].line;
- /* these need to be absolute addrs for OF and Matrox FB -- Cort */
- if ( dev->vendor == PCI_VENDOR_ID_MATROX )
- {
- if ( dev->resource[0].start < isa_mem_base )
- dev->resource[0].start += isa_mem_base;
- if ( dev->resource[1].start < isa_mem_base )
- dev->resource[1].start += isa_mem_base;
- }
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
/* the F50 identifies the amd as a trident */
if ( (dev->vendor == PCI_VENDOR_ID_TRIDENT) &&
(dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET) )
{
dev->vendor = PCI_VENDOR_ID_AMD;
- pcibios_write_config_word(dev->bus->number,
- dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+ pci_write_config_word(dev, PCI_VENDOR_ID,
+ PCI_VENDOR_ID_AMD);
}
#ifdef CONFIG_POWER4
power4_fixup_dev(dev);
-#else
- if (dev->bus->number > 0 && python_busnr > 0)
- dev->resource[0].start += dev->bus->number*0x01000000;
#endif
}
}
@@ -402,86 +298,213 @@
bus->resource[1] = &gg2_resources.pci_mem;
}
-decl_config_access_method(grackle);
-decl_config_access_method(indirect);
-decl_config_access_method(rtas);
+static void process_bridge_ranges(struct pci_controller *hose,
+ struct device_node *dev, int index)
+{
+ unsigned int *ranges;
+ int rlen = 0;
+ int memno = 0;
+ struct resource *res;
+
+ hose->io_base_phys = 0;
+ ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+ while ((rlen -= 6 * sizeof(unsigned int)) >= 0) {
+ res = NULL;
+ switch (ranges[0] >> 24) {
+ case 1: /* I/O space */
+ if (ranges[2] != 0)
+ break;
+ hose->io_base_phys = ranges[3];
+ hose->io_base_virt = ioremap(ranges[3], ranges[5]);
+ if (index == 0) {
+ isa_io_base = (unsigned long) hose->io_base_virt;
+ printk("isa_io_base=%lx\n", isa_io_base);
+ }
+ res = &hose->io_resource;
+ res->flags = IORESOURCE_IO;
+ break;
+ case 2: /* memory space */
+ if (index == 0 && ranges[1] == 0 && ranges[2] == 0){
+ isa_mem_base = ranges[3];
+ printk("isa_mem_base=%lx\n", isa_mem_base);
+ }
+ if (memno == 0) {
+ hose->pci_mem_offset = ranges[3] - ranges[2];
+ printk("pci_mem_offset=%lx for this bridge\n",
+ hose->pci_mem_offset);
+ }
+ res = &hose->mem_resources[memno];
+ res->flags = IORESOURCE_MEM;
+ ++memno;
+ break;
+ }
+ if (res != NULL) {
+ res->name = dev->full_name;
+ res->start = ranges[3];
+ res->end = res->start + ranges[5] - 1;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
+ }
+ ranges += 6;
+ }
+}
+
+/* this is largely modeled and stolen after the pmac_pci code -- tgall
+ */
+
+static void __init
+ibm_add_bridges(struct device_node *dev)
+{
+ int *bus_range;
+ int len, index = 0;
+ struct pci_controller *hose;
+ volatile unsigned char *cfg;
+ unsigned int *dma;
+#ifdef CONFIG_POWER3
+ unsigned long *opprop = (unsigned long *)
+ get_property(find_path_device("/"), "platform-open-pic", NULL);
+#endif
+
+ for(; dev != NULL; dev = dev->next, ++index) {
+ if (dev->n_addrs < 1) {
+ printk(KERN_WARNING "Can't use %s: no address\n",
+ dev->full_name);
+ continue;
+ }
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s\n",
+ dev->full_name);
+ continue;
+ }
+ if (bus_range[1] == bus_range[0])
+ printk(KERN_INFO "PCI bus %d", bus_range[0]);
+ else
+ printk(KERN_INFO "PCI buses %d..%d",
+ bus_range[0], bus_range[1]);
+ printk(" controlled by %s at %x\n", dev->type,
+ dev->addrs[0].address);
+
+ hose = pcibios_alloc_controller();
+ if (!hose) {
+ printk("Can't allocate PCI controller structure for %s\n",
+ dev->full_name);
+ continue;
+ }
+ hose->arch_data = dev;
+ hose->first_busno = bus_range[0];
+ hose->last_busno = bus_range[1];
+ hose->ops = &python_pci_ops;
+
+ cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20);
+ hose->cfg_addr = (volatile unsigned int *) cfg;
+ hose->cfg_data = cfg + 0x10;
+
+ process_bridge_ranges(hose, dev, index);
+
+#ifdef CONFIG_POWER3
+ openpic_setup_ISU(index, opprop[index+1]);
+#endif /* CONFIG_POWER3 */
+
+ /* check the first bridge for a property that we can
+ use to set pci_dram_offset */
+ dma = (unsigned int *)
+ get_property(dev, "ibm,dma-ranges", &len);
+ if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
+ pci_dram_offset = dma[2] - dma[3];
+ printk("pci_dram_offset = %lx\n", pci_dram_offset);
+ }
+ }
+}
+#ifdef CONFIG_POWER4
void __init
-chrp_setup_pci_ptrs(void)
+power4_add_bridge(void)
+{
+ struct pci_controller* hose;
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ hose->ops = &rtas_pci_ops;
+ pci_dram_offset = 0;
+}
+#endif /* CONFIG_POWER4 */
+
+void __init
+chrp_find_bridges(void)
{
struct device_node *py;
+ char *model, *name;
+ struct pci_controller* hose;
ppc_md.pcibios_fixup = chrp_pcibios_fixup;
+
#ifdef CONFIG_POWER4
- set_config_access_method(rtas);
- pci_dram_offset = 0;
+ power4_add_bridge();
#else /* CONFIG_POWER4 */
- if ( !strncmp("MOT",
- get_property(find_path_device("/"), "model", NULL),3) )
- {
- pci_dram_offset = 0;
- isa_mem_base = 0xf7000000;
- isa_io_base = 0xfe000000;
- set_config_access_method(grackle);
+ model = get_property(find_path_device("/"), "model", NULL);
+ if (!strncmp("MOT", model, 3)) {
+ struct pci_controller* hose;
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+ /* Check that please. This must be the root of the OF
+ * PCI tree (the root host bridge
+ */
+ hose->arch_data = find_devices("pci");
+ setup_grackle(hose, 0x20000);
+ return;
}
- else
- {
- if ((py = find_compatible_devices("pci", "IBM,python")) != 0
- || (py = find_compatible_devices("pci", "IBM,python3.0")) != 0)
- {
- char *name = get_property(find_path_device("/"), "name", NULL);
- /* find out how many pythons */
- while ( (py = py->next) ) python_busnr++;
- set_config_access_method(python);
-
- /*
- * We base these values on the machine type but should
- * try to read them from the python controller itself.
- * -- Cort
- */
- if ( !strncmp("IBM,7025-F50", name, 12) )
- {
- pci_dram_offset = 0x80000000;
- isa_mem_base = 0xa0000000;
- isa_io_base = 0x88000000;
- } else if ( !strncmp("IBM,7043-260", name, 12)
- || !strncmp("IBM,7044-270", name, 12))
- {
- pci_dram_offset = 0x0;
- isa_mem_base = 0xc0000000;
- isa_io_base = 0xf8000000;
- }
- }
- else
- {
- if ( !strncmp("IBM,7043-150", get_property(find_path_device("/"), "name", NULL),12) ||
- !strncmp("IBM,7046-155", get_property(find_path_device("/"), "name", NULL),12) ||
- !strncmp("IBM,7046-B50", get_property(find_path_device("/"), "name", NULL),12) )
- {
- pci_dram_offset = 0;
- isa_mem_base = 0x80000000;
- isa_io_base = 0xfe000000;
- pci_config_address = (unsigned int *)0xfec00000;
- pci_config_data = (unsigned char *)0xfee00000;
- set_config_access_method(indirect);
- }
- else
- {
- /* LongTrail */
- pci_dram_offset = 0;
- isa_mem_base = 0xf7000000;
- isa_io_base = 0xf8000000;
- set_config_access_method(gg2);
- ppc_md.pcibios_fixup = gg2_pcibios_fixup;
- ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
- }
- }
- }
+ if ((py = find_compatible_devices("pci", "IBM,python")))
+ {
+ /* XXX xmon_init_scc needs this set and the BAT
+ set up in MMU_init */
+ ibm_add_bridges(find_devices("pci"));
+ return;
+ }
+
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return;
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+ /* Check that please. This must be the root of the OF
+ * PCI tree (the root host bridge
+ */
+ hose->arch_data = find_devices("pci");
+ name = get_property(find_path_device("/"), "name", NULL);
+ if (!strncmp("IBM,7043-150", name, 12) ||
+ !strncmp("IBM,7046-155", name, 12) ||
+ !strncmp("IBM,7046-B50", name, 12) ) {
+ setup_grackle(hose, 0x01000000);
+ isa_mem_base = 0x80000000;
+ return;
+ }
+
+ /* LongTrail */
+ hose->ops = &gg2_pci_ops;
+ pci_dram_offset = 0;
+ isa_mem_base = 0xf7000000;
+ hose->io_base_phys = (unsigned long) 0xf8000000;
+ hose->io_base_virt = ioremap(hose->io_base_phys, 0x10000);
+ isa_io_base = (unsigned long) hose->io_base_virt;
+ ppc_md.pcibios_fixup = gg2_pcibios_fixup;
+ ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
#endif /* CONFIG_POWER4 */
}
#ifdef CONFIG_PPC64BRIDGE
+#ifdef CONFIG_POWER4
/*
* Hack alert!!!
* 64-bit machines like POWER3 and POWER4 have > 32 bit
@@ -490,9 +513,7 @@
* page table gives us into parts of the physical address
* space above 4GB so we can access the I/O devices.
*/
-
-#ifdef CONFIG_POWER4
-static unsigned long pci_address_offset(int busnr, unsigned int flags)
+unsigned long pci_address_offset(int busnr, unsigned int flags)
{
unsigned long offset = 0;
@@ -507,35 +528,6 @@
else
}
return offset;
-}
-
-unsigned long phys_to_bus(unsigned long pa)
-{
- if (pa >= 0xf8000000)
- pa -= 0x38000000;
- else if (pa >= 0x80000000 && pa < 0xc0000000)
- pa += 0x40000000;
- return pa;
-}
-
-unsigned long bus_to_phys(unsigned int ba, int busnr)
-{
- return ba + pci_address_offset(busnr, IORESOURCE_MEM);
-}
-
-#else /* CONFIG_POWER4 */
-/*
- * For now assume I/O addresses are < 4GB and PCI bridges don't
- * remap addresses on POWER3 machines.
- */
-unsigned long phys_to_bus(unsigned long pa)
-{
- return pa;
-}
-
-unsigned long bus_to_phys(unsigned int ba, int busnr)
-{
- return ba;
}
#endif /* CONFIG_POWER4 */
#endif /* CONFIG_PPC64BRIDGE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)