patch-2.0.34 linux/arch/alpha/kernel/bios32.c
Next file: linux/arch/alpha/kernel/cia.c
Previous file: linux/arch/alpha/kernel/apecs.c
Back to the patch index
Back to the overall index
- Lines: 1815
- Date:
Wed Jun 3 15:17:46 1998
- Orig file:
v2.0.33/linux/arch/alpha/kernel/bios32.c
- Orig date:
Sun Feb 2 04:59:20 1997
diff -u --recursive --new-file v2.0.33/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
@@ -57,7 +57,7 @@
#include <asm/hwrpb.h>
#include <asm/io.h>
#include <asm/segment.h>
-
+#include <asm/dma.h>
#define KB 1024
#define MB (1024*KB)
@@ -73,6 +73,8 @@
/*
+ * PCI_MODIFY
+ *
* Temporary internal macro. If this 0, then do not write to any of
* the PCI registers, merely read them (i.e., use configuration as
* determined by SRM). The SRM seem do be doing a less than perfect
@@ -89,34 +91,72 @@
* the graphics card---there have been some rumor that the #9 BIOS
* incorrectly resets that address to 0...).
*/
+#ifdef CONFIG_ALPHA_SRM_SETUP
+#define PCI_MODIFY 0
+static struct pci_dev *irq_dev_to_reset[16];
+static unsigned char irq_to_reset[16];
+static int irq_reset_count = 0;
+static struct pci_dev *io_dev_to_reset[16];
+static unsigned char io_reg_to_reset[16];
+static unsigned int io_to_reset[16];
+static int io_reset_count = 0;
+#else /* SRM_SETUP */
#define PCI_MODIFY 1
+#endif /* SRM_SETUP */
extern struct hwrpb_struct *hwrpb;
-
#if PCI_MODIFY
/* NOTE: we can't just blindly use 64K for machines with EISA busses; they
may also have PCI-PCI bridges present, and then we'd configure the bridge
incorrectly */
-#if 0
-static unsigned int io_base = 64*KB; /* <64KB are (E)ISA ports */
+/* NOTE also that we may need this stuff for SRM_SETUP also, since certain
+ SRM consoles screw up and allocate I/O space addresses > 64K behind
+ PCI-to_PCI bridges, which can't pass addresses larger than 64K... */
+#if defined(CONFIG_ALPHA_EISA)
+static unsigned int io_base = 0x9000; /* start above 8th slot */
#else
-static unsigned int io_base = 0xb000;
+static unsigned int io_base = 0x8000;
#endif
#if defined(CONFIG_ALPHA_XL)
/*
- an AVANTI *might* be an XL, and an XL has only 27 bits of ISA address
- that get passed through the PCI<->ISA bridge chip. Because this causes
- us to set the PCI->Mem window bases lower than normal, we've gotta allocate
- PCI bus devices' memory addresses *above* the PCI<->memory mapping windows,
- so that CPU memory DMA addresses issued by a bus device don't conflict
- with bus memory addresses, like frame buffer memory for graphics cards.
+ An XL is AVANTI (APECS) family, *but* it has only 27 bits of ISA address
+ that get passed through the PCI<->ISA bridge chip. Although this causes
+ us to set the PCI->Mem window bases lower than normal, we still allocate
+ PCI bus devices' memory addresses *below* the low DMA mapping window,
+ and hope they fit below 64Mb (to avoid conflicts), and so that they can
+ be accessed via SPARSE space.
+
+ We accept the risk that a broken Myrinet card will be put into a true XL
+ and thus can more easily run into the problem described below.
+*/
+static unsigned int mem_base = 16*MB + 2*MB; /* 16M to 64M-1 is avail */
+
+#elif defined(CONFIG_ALPHA_LCA) || defined(CONFIG_ALPHA_APECS)
+/*
+ We try to make this address *always* have more than 1 bit set.
+ this is so that devices like the broken Myrinet card will always have
+ a PCI memory address that will never match a IDSEL address in
+ PCI Config space, which can cause problems with early rev cards.
+
+ However, APECS and LCA have only 34 bits for physical addresses, thus
+ limiting PCI bus memory addresses for SPARSE access to be less than 128Mb.
+*/
+static unsigned int mem_base = 64*MB + 2*MB;
+
+#else
+/*
+ We try to make this address *always* have more than 1 bit set.
+ this is so that devices like the broken Myrinet card will always have
+ a PCI memory address that will never match a IDSEL address in
+ PCI Config space, which can cause problems with early rev cards.
+
+ Because CIA and PYXIS and T2 have more bits for physical addresses,
+ they support an expanded range of SPARSE memory addresses.
*/
-static unsigned int mem_base = 1024*MB;
-#else /* CONFIG_ALPHA_XL */
-static unsigned int mem_base = 16*MB; /* <16MB is ISA memory */
+static unsigned int mem_base = 128*MB + 16*MB;
#endif /* CONFIG_ALPHA_XL */
/*
@@ -128,7 +168,7 @@
struct pci_bus *bus;
unsigned short cmd;
-#if defined(CONFIG_ALPHA_MIKASA) || defined(CONFIG_ALPHA_ALCOR)
+#if defined(CONFIG_ALPHA_EISA)
/*
* HACK: the PCI-to-EISA bridge does not seem to identify
* itself as a bridge... :-(
@@ -139,6 +179,18 @@
}
#endif
+ /*
+ * we don't have code that will init the CYPRESS bridge correctly
+ * so we do the next best thing, and depend on the previous
+ * console code to do the right thing, and ignore it here... :-\
+ */
+ if ((dev->vendor == 0x1080) && (dev->device == 0xC693)) {
+#if 0
+ printk("disable_dev: ignoring CYPRESS bridge...\n");
+#endif
+ return;
+ }
+
bus = dev->bus;
pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
@@ -160,7 +212,7 @@
unsigned int base, mask, size, reg;
unsigned int alignto;
-#if defined(CONFIG_ALPHA_MIKASA) || defined(CONFIG_ALPHA_ALCOR)
+#if defined(CONFIG_ALPHA_EISA)
/*
* HACK: the PCI-to-EISA bridge does not seem to identify
* itself as a bridge... :-(
@@ -171,10 +223,36 @@
}
#endif
+ /*
+ * we don't have code that will init the CYPRESS bridge correctly
+ * so we do the next best thing, and depend on the previous
+ * console code to do the right thing, and ignore it here... :-\
+ */
+ if ((dev->vendor == 0x1080) && (dev->device == 0xC693)) {
+#if 0
+ printk("layout_dev: ignoring CYPRESS bridge...\n");
+#endif
+ return;
+ }
+
bus = dev->bus;
pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
+
+#ifdef NOT_NOW
+ if ((dev->vendor == 0x1080) && (dev->device == 0xC693) &&
+ ((PCI_FUNC(dev->devfn) == 1) || (PCI_FUNC(dev->devfn) == 2)))
+ { /* if primary or secondary IDE on the CYPRESS bridge */
+ if ((reg == PCI_BASE_ADDRESS_0) || (reg == PCI_BASE_ADDRESS_1)) {
+#if 0
+ printk("layout_dev: ignoring CYPRESS IDE base reg 0/1\n");
+#endif
+ continue; /* ignore first two registers */
+ }
+ }
+#endif /* NOT_NOW */
+
/*
* Figure out how much space and of what type this
* device wants.
@@ -182,6 +260,10 @@
pcibios_write_config_dword(bus->number, dev->devfn, reg,
0xffffffff);
pcibios_read_config_dword(bus->number, dev->devfn, reg, &base);
+#if 0
+printk("layout_dev: slot %d fn %d off 0x%x base 0x%x\n",
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), reg, base);
+#endif
if (!base) {
/* this base-address register is unused */
continue;
@@ -201,11 +283,23 @@
mask = (~base << 1) | 0x1;
size = (mask & base) & 0xffffffff;
/* align to multiple of size of minimum base */
+#if 0
alignto = MAX(0x400, size) ;
+#else
+ /*
+ If we align to 0x800 bounds, we probably avoid
+ having devices in any 0xzCzz range, which is
+ where the DE4X5 driver probes for EISA cards.
+ Adaptecs, especially, resent such intrusions. :-(
+ */
+ alignto = MAX(0x800, size) ;
+#endif
base = ALIGN(io_base, alignto );
io_base = base + size;
pcibios_write_config_dword(bus->number, dev->devfn,
reg, base | 0x1);
+ DBG_DEVS(("layout_dev: dev 0x%x IO @ 0x%x (0x%x)\n",
+ dev->device, base, size));
} else {
unsigned int type;
/*
@@ -266,7 +360,7 @@
base = ALIGN(mem_base, alignto);
if (size > 7 * 16*MB) {
printk("bios32 WARNING: slot %d, function %d "
- "requests %dB of contiguous address "
+ "requests 0x%x bytes of contig address "
" space---don't use sparse memory "
" accesses on this device!!\n",
PCI_SLOT(dev->devfn),
@@ -277,7 +371,8 @@
base += 16*MB;
base = ALIGN(base, alignto);
}
- if (base / (128*MB) != (base + size) / (128*MB)) {
+ if (base / (128*MB) != (base + size) / (128*MB))
+ {
base &= ~(128*MB - 1);
base += (128 + 16)*MB;
base = ALIGN(base, alignto);
@@ -286,13 +381,15 @@
mem_base = base + size;
pcibios_write_config_dword(bus->number, dev->devfn,
reg, base);
+ DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%x (0x%x)\n",
+ dev->device, base, size));
}
- }
+ } /* end for-loop */
/* enable device: */
if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED ||
dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA ||
- dev->class >> 8 == PCI_CLASS_DISPLAY_VGA ||
- dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)
+ dev->class >> 8 == PCI_CLASS_STORAGE_IDE ||
+ dev->class >> 16 == PCI_BASE_CLASS_DISPLAY)
{
/*
* All of these (may) have I/O scattered all around
@@ -305,21 +402,24 @@
pcibios_write_config_word(bus->number, dev->devfn, PCI_COMMAND,
cmd | PCI_COMMAND_MASTER);
- DBG_DEVS(("layout_dev: bus %d slot 0x%x VID 0x%x DID 0x%x class 0x%x\n",
- bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class));
+
+ DBG_DEVS(("layout_dev: bus %d slot %d VID 0x%x DID 0x%x class 0x%x cmd 0x%x\n",
+ bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device,
+ dev->class, cmd|PCI_COMMAND_MASTER));
}
-static void layout_bus(struct pci_bus *bus)
+static int layout_bus(struct pci_bus *bus)
{
unsigned int l, tio, bio, tmem, bmem;
struct pci_bus *child;
struct pci_dev *dev;
+ int found_vga = 0;
DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
if (!bus->devices && !bus->children)
- return;
+ return 0;
/*
* Align the current bases on appropriate boundaries (4K for
@@ -338,7 +438,11 @@
* decoders are programmed consistently.
*/
for (dev = bus->devices; dev; dev = dev->sibling) {
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) {
+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
+#ifdef CONFIG_ALPHA_BOOK1
+ || (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)
+#endif /* CONFIG_ALPHA_BOOK1 */
+ ) {
disable_dev(dev) ;
}
}
@@ -349,9 +453,15 @@
DBG_DEVS(("layout_bus: starting bus %d devices\n", bus->number));
for (dev = bus->devices; dev; dev = dev->sibling) {
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) {
+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
+#ifdef CONFIG_ALPHA_BOOK1
+ || (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)
+#endif /* CONFIG_ALPHA_BOOK1 */
+ ) {
layout_dev(dev);
}
+ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
+ found_vga = 1;
}
/*
* Recursively allocate space for all of the sub-buses:
@@ -359,7 +469,7 @@
DBG_DEVS(("layout_bus: starting bus %d children\n", bus->number));
for (child = bus->children; child; child = child->next) {
- layout_bus(child);
+ found_vga += layout_bus(child);
}
/*
* Align the current bases on 4K and 1MB boundaries:
@@ -375,7 +485,8 @@
*/
pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
0x1c, &l);
- l = (l & 0xffff0000) | ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000);
+ l = (l & 0xffff0000) | ((bio >> 8) & 0x00f0) |
+ ((tio - 1) & 0xf000);
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x1c, l);
/*
@@ -391,10 +502,13 @@
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x24, 0x0000ffff);
/*
- * Tell bridge that there is an ISA bus in the system:
+ * Tell bridge that there is an ISA bus in the system,
+ * and (possibly) a VGA as well.
*/
+ l = 0x00040000; /* ISA present */
+ if (found_vga) l |= 0x00080000; /* VGA present */
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
- 0x3c, 0x00040000);
+ 0x3c, l);
/*
* Clear status bits, enable I/O (for downstream I/O),
* turn on master enable (for upstream I/O), turn on
@@ -404,6 +518,7 @@
pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
0x4, 0xffff0007);
}
+ return found_vga;
}
#endif /* !PCI_MODIFY */
@@ -501,9 +616,9 @@
}
/*
- * A small note about bridges and interrupts. The DECchip 21050 (and later chips)
- * adheres to the PCI-PCI bridge specification. This says that the interrupts on
- * the other side of a bridge are swizzled in the following manner:
+ * A small note about bridges and interrupts. The DC 21050 (and later chips)
+ * adheres to the PCI-PCI bridge specification. This says that the interrupts
+ * on the other side of a bridge are swizzled in the following manner:
*
* Dev Interrupt Interrupt
* Pin on Pin on
@@ -541,13 +656,86 @@
return (((pin-1) + slot) % 4) + 1 ;
}
+#ifdef CONFIG_ALPHA_SRM_SETUP
+/* look for mis-configured devices' IO space addresses behind bridges */
+static void check_behind_io(struct pci_dev *dev)
+{
+ struct pci_bus *bus = dev->bus;
+ unsigned int reg, orig_base, new_base, found_one = 0;
+
+ for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
+ /* read the current setting, check for I/O space and >= 64K */
+ pcibios_read_config_dword(bus->number, dev->devfn, reg, &orig_base);
+ if (!orig_base || !(orig_base & PCI_BASE_ADDRESS_SPACE_IO))
+ continue; /* unused or non-IO */
+ if (orig_base < 64*1024) {
+#if 1
+printk("check_behind_io: ALREADY OK! bus %d slot %d base 0x%x\n",
+ bus->number, PCI_SLOT(dev->devfn), orig_base);
+#endif
+ if (orig_base & ~1)
+ continue; /* OK! */
+ orig_base = 0x12001; /* HACK! FIXME!! */
+ }
+
+ /* HACK ALERT! for now, just subtract 32K from the
+ original address, which should give us addresses
+ in the range 0x8000 and up */
+ new_base = orig_base - 0x8000;
+#if 1
+printk("check_behind_io: ALERT! bus %d slot %d old 0x%x new 0x%x\n",
+ bus->number, PCI_SLOT(dev->devfn), orig_base, new_base);
+#endif
+ pcibios_write_config_dword(bus->number, dev->devfn,
+ reg, new_base);
+
+ io_dev_to_reset[io_reset_count] = dev;
+ io_reg_to_reset[io_reset_count] = reg;
+ io_to_reset[io_reset_count] = orig_base;
+ io_reset_count++;
+ found_one++;
+ } /* end for-loop */
+
+ /* if any were modified, gotta hack the bridge IO limits too... */
+ if (found_one) {
+ if (bus->self) {
+ struct pci_dev *bridge = bus->self;
+ unsigned int l;
+ /*
+ * Set up the top and bottom of the PCI I/O segment
+ * for this bus.
+ */
+ pcibios_read_config_dword(bridge->bus->number,
+ bridge->devfn, 0x1c, &l);
+#if 1
+printk("check_behind_io: ALERT! bus %d slot %d oldLIM 0x%x\n",
+ bus->number, PCI_SLOT(bridge->devfn), l);
+#endif
+ l = (l & 0xffff0000U) | 0xf080U; /* give it ALL */
+ pcibios_write_config_dword(bridge->bus->number,
+ bridge->devfn, 0x1c, l);
+ pcibios_write_config_dword(bridge->bus->number,
+ bridge->devfn,
+ 0x3c, 0x00040000);
+ pcibios_write_config_dword(bridge->bus->number,
+ bridge->devfn,
+ 0x4, 0xffff0007);
+ } else
+ printk("check_behind_io: WARNING! bus->self NULL\n");
+ }
+}
+#endif /* CONFIG_ALPHA_SRM_SETUP */
+
/*
* Most evaluation boards share most of the fixup code, which is isolated here.
* This function is declared "inline" as only one platform will ever be selected
* in any given kernel. If that platform doesn't need this code, we don't want
* it around as dead code.
*/
-static inline void common_fixup(long min_idsel, long max_idsel, long irqs_per_slot,
+static inline void common_fixup(
+ long min_idsel,
+ long max_idsel,
+ long irqs_per_slot,
char irq_tab[max_idsel - min_idsel + 1][irqs_per_slot],
long ide_base)
{
@@ -559,37 +747,122 @@
* Go through all devices, fixing up irqs as we see fit:
*/
for (dev = pci_devices; dev; dev = dev->next) {
- if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE
-#if defined(CONFIG_ALPHA_MIKASA) || defined(CONFIG_ALPHA_ALCOR)
+ if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
+#if defined(CONFIG_ALPHA_EISA)
/* PCEB (PCI to EISA bridge) does not identify
itself as a bridge... :-( */
&& !((dev->vendor==0x8086) && (dev->device==0x482))
#endif
+#ifdef CONFIG_ALPHA_BOOK1
+ || (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA)
+#endif /* CONFIG_ALPHA_BOOK1 */
) {
dev->irq = 0;
/*
- * This device is not on the primary bus, we need to figure out which
- * interrupt pin it will come in on. We know which slot it will come
- * in on 'cos that slot is where the bridge is. Each time the interrupt
- * line passes through a PCI-PCI bridge we must apply the swizzle function
+ * This device is not on the primary bus,
+ * we need to figure out which
+ * interrupt pin it will come in on.
+ * We know which slot it will come
+ * in on 'cuz that slot is where the bridge is.
+ * Each time the interrupt
+ * line passes through a PCI-PCI bridge
+ * we must apply the swizzle function
* (see the inline static routine above).
*/
if (dev->bus->number != 0) {
- struct pci_dev *curr = dev ;
- /* read the pin and do the PCI-PCI bridge interrupt pin swizzle */
- pcibios_read_config_byte(dev->bus->number, dev->devfn,
- PCI_INTERRUPT_PIN, &pin);
+ /* read the pin and do the PCI-PCI bridge
+ interrupt pin swizzle */
+ pcibios_read_config_byte(dev->bus->number,
+ dev->devfn,
+ PCI_INTERRUPT_PIN,
+ &pin);
/* cope with 0 */
if (pin == 0) pin = 1 ;
- /* follow the chain of bridges, swizzling as we go */
+ /* follow the chain of bridges,
+ swizzling as we go */
+#if defined(CONFIG_ALPHA_MIATA)
+ /* check first for the built-in bridge */
+ if ((PCI_SLOT(dev->bus->self->devfn) == 8) ||
+ (PCI_SLOT(dev->bus->self->devfn) == 20)) {
+ slot = PCI_SLOT(dev->devfn) + 9;
+#if 0
+ printk("MIATA: bus 1 slot %d pin %d irq %d "
+ "min_idsel %d\n",
+ PCI_SLOT(dev->devfn), pin,
+ irq_tab[slot - min_idsel][pin],
+ min_idsel);
+#endif
+ }
+ else /* must be a card-based bridge */
+ {
+ struct pci_dev *curr = dev ;
do {
+ if ((PCI_SLOT(curr->bus->self->devfn) == 8) ||
+ (PCI_SLOT(curr->bus->self->devfn) == 20))
+ {
+ slot = PCI_SLOT(curr->devfn) + 5;
+ break;
+ }
/* swizzle */
- pin = bridge_swizzle(pin, PCI_SLOT(curr->devfn)) ;
+ pin = bridge_swizzle(
+ pin, PCI_SLOT(curr->devfn)) ;
+ /* move up the chain of bridges */
+ curr = curr->bus->self ;
+ /* slot of the next bridge. */
+ slot = PCI_SLOT(curr->devfn);
+ } while (curr->bus->self) ;
+ }
+#elif defined(CONFIG_ALPHA_NORITAKE)
+ /* check first for the built-in bridge */
+ if (PCI_SLOT(dev->bus->self->devfn) == 8) {
+ slot = PCI_SLOT(dev->devfn) + 15; /* WAG! */
+#if 0
+ printk("NORITAKE: bus 1 slot %d pin %d "
+ "irq %d min_idsel %d\n",
+ PCI_SLOT(dev->devfn), pin,
+ irq_tab[slot - min_idsel][pin],
+ min_idsel);
+#endif
+ }
+ else /* must be a card-based bridge */
+ {
+ struct pci_dev *curr = dev ;
+ do {
+ if (PCI_SLOT(curr->bus->self->devfn) == 8) {
+ slot = PCI_SLOT(curr->devfn) + 15;
+ break;
+ }
+ /* swizzle */
+ pin = bridge_swizzle(
+ pin, PCI_SLOT(curr->devfn)) ;
+ /* move up the chain of bridges */
+ curr = curr->bus->self ;
+ /* slot of the next bridge. */
+ slot = PCI_SLOT(curr->devfn);
+ } while (curr->bus->self) ;
+ }
+#else /* not MIATA or NORITAKE */
+ {
+ struct pci_dev *curr = dev ;
+ do {
+ /* swizzle */
+ pin = bridge_swizzle(
+ pin, PCI_SLOT(curr->devfn)) ;
/* move up the chain of bridges */
curr = curr->bus->self ;
} while (curr->bus->self) ;
/* The slot is the slot of the last bridge. */
slot = PCI_SLOT(curr->devfn) ;
+ }
+#endif /* not MIATA or NORITAKE */
+#ifdef CONFIG_ALPHA_SRM_SETUP
+ /*
+ must make sure that SRM didn't screw up
+ and allocate an address > 64K for I/O
+ space behind a PCI-PCI bridge
+ */
+ check_behind_io(dev);
+#endif /* CONFIG_ALPHA_SRM_SETUP */
} else {
/* work out the slot */
slot = PCI_SLOT(dev->devfn) ;
@@ -601,28 +874,193 @@
}
if (irq_tab[slot - min_idsel][pin] != -1)
dev->irq = irq_tab[slot - min_idsel][pin];
-#if PCI_MODIFY
- /* tell the device: */
+
+#ifdef CONFIG_ALPHA_SRM
+ {
+ unsigned char irq_orig;
+ /* read the original SRM-set IRQ and tell */
+ pcibios_read_config_byte(dev->bus->number,
+ dev->devfn,
+ PCI_INTERRUPT_LINE,
+ &irq_orig);
+ if (irq_orig != dev->irq) {
+ printk("common_fixup: bus %d slot 0x%x "
+ "SRM IRQ 0x%x changed to 0x%x\n",
+ dev->bus->number,PCI_SLOT(dev->devfn),
+ irq_orig, dev->irq);
+#ifdef CONFIG_ALPHA_SRM_SETUP
+ irq_dev_to_reset[irq_reset_count] = dev;
+ irq_to_reset[irq_reset_count] = irq_orig;
+ irq_reset_count++;
+#endif /* CONFIG_ALPHA_SRM_SETUP */
+ }
+ }
+#endif /* SRM */
+
+ /* always tell the device, so the driver knows */
pcibios_write_config_byte(dev->bus->number, dev->devfn,
PCI_INTERRUPT_LINE, dev->irq);
-#endif
+
+ DBG_DEVS(("common_fixup: bus %d slot 0x%x VID 0x%x DID 0x%x\n"
+ " int_slot 0x%x pin 0x%x irq 0x%x\n",
+ dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor,
+ dev->device, slot, pin, dev->irq));
+
/*
* if it's a VGA, enable its BIOS ROM at C0000
*/
if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
- pcibios_write_config_dword(dev->bus->number,
+ /* but if its a Cirrus 543x/544x DISABLE it, */
+ /* since enabling ROM disables the memory... */
+ if ((dev->vendor == PCI_VENDOR_ID_CIRRUS) &&
+ (dev->device >= 0x00a0) &&
+ (dev->device <= 0x00ac)) {
+ pcibios_write_config_dword(
+ dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x00000000);
+ } else {
+ pcibios_write_config_dword(
+ dev->bus->number,
dev->devfn,
PCI_ROM_ADDRESS,
0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
}
}
+ /*
+ * if it's a SCSI, disable its BIOS ROM
+ */
+ if ((dev->class >> 8) == PCI_CLASS_STORAGE_SCSI) {
+ pcibios_write_config_dword(dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x0000000);
+ }
+#ifdef NOT_NOW
+ if ((dev->vendor == 0x1080) && (dev->device == 0xC693)
+ && (PCI_FUNC(dev->devfn) == 1))
+ {
+#if 0
+{
+int i; unsigned char b; unsigned short w; unsigned int d;
+ pcibios_read_config_word(dev->bus->number, dev->devfn, 4, &w);
+ printk("common_fixup: CYPRESS fn 1: PCI CMD reg = 0x%x\n", w);
+ pcibios_read_config_word(dev->bus->number, dev->devfn, 6, &w);
+ printk("common_fixup: CYPRESS fn 1: PCI STS reg = 0x%x\n", w);
+ for (i = 0x10; i <= 0x14; i+=4) {
+ pcibios_read_config_dword(dev->bus->number, dev->devfn, i, &d);
+ printk("common_fixup: CYPRESS fn 1: PCI register offset 0x%x = 0x%x\n",i,d);
+ }
+ pcibios_read_config_dword(dev->bus->number, dev->devfn, 0x20, &d);
+ printk("common_fixup: CYPRESS fn 1: PCI register offset 0x20 = 0x%x\n", d);
+ for (i = 0x3c; i <= 0x3d; i++) {
+ pcibios_read_config_byte(dev->bus->number, dev->devfn, i, &b);
+ printk("common_fixup: CYPRESS fn 1: PCI register offset 0x%x = 0x%x\n",i,b);
+ }
+ pcibios_read_config_dword(dev->bus->number, dev->devfn, 0x40, &d);
+ printk("common_fixup: CYPRESS fn 1: PCI register offset 0x40 = 0x%x\n",d);
+}
+#endif
+ }
+ if ((dev->vendor == 0x1080) && (dev->device == 0xC693)
+ && (PCI_FUNC(dev->devfn) == 2))
+ {
+#if 0
+{
+int i; unsigned char b; unsigned short w; unsigned int d;
+ pcibios_read_config_word(dev->bus->number, dev->devfn, 4, &w);
+ printk("common_fixup: CYPRESS fn 2: PCI CMD reg = 0x%x\n", w);
+ pcibios_read_config_word(dev->bus->number, dev->devfn, 6, &w);
+ printk("common_fixup: CYPRESS fn 2: PCI STS reg = 0x%x\n", w);
+ for (i = 0x10; i <= 0x14; i+=4) {
+ pcibios_read_config_dword(dev->bus->number, dev->devfn, i, &d);
+ printk("common_fixup: CYPRESS fn 2: PCI register offset 0x%x = 0x%x\n",i,d);
+ }
+ pcibios_read_config_dword(dev->bus->number, dev->devfn, 0x20, &d);
+ printk("common_fixup: CYPRESS fn 2: PCI register offset 0x20 = 0x%x\n", d);
+ for (i = 0x3c; i <= 0x3d; i++) {
+ pcibios_read_config_byte(dev->bus->number, dev->devfn, i, &b);
+ printk("common_fixup: CYPRESS fn 2: PCI register offset 0x%x = 0x%x\n",i,b);
+ }
+ pcibios_read_config_dword(dev->bus->number, dev->devfn, 0x40, &d);
+ printk("common_fixup: CYPRESS fn 2: PCI register offset 0x40 = 0x%x\n",d);
+}
+#endif
+ }
+#endif /* NOT_NOW */
+ } else { /* it *is* a bridge... */
+#ifdef NOT_NOW
+ /*
+ * if it's CYPRESS PCI-ISA bridge, disable IDE
+ * interrupt routing through PCI (ie do through PIC)
+ */
+ if ((dev->vendor == 0x1080) && (dev->device == 0xC693)
+ && (PCI_FUNC(dev->devfn) == 0))
+ {
+#if 0
+{
+int i; unsigned char d; unsigned short w;
+ pcibios_read_config_word(dev->bus->number, dev->devfn, 4, &w);
+ printk("common_fixup: CYPRESS fn 0: PCI CMD reg = 0x%x\n", w);
+ for (i = 0x40; i < 0x50; i++) {
+ pcibios_read_config_byte(dev->bus->number, dev->devfn, i, &d);
+ printk("common_fixup: CYPRESS fn 0: PCI register offset 0x%x = 0x%x\n",
+ i, d);
+ }
+ for (i=1; i <= 5; i++) {
+ outb(i, 0x22);
+ printk("CY control reg %d: 0x%02x\n", i, inb(0x23));
+ }
+}
+#endif
+#if 0
+ pcibios_write_config_word(dev->bus->number,
+ dev->devfn, 0x04, 0x0007);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x40, 0x80);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x41, 0x80);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x42, 0x80);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x43, 0x80);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x44, 0x27);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x45, 0xe0);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x48, 0xf0);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x49, 0x40);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x4a, 0x00);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x4b, 0x80);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x4c, 0x80);
+ pcibios_write_config_byte(dev->bus->number,
+ dev->devfn, 0x4d, 0x70);
+#endif
+ outb(0, DMA1_RESET_REG);
+ outb(0, DMA2_RESET_REG);
+ outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+ outb(0, DMA2_MASK_REG);
+#if 0
+ outb(0, DMA1_CLR_MASK_REG);
+ outb(0, DMA2_CLR_MASK_REG);
+#endif
+ }
+#endif /* NOT_NOW */
+ }
}
if (ide_base) {
enable_ide(ide_base);
}
}
+
/*
* The EB66+ is very similar to the EB66 except that it does not have
* the on-board NCR and Tulip chips. In the code below, I have used
@@ -639,6 +1077,7 @@
static inline void eb66p_fixup(void)
{
char irq_tab[5][5] = {
+ /*INT INTA INTB INTC INTD */
{16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J25 */
{16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J26 */
{ -1, -1, -1, -1, -1}, /* IdSel 8, SIO */
@@ -650,7 +1089,7 @@
/*
- * The PC164 has 19 PCI interrupts, four from each of the four PCI
+ * The PC164/LX164 have 19 PCI interrupts, four from each of the four PCI
* slots, the SIO, PCI/IDE, and USB.
*
* Each of the interrupts can be individually masked. This is
@@ -693,12 +1132,9 @@
static inline void alphapc164_fixup(void)
{
- extern int SMCInit(void);
+ extern void SMC93X_Init(void);
char irq_tab[7][5] = {
- /*
- * int intA intB intC intD
- * ---- ---- ---- ---- ----
- */
+ /*INT INTA INTB INTC INTD */
{ 16+2, 16+2, 16+9, 16+13, 16+17}, /* IdSel 5, slot 2, J20 */
{ 16+0, 16+0, 16+7, 16+11, 16+15}, /* IdSel 6, slot 0, J29 */
{ 16+1, 16+1, 16+8, 16+12, 16+16}, /* IdSel 7, slot 1, J26 */
@@ -710,7 +1146,7 @@
common_fixup(5, 11, 5, irq_tab, 0);
- SMCInit();
+ SMC93X_Init();
}
/*
@@ -729,6 +1165,7 @@
static inline void cabriolet_fixup(void)
{
char irq_tab[5][5] = {
+ /*INT INTA INTB INTC INTD */
{ 16+2, 16+2, 16+7, 16+11, 16+15}, /* IdSel 5, slot 2, J21 */
{ 16+0, 16+0, 16+5, 16+9, 16+13}, /* IdSel 6, slot 0, J19 */
{ 16+1, 16+1, 16+6, 16+10, 16+14}, /* IdSel 7, slot 1, J20 */
@@ -785,6 +1222,7 @@
static inline void eb66_and_eb64p_fixup(void)
{
char irq_tab[5][5] = {
+ /*INT INTA INTB INTC INTD */
{16+7, 16+7, 16+7, 16+7, 16+7}, /* IdSel 5, slot ?, ?? */
{16+0, 16+0, 16+2, 16+4, 16+9}, /* IdSel 6, slot ?, ?? */
{16+1, 16+1, 16+3, 16+8, 16+10}, /* IdSel 7, slot ?, ?? */
@@ -796,7 +1234,7 @@
/*
- * Fixup configuration for MIKASA (NORITAKE is different)
+ * Fixup configuration for MIKASA
*
* Summary @ 0x536:
* Bit Meaning
@@ -848,6 +1286,86 @@
}
/*
+ * Fixup configuration for NORITAKE
+ *
+ * Summary @ 0x542, summary register #1:
+ * Bit Meaning
+ * 0 All valid ints from summary regs 2 & 3
+ * 1 QLOGIC ISP1020A SCSI
+ * 2 Interrupt Line A from slot 0
+ * 3 Interrupt Line B from slot 0
+ * 4 Interrupt Line A from slot 1
+ * 5 Interrupt line B from slot 1
+ * 6 Interrupt Line A from slot 2
+ * 7 Interrupt Line B from slot 2
+ * 8 Interrupt Line A from slot 3
+ * 9 Interrupt Line B from slot 3
+ *10 Interrupt Line A from slot 4
+ *11 Interrupt Line B from slot 4
+ *12 Interrupt Line A from slot 5
+ *13 Interrupt Line B from slot 5
+ *14 Interrupt Line A from slot 6
+ *15 Interrupt Line B from slot 6
+ *
+ * Summary @ 0x544, summary register #2:
+ * Bit Meaning
+ * 0 OR of all unmasked ints in SR #2
+ * 1 OR of secondary bus ints
+ * 2 Interrupt Line C from slot 0
+ * 3 Interrupt Line D from slot 0
+ * 4 Interrupt Line C from slot 1
+ * 5 Interrupt line D from slot 1
+ * 6 Interrupt Line C from slot 2
+ * 7 Interrupt Line D from slot 2
+ * 8 Interrupt Line C from slot 3
+ * 9 Interrupt Line D from slot 3
+ *10 Interrupt Line C from slot 4
+ *11 Interrupt Line D from slot 4
+ *12 Interrupt Line C from slot 5
+ *13 Interrupt Line D from slot 5
+ *14 Interrupt Line C from slot 6
+ *15 Interrupt Line D from slot 6
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot Device
+ * 7 Intel PCI-EISA bridge chip
+ * 8 DEC PCI-PCI bridge chip
+ * 11 PCI on board slot 0
+ * 12 PCI on board slot 1
+ * 13 PCI on board slot 2
+ *
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and
+ * above for PCI interrupts. The IRQ relates to which bit the interrupt
+ * comes in on. This makes interrupt processing much easier.
+ */
+static inline void noritake_fixup(void)
+{
+ char irq_tab[15][5] = {
+ /*INT INTA INTB INTC INTD */
+ /* note: IDSELs 16, 17, and 25 are CORELLE only */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */
+ { -1, -1, -1, -1, -1}, /* IdSel 17, S3 Trio64 */
+ { -1, -1, -1, -1, -1}, /* IdSel 18, PCEB */
+ { -1, -1, -1, -1, -1}, /* IdSel 19, PPB */
+ { -1, -1, -1, -1, -1}, /* IdSel 20, ???? */
+ { -1, -1, -1, -1, -1}, /* IdSel 21, ???? */
+ { 16+2, 16+2, 16+3, 32+2, 32+3}, /* IdSel 22, slot 0 */
+ { 16+4, 16+4, 16+5, 32+4, 32+5}, /* IdSel 23, slot 1 */
+ { 16+6, 16+6, 16+7, 32+6, 32+7}, /* IdSel 24, slot 2 */
+ { 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 25, slot 3 */
+ /* the following 5 are actually on PCI bus 1, across the bridge */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* IdSel 16, QLOGIC */
+ { 16+8, 16+8, 16+9, 32+8, 32+9}, /* IdSel 17, slot 3 */
+ {16+10, 16+10, 16+11, 32+10, 32+11}, /* IdSel 18, slot 4 */
+ {16+12, 16+12, 16+13, 32+12, 32+13}, /* IdSel 19, slot 5 */
+ {16+14, 16+14, 16+15, 32+14, 32+15}, /* IdSel 20, slot 6 */
+ };
+ common_fixup(5, 19, 5, irq_tab, 0);
+}
+
+/*
* Fixup configuration for ALCOR
*
* Summary @ GRU_INT_REQ:
@@ -892,8 +1410,10 @@
*/
static inline void alcor_fixup(void)
{
- char irq_tab[6][5] = {
+ char irq_tab[7][5] = {
/*INT INTA INTB INTC INTD */
+ /* note: IDSEL 17 is XLT only */
+ {16+13, 16+13, 16+13, 16+13, 16+13}, /* IdSel 17, TULIP */
{ 16+8, 16+8, 16+9, 16+10, 16+11}, /* IdSel 18, slot 0 */
{16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 19, slot 3 */
{16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 20, slot 4 */
@@ -901,9 +1421,10 @@
{ 16+0, 16+0, 16+1, 16+2, 16+3}, /* IdSel 22, slot 2 */
{ 16+4, 16+4, 16+5, 16+6, 16+7}, /* IdSel 23, slot 1 */
};
- common_fixup(7, 12, 5, irq_tab, 0);
+ common_fixup(6, 12, 5, irq_tab, 0);
}
+#if 0
/*
* Fixup configuration for ALPHA XLT (EV5/EV56)
*
@@ -959,7 +1480,303 @@
};
common_fixup(6, 12, 5, irq_tab, 0);
}
+#endif /* 0 */
+/*
+ * Fixup configuration for ALPHA SABLE (2100) - 2100A is different ??
+ *
+ * Summary Registers (536/53a/53c):
+ * Bit Meaning
+ *-----------------
+ * 0 PCI slot 0
+ * 1 NCR810 (builtin)
+ * 2 TULIP (builtin)
+ * 3 mouse
+ * 4 PCI slot 1
+ * 5 PCI slot 2
+ * 6 keyboard
+ * 7 floppy
+ * 8 COM2
+ * 9 parallel port
+ *10 EISA irq 3
+ *11 EISA irq 4
+ *12 EISA irq 5
+ *13 EISA irq 6
+ *14 EISA irq 7
+ *15 COM1
+ *16 EISA irq 9
+ *17 EISA irq 10
+ *18 EISA irq 11
+ *19 EISA irq 12
+ *20 EISA irq 13
+ *21 EISA irq 14
+ *22 NC
+ *23 IIC
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot Device
+ * 0 TULIP
+ * 1 SCSI
+ * 2 PCI-EISA bridge
+ * 3 none
+ * 4 none
+ * 5 none
+ * 6 PCI on board slot 0
+ * 7 PCI on board slot 1
+ * 8 PCI on board slot 2
+ *
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and
+ * above for PCI interrupts. The IRQ relates to which bit the interrupt
+ * comes in on. This makes interrupt processing much easier.
+ */
+/* NOTE: the IRQ assignments below are arbitrary, but need to be consistent
+ with the values in the sable_irq_to_mask[] and sable_mask_to_irq[] tables
+ in irq.c
+ */
+static inline void sable_fixup(void)
+{
+ char irq_tab[9][5] = {
+ /*INT INTA INTB INTC INTD */
+ { 32+0, 32+0, 32+0, 32+0, 32+0}, /* IdSel 0, TULIP */
+ { 32+1, 32+1, 32+1, 32+1, 32+1}, /* IdSel 1, SCSI */
+ { -1, -1, -1, -1, -1}, /* IdSel 2, SIO */
+ { -1, -1, -1, -1, -1}, /* IdSel 3, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 4, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 5, none */
+ { 32+2, 32+2, 32+2, 32+2, 32+2}, /* IdSel 6, slot 0 */
+ { 32+3, 32+3, 32+3, 32+3, 32+3}, /* IdSel 7, slot 1 */
+ { 32+4, 32+4, 32+4, 32+4, 32+4}, /* IdSel 8, slot 2 */
+ };
+ common_fixup(0, 8, 5, irq_tab, 0);
+}
+
+/*
+ * Fixup configuration for MIATA (EV56+PYXIS)
+ *
+ * Summary @ PYXIS_INT_REQ:
+ * Bit Meaning
+ * 0 Fan Fault
+ * 1 NMI
+ * 2 Halt/Reset switch
+ * 3 none
+ * 4 CID0 (Riser ID)
+ * 5 CID1 (Riser ID)
+ * 6 Interval timer
+ * 7 PCI-ISA Bridge
+ * 8 Ethernet
+ * 9 EIDE (deprecated, ISA 14/15 used)
+ *10 none
+ *11 USB
+ *12 Interrupt Line A from slot 4
+ *13 Interrupt Line B from slot 4
+ *14 Interrupt Line C from slot 4
+ *15 Interrupt Line D from slot 4
+ *16 Interrupt Line A from slot 5
+ *17 Interrupt line B from slot 5
+ *18 Interrupt Line C from slot 5
+ *19 Interrupt Line D from slot 5
+ *20 Interrupt Line A from slot 1
+ *21 Interrupt Line B from slot 1
+ *22 Interrupt Line C from slot 1
+ *23 Interrupt Line D from slot 1
+ *24 Interrupt Line A from slot 2
+ *25 Interrupt Line B from slot 2
+ *26 Interrupt Line C from slot 2
+ *27 Interrupt Line D from slot 2
+ *27 Interrupt Line A from slot 3
+ *29 Interrupt Line B from slot 3
+ *30 Interrupt Line C from slot 3
+ *31 Interrupt Line D from slot 3
+ *
+ * The device to slot mapping looks like:
+ *
+ * Slot Device
+ * 3 DC21142 Ethernet
+ * 4 EIDE CMD646
+ * 5 none
+ * 6 USB
+ * 7 PCI-ISA bridge
+ * 8 PCI-PCI Bridge (SBU Riser)
+ * 9 none
+ * 10 none
+ * 11 PCI on board slot 4 (SBU Riser)
+ * 12 PCI on board slot 5 (SBU Riser)
+ *
+ * These are behind the bridge, so I'm not sure what to do...
+ *
+ * 13 PCI on board slot 1 (SBU Riser)
+ * 14 PCI on board slot 2 (SBU Riser)
+ * 15 PCI on board slot 3 (SBU Riser)
+ *
+ *
+ * This two layered interrupt approach means that we allocate IRQ 16 and
+ * above for PCI interrupts. The IRQ relates to which bit the interrupt
+ * comes in on. This makes interrupt processing much easier.
+ */
+static inline void miata_fixup(void)
+{
+ extern int es1888_init(void);
+ extern void SMC669_Init(void); /* might be a MiataGL */
+ char irq_tab[18][5] = {
+ /*INT INTA INTB INTC INTD */
+ {16+ 8, 16+ 8, 16+ 8, 16+ 8, 16+ 8}, /* IdSel 14, DC21142/3 */
+ { -1, -1, -1, -1, -1}, /* IdSel 15, EIDE */
+ { -1, -1, -1, -1, -1}, /* IdSel 16, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 17, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 18, PCI-ISA */
+ { -1, -1, -1, -1, -1}, /* IdSel 19, PCI-PCI old */
+ { -1, -1, -1, -1, -1}, /* IdSel 20, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 21, none */
+ {16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 22, slot 4 */
+ {16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 23, slot 5 */
+ /* the following 7 are actually on PCI bus 1, across the bridge */
+ {16+11, 16+11, 16+11, 16+11, 16+11}, /* IdSel 24, QLISP on GL */
+ { -1, -1, -1, -1, -1}, /* IdSel 25, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 26, none */
+ { -1, -1, -1, -1, -1}, /* IdSel 27, none */
+ {16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 28, slot 1 */
+ {16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 29, slot 2 */
+ {16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 30, slot 3 */
+ /* this bridge is on the main bus of the later original MIATA */
+ { -1, -1, -1, -1, -1}, /* IdSel 31, PCI-PCI new */
+ };
+ common_fixup(3, 20, 5, irq_tab, 0);
+ SMC669_Init(); /* might be a MiataGL, so try to find one of these */
+ es1888_init();
+}
+
+/*
+ * Fixup configuration for SX164 (PCA56+PYXIS)
+ *
+ * Summary @ PYXIS_INT_REQ:
+ * Bit Meaning
+ * 0 RSVD
+ * 1 NMI
+ * 2 Halt/Reset switch
+ * 3 MBZ
+ * 4 RAZ
+ * 5 RAZ
+ * 6 Interval timer (RTC)
+ * 7 PCI-ISA Bridge
+ * 8 Interrupt Line A from slot 3
+ * 9 Interrupt Line A from slot 2
+ *10 Interrupt Line A from slot 1
+ *11 Interrupt Line A from slot 0
+ *12 Interrupt Line B from slot 3
+ *13 Interrupt Line B from slot 2
+ *14 Interrupt Line B from slot 1
+ *15 Interrupt line B from slot 0
+ *16 Interrupt Line C from slot 3
+ *17 Interrupt Line C from slot 2
+ *18 Interrupt Line C from slot 1
+ *19 Interrupt Line C from slot 0
+ *20 Interrupt Line D from slot 3
+ *21 Interrupt Line D from slot 2
+ *22 Interrupt Line D from slot 1
+ *23 Interrupt Line D from slot 0
+ *
+ * IdSel
+ * 5 32 bit PCI option slot 2
+ * 6 64 bit PCI option slot 0
+ * 7 64 bit PCI option slot 1
+ * 8 Cypress I/O
+ * 9 32 bit PCI option slot 3
+ *
+ */
+
+static inline void sx164_fixup(void)
+{
+ extern void SMC669_Init(void);
+ char irq_tab[5][5] = {
+ /*INT INTA INTB INTC INTD */
+ { 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
+ { 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
+ { 16+10, 16+10, 16+14, 16+18, 16+22}, /* IdSel 7 slot 1 J18 */
+ { -1, -1, -1, -1, -1}, /* IdSel 8 SIO */
+ { 16+ 8, 16+ 8, 16+12, 16+16, 16+20} /* IdSel 9 slot 3 J15 */
+ };
+
+ common_fixup(5, 9, 5, irq_tab, 0);
+
+ SMC669_Init();
+}
+
+static inline void ruffian_fixup(void)
+{
+ struct pci_dev *dev;
+
+ /*
+ * Go through all devices
+ */
+ for (dev = pci_devices; dev; dev = dev->next) {
+ if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) {
+ /*
+ * if it's a VGA, enable its BIOS ROM at C0000
+ */
+ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+ /* but if its a Cirrus 543x/544x DISABLE it, */
+ /* since enabling ROM disables the memory... */
+ if ((dev->vendor == PCI_VENDOR_ID_CIRRUS) &&
+ (dev->device >= 0x00a0) &&
+ (dev->device <= 0x00ac)) {
+ pcibios_write_config_dword(
+ dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x00000000);
+ } else {
+ pcibios_write_config_dword(
+ dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x000c0000 | PCI_ROM_ADDRESS_ENABLE);
+ }
+ }
+ /*
+ * if it's a SCSI, disable its BIOS ROM
+ */
+ if ((dev->class >> 8) == PCI_CLASS_STORAGE_SCSI) {
+ pcibios_write_config_dword(dev->bus->number,
+ dev->devfn,
+ PCI_ROM_ADDRESS,
+ 0x0000000);
+ }
+ }
+ }
+}
+
+/*
+ * The Takara has PCI devices 1, 2, and 3 configured to slots 20,
+ * 19, and 18 respectively, in the default configuration. They can
+ * also be jumpered to slots 8, 7, and 6 respectively, which is fun
+ * because the SIO ISA bridge can also be slot 7. However, the SIO
+ * doesn't explicitly generate PCI-type interrupts, so we can
+ * assign it whatever the hell IRQ we like and it doesn't matter.
+ */
+static inline void takara_fixup(void)
+{
+ char irq_tab[15][5] = {
+ { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */
+ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */
+ { -1, -1, -1, -1, -1}, /* slot 9 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 10 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 11 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 12 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 13 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 14 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 15 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 16 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 17 == nothing */
+ { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 18 == device 3 */
+ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 19 == device 2 */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 20 == device 1 */
+ };
+
+ common_fixup(6, 20, 5, irq_tab, 0x26e);
+}
/*
* Fixup configuration for all boards that route the PCI interrupts
@@ -1029,7 +1846,12 @@
* they are co-indicated when the platform type "Noname" is
* selected... :-(
*/
+#ifdef CONFIG_ALPHA_BOOK1
+ /* for the AlphaBook1, NCR810 SCSI is 14, PCMCIA controller is 15 */
+ const unsigned int route_tab = 0x0e0f0a0a;
+#else /* CONFIG_ALPHA_BOOK1 */
const unsigned int route_tab = 0x0b0a0f09;
+#endif /* CONFIG_ALPHA_BOOK1 */
#else /* CONFIG_ALPHA_NONAME */
const unsigned int route_tab = 0x0b0a090f;
#endif /* CONFIG_ALPHA_NONAME */
@@ -1044,7 +1866,11 @@
*/
level_bits = 0;
for (dev = pci_devices; dev; dev = dev->next) {
- if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE)
+ if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE)
+#ifdef CONFIG_ALPHA_BOOK1
+ && (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA)
+#endif /* CONFIG_ALPHA_BOOK1 */
+ )
continue;
dev->irq = 0;
if (dev->bus->number != 0) {
@@ -1076,16 +1902,17 @@
if (slot < 6 || slot >= 6 + sizeof(pirq_tab)/sizeof(pirq_tab[0])) {
printk("bios32.sio_fixup: "
- "weird, found device %04x:%04x in non-existent slot %d!!\n",
+ "weird, found device %04x:%04x "
+ "in non-existent slot %d!!\n",
dev->vendor, dev->device, slot);
continue;
}
pirq = pirq_tab[slot - 6][pin];
DBG_DEVS(("sio_fixup: bus %d slot 0x%x VID 0x%x DID 0x%x\n"
- " int_slot 0x%x int_pin 0x%x, pirq 0x%x\n",
- dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device,
- slot, pin, pirq));
+ " int_slot 0x%x pin 0x%x pirq 0x%x\n",
+ dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor,
+ dev->device, slot, pin, pirq));
/*
* if it's a VGA, enable its BIOS ROM at C0000
*/
@@ -1107,15 +1934,51 @@
dev->irq = (route_tab >> (8 * pirq)) & 0xff;
+#ifndef CONFIG_ALPHA_BOOK1
+ /* do not set *ANY* level triggers for AlphaBook1 */
/* must set the PCI IRQs to level triggered */
level_bits |= (1 << dev->irq);
+#endif /* !CONFIG_ALPHA_BOOK1 */
#if PCI_MODIFY
/* tell the device: */
pcibios_write_config_byte(dev->bus->number, dev->devfn,
PCI_INTERRUPT_LINE, dev->irq);
#endif
+
+#ifdef CONFIG_ALPHA_BOOK1
+ /*
+ * on the AlphaBook1, the PCMCIA chip (Cirrus 6729)
+ * is sensitive to PCI bus bursts, so we must DISABLE
+ * burst mode for the NCR 8xx SCSI... :-(
+ *
+ * Note that the NCR810 SCSI driver must preserve the
+ * setting of the bit in order for this to work. At the
+ * moment (2.0.29), ncr53c8xx.c does NOT do this, but
+ * 53c7,8xx.c DOES...
+ */
+ if ((dev->vendor == PCI_VENDOR_ID_NCR) &&
+ ((dev->device == PCI_DEVICE_ID_NCR_53C810) ||
+ (dev->device == PCI_DEVICE_ID_NCR_53C815) ||
+ (dev->device == PCI_DEVICE_ID_NCR_53C820) ||
+ (dev->device == PCI_DEVICE_ID_NCR_53C825)
+ )) {
+ unsigned int io_port;
+ unsigned char ctest4;
+
+ pcibios_read_config_dword(dev->bus->number, dev->devfn,
+ PCI_BASE_ADDRESS_0, &io_port);
+ io_port &= PCI_BASE_ADDRESS_IO_MASK;
+ ctest4 = inb(io_port+0x21);
+ if (!(ctest4 & 0x80)) {
+ printk("AlphaBook1 NCR init: setting burst disable\n");
+ outb(ctest4 | 0x80, io_port+0x21);
+ }
}
+#endif /* CONFIG_ALPHA_BOOK1 */
+
+ } /* end for devs */
+
/*
* Now, make all PCI interrupts level sensitive. Notice:
* these registers must be accessed byte-wise. inw()/outw()
@@ -1125,21 +1988,43 @@
* so that the only bits getting set are for devices actually found.
* Note that we do preserve the remainder of the bits, which we hope
* will be set correctly by ARC/SRM.
+ *
+ * Note: we at least preserve any level-set bits on AlphaBook1
*/
level_bits |= ((inb(0x4d0) | (inb(0x4d1) << 8)) & 0x71ff);
outb((level_bits >> 0) & 0xff, 0x4d0);
outb((level_bits >> 8) & 0xff, 0x4d1);
+
+#ifdef CONFIG_ALPHA_BOOK1
+ {
+ unsigned char orig, config;
+ /* on the AlphaBook1, make sure that register PR1 indicates 1Mb mem */
+ outb(0x0f, 0x3ce); orig = inb(0x3cf); /* read PR5 */
+ outb(0x0f, 0x3ce); outb(0x05, 0x3cf); /* unlock PR0-4 */
+ outb(0x0b, 0x3ce); config = inb(0x3cf); /* read PR1 */
+ if ((config & 0xc0) != 0xc0) {
+ printk("AlphaBook1 VGA init: setting 1Mb memory\n");
+ config |= 0xc0;
+ outb(0x0b, 0x3ce); outb(config, 0x3cf); /* write PR1 */
+ }
+ outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */
+ }
+#endif /* CONFIG_ALPHA_BOOK1 */
+
+#ifndef CONFIG_ALPHA_BOOK1
+ /* do not do IDE init for AlphaBook1 */
enable_ide(0x26e);
+#endif /* !CONFIG_ALPHA_BOOK1 */
}
#ifdef CONFIG_TGA_CONSOLE
-extern void tga_console_init(void);
+extern void tga_console_find(void);
#endif /* CONFIG_TGA_CONSOLE */
unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
{
-#if PCI_MODIFY
+#if PCI_MODIFY && !defined(CONFIG_ALPHA_RUFFIAN)
/*
* Scan the tree, allocating PCI memory and I/O space.
*/
@@ -1153,7 +2038,7 @@
sio_fixup();
#elif defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB164)
cabriolet_fixup();
-#elif defined(CONFIG_ALPHA_PC164)
+#elif defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164)
alphapc164_fixup();
#elif defined(CONFIG_ALPHA_EB66P)
eb66p_fixup();
@@ -1163,16 +2048,26 @@
eb66_and_eb64p_fixup();
#elif defined(CONFIG_ALPHA_MIKASA)
mikasa_fixup();
-#elif defined(CONFIG_ALPHA_ALCOR)
+#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
alcor_fixup();
-#elif defined(CONFIG_ALPHA_XLT)
- xlt_fixup();
+#elif defined(CONFIG_ALPHA_SABLE)
+ sable_fixup();
+#elif defined(CONFIG_ALPHA_MIATA)
+ miata_fixup();
+#elif defined(CONFIG_ALPHA_NORITAKE)
+ noritake_fixup();
+#elif defined(CONFIG_ALPHA_SX164)
+ sx164_fixup();
+#elif defined(CONFIG_ALPHA_TAKARA)
+ takara_fixup();
+#elif defined(CONFIG_ALPHA_RUFFIAN)
+ ruffian_fixup();
#else
# error You must tell me what kind of platform you want.
#endif
#ifdef CONFIG_TGA_CONSOLE
- tga_console_init();
+ tga_console_find();
#endif /* CONFIG_TGA_CONSOLE */
return mem_start;
@@ -1282,262 +2177,117 @@
}
return err;
}
-#ifdef CONFIG_ALPHA_PC164
-
-/* device "activate" register contents */
-#define DEVICE_ON 1
-#define DEVICE_OFF 0
-
-/* configuration on/off keys */
-#define CONFIG_ON_KEY 0x55
-#define CONFIG_OFF_KEY 0xaa
-
-/* configuration space device definitions */
-#define FDC 0
-#define IDE1 1
-#define IDE2 2
-#define PARP 3
-#define SER1 4
-#define SER2 5
-#define RTCL 6
-#define KYBD 7
-#define AUXIO 8
-
-/* Chip register offsets from base */
-#define CONFIG_CONTROL 0x02
-#define INDEX_ADDRESS 0x03
-#define LOGICAL_DEVICE_NUMBER 0x07
-#define DEVICE_ID 0x20
-#define DEVICE_REV 0x21
-#define POWER_CONTROL 0x22
-#define POWER_MGMT 0x23
-#define OSC 0x24
-
-#define ACTIVATE 0x30
-#define ADDR_HI 0x60
-#define ADDR_LO 0x61
-#define INTERRUPT_SEL 0x70
-#define INTERRUPT_SEL_2 0x72 /* KYBD/MOUS only */
-#define DMA_CHANNEL_SEL 0x74 /* FDC/PARP only */
-
-#define FDD_MODE_REGISTER 0x90
-#define FDD_OPTION_REGISTER 0x91
-
-/* values that we read back that are expected ... */
-#define VALID_DEVICE_ID 2
-
-/* default device addresses */
-#define KYBD_INTERRUPT 1
-#define MOUS_INTERRUPT 12
-#define COM2_BASE 0x2f8
-#define COM2_INTERRUPT 3
-#define COM1_BASE 0x3f8
-#define COM1_INTERRUPT 4
-#define PARP_BASE 0x3bc
-#define PARP_INTERRUPT 7
-
-#define SMC_DEBUG 0
-
-unsigned long SMCConfigState( unsigned long baseAddr )
-{
- unsigned char devId;
- unsigned char devRev;
-
- unsigned long configPort;
- unsigned long indexPort;
- unsigned long dataPort;
-
- configPort = indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )configPort + 1 );
-
- outb(CONFIG_ON_KEY, configPort);
- outb(CONFIG_ON_KEY, configPort);
- outb(DEVICE_ID, indexPort);
- devId = inb(dataPort);
- if ( devId == VALID_DEVICE_ID ) {
- outb(DEVICE_REV, indexPort);
- devRev = inb(dataPort);
- }
- else {
- baseAddr = 0;
- }
- return( baseAddr );
-}
-
-void SMCRunState( unsigned long baseAddr )
-{
- outb(CONFIG_OFF_KEY, baseAddr);
-}
-
-unsigned long SMCDetectUltraIO(void)
-{
- unsigned long baseAddr;
-
- baseAddr = 0x3F0;
- if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x3F0 ) {
- return( baseAddr );
- }
- baseAddr = 0x370;
- if ( ( baseAddr = SMCConfigState( baseAddr ) ) == 0x370 ) {
- return( baseAddr );
- }
- return( ( unsigned long )0 );
-}
-
-void SMCEnableDevice( unsigned long baseAddr,
- unsigned long device,
- unsigned long portaddr,
- unsigned long interrupt)
-{
- unsigned long indexPort;
- unsigned long dataPort;
-
- indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
- outb(LOGICAL_DEVICE_NUMBER, indexPort);
- outb(device, dataPort);
-
- outb(ADDR_LO, indexPort);
- outb(( portaddr & 0xFF ), dataPort);
-
- outb(ADDR_HI, indexPort);
- outb(( ( portaddr >> 8 ) & 0xFF ), dataPort);
-
- outb(INTERRUPT_SEL, indexPort);
- outb(interrupt, dataPort);
-
- outb(ACTIVATE, indexPort);
- outb(DEVICE_ON, dataPort);
-}
+#if (defined(CONFIG_ALPHA_PC164) || \
+ defined(CONFIG_ALPHA_LX164) || \
+ defined(CONFIG_ALPHA_SX164) || \
+ defined(CONFIG_ALPHA_EB164) || \
+ defined(CONFIG_ALPHA_EB66P) || \
+ defined(CONFIG_ALPHA_CABRIOLET)) && defined(CONFIG_ALPHA_SRM)
-void SMCEnableKYBD( unsigned long baseAddr )
+/*
+ on the above machines, under SRM console, we must use the CSERVE PALcode
+ routine to manage the interrupt mask for us, otherwise, the kernel/HW get
+ out of sync with what the PALcode thinks it needs to deliver/ignore
+ */
+void
+cserve_update_hw(unsigned long irq, unsigned long mask)
{
- unsigned long indexPort;
- unsigned long dataPort;
-
- indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
-
- outb(LOGICAL_DEVICE_NUMBER, indexPort);
- outb(KYBD, dataPort);
-
- outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
- outb(KYBD_INTERRUPT, dataPort);
+ extern void cserve_ena(unsigned long);
+ extern void cserve_dis(unsigned long);
- outb(INTERRUPT_SEL_2, indexPort);/* Secondary interrupt select */
- outb(MOUS_INTERRUPT, dataPort);
-
- outb(ACTIVATE, indexPort);
- outb(DEVICE_ON, dataPort);
+ if (mask & (1UL << irq))
+ /* disable */
+ cserve_dis(irq - 16);
+ else
+ /* enable */
+ cserve_ena(irq - 16);
+ return;
+}
+#endif /* (PC164 || LX164 || SX164 || EB164 || CABRIO) && SRM */
+
+#ifdef CONFIG_ALPHA_MIATA
+
+/* init the built-in ES1888 sound chip (SB16 compatible) */
+int es1888_init(void)
+{
+ /* sequence of IO reads to init the audio controller */
+ inb(0x0229);
+ inb(0x0229);
+ inb(0x0229);
+ inb(0x022b);
+ inb(0x0229);
+ inb(0x022b);
+ inb(0x0229);
+ inb(0x0229);
+ inb(0x022b);
+ inb(0x0229);
+ inb(0x0220); /* this sets the base address to 0x220 */
+
+ /* sequence to set DMA channels */
+ outb(0x01, 0x0226); /* reset */
+ inb(0x0226); /* pause */
+ outb(0x00, 0x0226); /* release reset */
+ while (!(inb(0x022e) & 0x80)) /* wait for bit 7 to assert*/
+ continue;
+ inb(0x022a); /* pause */
+ outb(0xc6, 0x022c); /* enable extended mode */
+ while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
+ continue;
+ outb(0xb1, 0x022c); /* setup for write to Interrupt CR */
+ while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
+ continue;
+ outb(0x14, 0x022c); /* set IRQ 5 */
+ while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
+ continue;
+ outb(0xb2, 0x022c); /* setup for write to DMA CR */
+ while (inb(0x022c) & 0x80) /* wait for bit 7 to deassert */
+ continue;
+ outb(0x18, 0x022c); /* set DMA channel 1 */
+
+ return 0;
}
-void SMCEnableFDC( unsigned long baseAddr )
-{
- unsigned long indexPort;
- unsigned long dataPort;
-
- unsigned char oldValue;
-
- indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
+#endif /* CONFIG_ALPHA_MIATA */
- outb(LOGICAL_DEVICE_NUMBER, indexPort);
- outb(FDC, dataPort);
-
- outb(FDD_MODE_REGISTER, indexPort);
- oldValue = inb(dataPort);
-
- oldValue |= 0x0E; /* Enable burst mode */
- outb(oldValue, dataPort);
-
- outb(INTERRUPT_SEL, indexPort); /* Primary interrupt select */
- outb(0x06, dataPort );
-
- outb(DMA_CHANNEL_SEL, indexPort); /* DMA channel select */
- outb(0x02, dataPort);
-
- outb(ACTIVATE, indexPort);
- outb(DEVICE_ON, dataPort);
-}
-
-#if SMC_DEBUG
-void SMCReportDeviceStatus( unsigned long baseAddr )
+#ifdef CONFIG_ALPHA_SRM_SETUP
+void reset_for_srm(void)
{
- unsigned long indexPort;
- unsigned long dataPort;
- unsigned char currentControl;
-
- indexPort = baseAddr;
- dataPort = ( unsigned long )( ( char * )baseAddr + 1 );
-
- outb(POWER_CONTROL, indexPort);
- currentControl = inb(dataPort);
-
- if ( currentControl & ( 1 << FDC ) )
- printk( "\t+FDC Enabled\n" );
- else
- printk( "\t-FDC Disabled\n" );
-
- if ( currentControl & ( 1 << IDE1 ) )
- printk( "\t+IDE1 Enabled\n" );
- else
- printk( "\t-IDE1 Disabled\n" );
-
- if ( currentControl & ( 1 << IDE2 ) )
- printk( "\t+IDE2 Enabled\n" );
- else
- printk( "\t-IDE2 Disabled\n" );
-
- if ( currentControl & ( 1 << PARP ) )
- printk( "\t+PARP Enabled\n" );
- else
- printk( "\t-PARP Disabled\n" );
-
- if ( currentControl & ( 1 << SER1 ) )
- printk( "\t+SER1 Enabled\n" );
- else
- printk( "\t-SER1 Disabled\n" );
-
- if ( currentControl & ( 1 << SER2 ) )
- printk( "\t+SER2 Enabled\n" );
- else
- printk( "\t-SER2 Disabled\n" );
+ extern void scrreset(void);
+ struct pci_dev *dev;
+ int i;
- printk( "\n" );
-}
+ /* reset any IRQs that we changed */
+ for (i = 0; i < irq_reset_count; i++) {
+ dev = irq_dev_to_reset[i];
+
+ pcibios_write_config_byte(dev->bus->number, dev->devfn,
+ PCI_INTERRUPT_LINE, irq_to_reset[i]);
+#if 1
+ printk("reset_for_srm: bus %d slot 0x%x "
+ "SRM IRQ 0x%x changed back from 0x%x\n",
+ dev->bus->number, PCI_SLOT(dev->devfn),
+ irq_to_reset[i], dev->irq);
#endif
+ }
-int SMCInit(void)
-{
- unsigned long SMCUltraBase;
-
- if ( ( SMCUltraBase = SMCDetectUltraIO( ) ) != ( unsigned long )0 ) {
- printk( "SMC FDC37C93X Ultra I/O Controller found @ 0x%lx\n",
- SMCUltraBase );
-#if SMC_DEBUG
- SMCReportDeviceStatus( SMCUltraBase );
-#endif
- SMCEnableDevice( SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT );
- SMCEnableDevice( SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT );
- SMCEnableDevice( SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT );
- /* on PC164, IDE on the SMC is not enabled; CMD646 (PCI) on MB */
- SMCEnableKYBD( SMCUltraBase );
- SMCEnableFDC( SMCUltraBase );
-#if SMC_DEBUG
- SMCReportDeviceStatus( SMCUltraBase );
+ /* reset any IO addresses that we changed */
+ for (i = 0; i < io_reset_count; i++) {
+ dev = io_dev_to_reset[i];
+
+ pcibios_write_config_byte(dev->bus->number, dev->devfn,
+ io_reg_to_reset[i], io_to_reset[i]);
+#if 1
+ printk("reset_for_srm: bus %d slot 0x%x "
+ "SRM IO restored to 0x%x\n",
+ dev->bus->number, PCI_SLOT(dev->devfn),
+ io_to_reset[i]);
#endif
- SMCRunState( SMCUltraBase );
- return( 1 );
- }
- else {
-#if SMC_DEBUG
- printk( "No SMC FDC37C93X Ultra I/O Controller found\n" );
-#endif
- return( 0 );
- }
}
-#endif /* CONFIG_ALPHA_PC164 */
+ /* reset the visible screen to the top of display memory */
+ scrreset();
+}
+#endif /* CONFIG_ALPHA_SRM_SETUP */
#endif /* CONFIG_PCI */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov