patch-2.4.20 linux-2.4.20/arch/mips64/sgi-ip32/ip32-pci.c
Next file: linux-2.4.20/arch/mips64/sgi-ip32/ip32-reset.c
Previous file: linux-2.4.20/arch/mips64/sgi-ip32/ip32-irq.c
Back to the patch index
Back to the overall index
- Lines: 461
- Date:
Wed Dec 31 16:00:00 1969
- Orig file:
linux-2.4.19/arch/mips64/sgi-ip32/ip32-pci.c
- Orig date:
Fri Aug 2 17:39:43 2002
diff -urN linux-2.4.19/arch/mips64/sgi-ip32/ip32-pci.c linux-2.4.20/arch/mips64/sgi-ip32/ip32-pci.c
@@ -1,460 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000, 2001 Keith M Wesolowski
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <asm/pci.h>
-#include <asm/ip32/mace.h>
-#include <asm/ip32/crime.h>
-#include <asm/ip32/ip32_ints.h>
-#include <linux/delay.h>
-
-#undef DEBUG_MACE_PCI
-
-/*
- * O2 has up to 5 PCI devices connected into the MACE bridge. The device
- * map looks like this:
- *
- * 0 aic7xxx 0
- * 1 aic7xxx 1
- * 2 expansion slot
- * 3 N/C
- * 4 N/C
- */
-
-#define chkslot(dev) \
-do { \
- if ((dev)->bus->number > 0 || PCI_SLOT ((dev)->devfn) < 1 \
- || PCI_SLOT ((dev)->devfn) > 3) \
- return PCIBIOS_DEVICE_NOT_FOUND; \
-} while (0)
-
-#define mkaddr(dev, where) \
-((((dev)->devfn & 0xffUL) << 8) | ((where) & 0xfcUL))
-
-void macepci_error (int irq, void *dev, struct pt_regs *regs);
-
-static int macepci_read_config_byte (struct pci_dev *dev, int where,
- u8 *val)
-{
- *val = 0xff;
- chkslot (dev);
- mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
- *val = mace_read_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL));
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_read_config_word (struct pci_dev *dev, int where,
- u16 *val)
-{
- *val = 0xffff;
- chkslot (dev);
- if (where & 1)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
- *val = mace_read_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL));
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_read_config_dword (struct pci_dev *dev, int where,
- u32 *val)
-{
- *val = 0xffffffff;
- chkslot (dev);
- if (where & 3)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
- *val = mace_read_32 (MACEPCI_CONFIG_DATA);
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_byte (struct pci_dev *dev, int where,
- u8 val)
-{
- chkslot (dev);
- mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
- mace_write_8 (MACEPCI_CONFIG_DATA + ((where & 3UL) ^ 3UL), val);
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_word (struct pci_dev *dev, int where,
- u16 val)
-{
- chkslot (dev);
- if (where & 1)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
- mace_write_16 (MACEPCI_CONFIG_DATA + ((where & 2UL) ^ 2UL), val);
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int macepci_write_config_dword (struct pci_dev *dev, int where,
- u32 val)
-{
- chkslot (dev);
- if (where & 3)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- mace_write_32 (MACEPCI_CONFIG_ADDR, mkaddr (dev, where));
- mace_write_32 (MACEPCI_CONFIG_DATA, val);
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops macepci_ops = {
- macepci_read_config_byte,
- macepci_read_config_word,
- macepci_read_config_dword,
- macepci_write_config_byte,
- macepci_write_config_word,
- macepci_write_config_dword
-};
-
-struct pci_fixup pcibios_fixups[] = { { 0 } };
-
-void __init pcibios_init (void)
-{
- struct pci_dev *dev;
- u32 start, size;
- u16 cmd;
- u32 base_io = 0x3000; /* The first i/o address to assign after SCSI */
- u32 base_mem = 0x80100000; /* Likewise */
- u32 rev = mace_read_32 (MACEPCI_REV);
- int i;
-
- printk ("MACE: PCI rev %d detected at %016lx\n", rev,
- (u64) MACE_BASE + MACE_PCI);
-
- /* These are *bus* addresses */
- ioport_resource.start = 0;
- ioport_resource.end = 0xffffffffUL;
- iomem_resource.start = 0x80000000UL;
- iomem_resource.end = 0xffffffffUL;
-
- /* Clear any outstanding errors and enable interrupts */
- mace_write_32 (MACEPCI_ERROR_ADDR, 0);
- mace_write_32 (MACEPCI_ERROR_FLAGS, 0);
- mace_write_32 (MACEPCI_CONTROL, 0xff008500);
- crime_write_64 (CRIME_HARD_INT, 0UL);
- crime_write_64 (CRIME_SOFT_INT, 0UL);
- crime_write_64 (CRIME_INT_STAT, 0x000000000000ff00UL);
-
- if (request_irq (MACE_PCI_BRIDGE_IRQ, macepci_error, 0,
- "MACE PCI error", NULL))
- panic("PCI bridge can't get interrupt; can't happen.");
-
- pci_scan_bus (0, &macepci_ops, NULL);
-
-#ifdef DEBUG_MACE_PCI
- pci_for_each_dev (dev) {
- printk ("Device: %d/%d/%d ARCS-assigned bus resource map\n",
- dev->bus->number, PCI_SLOT (dev->devfn),
- PCI_FUNC (dev->devfn));
- for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
- if (dev->resource[i].start == 0)
- continue;
- printk ("%d: %016lx - %016lx (flags %04lx)\n",
- i, dev->resource[i].start,
- dev->resource[i].end, dev->resource[i].flags);
- }
- }
-#endif
- /*
- * Assign sane resources to and enable all devices. The requirement
- * for the SCSI controllers is well-known: a 256-byte I/O region
- * which we must assign, and a 1-page memory region which is
- * assigned by the system firmware.
- */
- pci_for_each_dev (dev) {
- switch (PCI_SLOT (dev->devfn)) {
- case 1: /* SCSI bus 0 */
- dev->resource[0].start = 0x1000UL;
- dev->resource[0].end = 0x10ffUL;
- break;
- case 2: /* SCSI bus 1 */
- dev->resource[0].start = 0x2000UL;
- dev->resource[0].end = 0x20ffUL;
- break;
- default: /* Slots - I guess we have only 1 */
- for (i=0; i < 6; i++) {
- size = dev->resource[i].end
- - dev->resource[i].start;
- if (!size
- || !(dev->resource[i].flags
- & (IORESOURCE_IO|IORESOURCE_MEM))) {
- dev->resource[i].start
- = dev->resource[i].end = 0UL;
- continue;
- }
- if (dev->resource[i].flags & IORESOURCE_IO) {
- dev->resource[i].start = base_io;
- base_io += PAGE_ALIGN (size);
- } else {
- dev->resource[i].start = base_mem;
- base_mem += 0x100000UL;
- }
- dev->resource[i].end =
- dev->resource[i].start + size;
- }
- break;
- }
- for (i=0; i < 6; i++) {
- if (dev->resource[i].start == 0)
- continue;
- start = dev->resource[i].start;
- if (dev->resource[i].flags & IORESOURCE_IO)
- start |= 1;
- pci_write_config_dword (dev,
- PCI_BASE_ADDRESS_0 + (i << 2), (u32) start);
- }
- pci_write_config_byte (dev, PCI_CACHE_LINE_SIZE, 0x20);
- pci_write_config_byte (dev, PCI_LATENCY_TIMER, 0x30);
- pci_read_config_word (dev, PCI_COMMAND, &cmd);
- cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
- pci_write_config_word (dev, PCI_COMMAND, cmd);
- pci_set_master (dev);
- }
- /*
- * Fixup O2 PCI slot. Bad hack.
- */
-/* devtag = pci_make_tag(0, 0, 3, 0);
-
- slot = macepci_conf_read(0, devtag, PCI_COMMAND_STATUS_REG);
- slot |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE;
- macepci_conf_write(0, devtag, PCI_COMMAND_STATUS_REG, slot);
-
- slot = macepci_conf_read(0, devtag, PCI_MAPREG_START);
- if (slot == 0xffffffe1)
- macepci_conf_write(0, devtag, PCI_MAPREG_START, 0x00001000);
-
- slot = macepci_conf_read(0, devtag, PCI_MAPREG_START + (2 << 2));
- if ((slot & 0xffff0000) == 0) {
- slot += 0x00010000;
- macepci_conf_write(0, devtag, PCI_MAPREG_START + (2 << 2),
- 0x00000000);
- }
- */
-#ifdef DEBUG_MACE_PCI
- printk ("Triggering PCI bridge interrupt...\n");
- mace_write_32 (MACEPCI_ERROR_FLAGS, MACEPCI_ERROR_INTERRUPT_TEST);
-
- pci_for_each_dev (dev) {
- printk ("Device: %d/%d/%d final bus resource map\n",
- dev->bus->number, PCI_SLOT (dev->devfn),
- PCI_FUNC (dev->devfn));
- for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
- if (dev->resource[i].start == 0)
- continue;
- printk ("%d: %016lx - %016lx (flags %04lx)\n",
- i, dev->resource[i].start,
- dev->resource[i].end, dev->resource[i].flags);
- }
- }
-#endif
-}
-
-/*
- * Given a PCI slot number (a la PCI_SLOT(...)) and the interrupt pin of
- * the device (1-4 => A-D), tell what irq to use. Note that we don't
- * in theory have slots 4 and 5, and we never normally use the shared
- * irqs. I suppose a device without a pin A will thank us for doing it
- * right if there exists such a broken piece of crap.
- */
-static int __init macepci_map_irq (struct pci_dev *dev, u8 slot, u8 pin)
-{
- chkslot (dev);
- if (pin == 0)
- pin = 1;
- switch (slot) {
- case 1:
- return MACEPCI_SCSI0_IRQ;
- case 2:
- return MACEPCI_SCSI1_IRQ;
- case 3:
- switch (pin) {
- case 2:
- return MACEPCI_SHARED0_IRQ;
- case 3:
- return MACEPCI_SHARED1_IRQ;
- case 4:
- return MACEPCI_SHARED2_IRQ;
- case 1:
- default:
- return MACEPCI_SLOT0_IRQ;
- }
- case 4:
- switch (pin) {
- case 2:
- return MACEPCI_SHARED2_IRQ;
- case 3:
- return MACEPCI_SHARED0_IRQ;
- case 4:
- return MACEPCI_SHARED1_IRQ;
- case 1:
- default:
- return MACEPCI_SLOT1_IRQ;
- }
- return MACEPCI_SLOT1_IRQ;
- case 5:
- switch (pin) {
- case 2:
- return MACEPCI_SHARED1_IRQ;
- case 3:
- return MACEPCI_SHARED2_IRQ;
- case 4:
- return MACEPCI_SHARED0_IRQ;
- case 1:
- default:
- return MACEPCI_SLOT2_IRQ;
- }
- default:
- return 0;
- }
-}
-
-/*
- * It's not entirely clear what this does in a system with no bridges.
- * In any case, bridges are not supported by Linux in O2.
- */
-static u8 __init macepci_swizzle (struct pci_dev *dev, u8 *pinp)
-{
- if (PCI_SLOT (dev->devfn) == 2)
- *pinp = 2;
- else
- *pinp = 1;
- return PCI_SLOT (dev->devfn);
-}
-
-/* All devices are enabled during initialization. */
-int pcibios_enable_device (struct pci_dev *dev)
-{
- return PCIBIOS_SUCCESSFUL;
-}
-
-char * __init pcibios_setup (char *str)
-{
- return str;
-}
-
-void __init pcibios_align_resource (void *data, struct resource *res,
- unsigned long size)
-{
-}
-
-void __init pcibios_update_resource (struct pci_dev *dev, struct resource *root,
- struct resource *res, int resource)
-{
-}
-
-void __init pcibios_update_irq (struct pci_dev *dev, int irq)
-{
- pci_write_config_byte (dev, PCI_INTERRUPT_LINE, irq);
-}
-
-void __init pcibios_fixup_bus (struct pci_bus *b)
-{
- pci_fixup_irqs (macepci_swizzle, macepci_map_irq);
-}
-
-/* XXX anybody know what this is supposed to do? */
-void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus,
- struct pbus_set_ranges_data * ranges)
-{
- ranges->io_start -= bus->resource[0]->start;
- ranges->io_end -= bus->resource[0]->start;
- ranges->mem_start -= bus->resource[1]->start;
- ranges->mem_end -= bus->resource[1]->start;
-}
-
-/*
- * Handle errors from the bridge. This includes master and target aborts,
- * various command and address errors, and the interrupt test. This gets
- * registered on the bridge error irq. It's conceivable that some of these
- * conditions warrant a panic. Anybody care to say which ones?
- */
-void macepci_error (int irq, void *dev, struct pt_regs *regs) {
- u32 flags, error_addr;
- char space;
-
- flags = mace_read_32 (MACEPCI_ERROR_FLAGS);
- error_addr = mace_read_32 (MACEPCI_ERROR_ADDR);
-
- if (flags & MACEPCI_ERROR_MEMORY_ADDR)
- space = 'M';
- else if (flags & MACEPCI_ERROR_CONFIG_ADDR)
- space = 'C';
- else space = 'X';
-
- if (flags & MACEPCI_ERROR_MASTER_ABORT) {
- printk ("MACEPCI: Master abort at 0x%08x (%c)\n", error_addr,
- space);
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_MASTER_ABORT);
- }
- if (flags & MACEPCI_ERROR_TARGET_ABORT) {
- printk ("MACEPCI: Target abort at 0x%08x (%c)\n", error_addr,
- space);
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_TARGET_ABORT);
- }
- if (flags & MACEPCI_ERROR_DATA_PARITY_ERR) {
- printk ("MACEPCI: Data parity error at 0x%08x (%c)\n",
- error_addr, space);
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_DATA_PARITY_ERR);
- }
- if (flags & MACEPCI_ERROR_RETRY_ERR) {
- printk ("MACEPCI: Retry error at 0x%08x (%c)\n", error_addr,
- space);
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_RETRY_ERR);
- }
- if (flags & MACEPCI_ERROR_ILLEGAL_CMD) {
- printk ("MACEPCI: Illegal command at 0x%08x (%c)\n",
- error_addr, space);
- mace_write_32 (MACEPCI_ERROR_FLAGS,
- flags & ~MACEPCI_ERROR_ILLEGAL_CMD);
- }
- if (flags & MACEPCI_ERROR_SYSTEM_ERR) {
- printk ("MACEPCI: System error at 0x%08x (%c)\n",
- error_addr, space);
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_SYSTEM_ERR);
- }
- if (flags & MACEPCI_ERROR_PARITY_ERR) {
- printk ("MACEPCI: Parity error at 0x%08x (%c)\n", error_addr,
- space);
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_PARITY_ERR);
- }
- if (flags & MACEPCI_ERROR_OVERRUN) {
- printk ("MACEPCI: Overrun error at 0x%08x (%c)\n",
- error_addr, space);
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_OVERRUN);
- }
- if (flags & MACEPCI_ERROR_SIG_TABORT) {
- printk ("MACEPCI: Signaled target abort (clearing)\n");
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_SIG_TABORT);
- }
- if (flags & MACEPCI_ERROR_INTERRUPT_TEST) {
- printk ("MACEPCI: Interrupt test triggered (clearing)\n");
- mace_write_32 (MACEPCI_ERROR_FLAGS, flags
- & ~MACEPCI_ERROR_INTERRUPT_TEST);
- }
-}
-unsigned __init int pcibios_assign_all_busses(void)
-{
- return 0;
-}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)