summary refs log tree commit diff
path: root/arch/mips
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2005-02-21 16:18:36 +0000
committerRalf Baechle <ralf@linux-mips.org>2005-10-29 19:30:42 +0100
commitc4ed38a0c6e2e5c4906296758f816ee71373792f (patch)
tree65ebab9ca61ea6d03109c53acd2989b626dce52a /arch/mips
parent049b13c358f0187cf3c5003d5fb9848dbcb28bc3 (diff)
downloadlinux-c4ed38a0c6e2e5c4906296758f816ee71373792f.tar.gz
Resurrect Cobalt support for 2.6.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Makefile1
-rw-r--r--arch/mips/cobalt/Makefile2
-rw-r--r--arch/mips/cobalt/int-handler.S4
-rw-r--r--arch/mips/cobalt/irq.c111
-rw-r--r--arch/mips/cobalt/promcon.c87
-rw-r--r--arch/mips/cobalt/reset.c59
-rw-r--r--arch/mips/cobalt/setup.c100
-rw-r--r--arch/mips/pci/fixup-cobalt.c55
-rw-r--r--arch/mips/pci/ops-gt64111.c10
9 files changed, 233 insertions, 196 deletions
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index dbd79bef34a0..5f2dfcddb9f2 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -323,6 +323,7 @@ load-$(CONFIG_MIPS_XXS1500)	+= 0xffffffff80100000
 # Cobalt Server
 #
 core-$(CONFIG_MIPS_COBALT)	+= arch/mips/cobalt/
+cflags-$(CONFIG_MIPS_COBALT)	+= -Iinclude/asm-mips/cobalt
 load-$(CONFIG_MIPS_COBALT)	+= 0xffffffff80080000
 
 #
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index a5e6554b2326..3b6b7579d1de 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -2,6 +2,6 @@
 # Makefile for the Cobalt micro systems family specific parts of the kernel
 #
 
-obj-y	 := irq.o int-handler.o reset.o setup.o promcon.o
+obj-y	 := irq.o int-handler.o reset.o setup.o
 
 EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
index 1a21dec1b3ca..f92608e8d84f 100644
--- a/arch/mips/cobalt/int-handler.S
+++ b/arch/mips/cobalt/int-handler.S
@@ -18,8 +18,8 @@
 		SAVE_ALL
 		CLI
 
-		la	ra, ret_from_irq
-		move	a1, sp
+		PTR_LA	ra, ret_from_irq
+		move	a0, sp
 		j	cobalt_irq
 
 		END(cobalt_handle_int)
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
index 6d2a81581397..0d90851f925e 100644
--- a/arch/mips/cobalt/irq.c
+++ b/arch/mips/cobalt/irq.c
@@ -10,6 +10,8 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
 
 #include <asm/i8259.h>
 #include <asm/irq_cpu.h>
@@ -25,8 +27,8 @@ extern void cobalt_handle_int(void);
  * the CPU interrupt lines, and ones that come in on the via chip. The CPU
  * mappings are:
  *
- *    16,  - Software interrupt 0 (unused)	IE_SW0
- *    17   - Software interrupt 1 (unused)	IE_SW0
+ *    16   - Software interrupt 0 (unused)	IE_SW0
+ *    17   - Software interrupt 1 (unused)	IE_SW1
  *    18   - Galileo chip (timer)		IE_IRQ0
  *    19   - Tulip 0 + NCR SCSI			IE_IRQ1
  *    20   - Tulip 1				IE_IRQ2
@@ -42,61 +44,94 @@ extern void cobalt_handle_int(void);
  *    15  - IDE1
  */
 
-asmlinkage void cobalt_irq(struct pt_regs *regs)
+static inline void galileo_irq(struct pt_regs *regs)
 {
-	unsigned int pending = read_c0_status() & read_c0_cause();
-
-	if (pending & CAUSEF_IP2) {			/* int 18 */
-		unsigned long irq_src = GALILEO_INL(GT_INTRCAUSE_OFS);
-
-		/* Check for timer irq ... */
-		if (irq_src & GALILEO_T0EXP) {
-			/* Clear the int line */
-			GALILEO_OUTL(0, GT_INTRCAUSE_OFS);
-			do_IRQ(COBALT_TIMER_IRQ, regs);
-		}
-		return;
-	}
+	unsigned int mask, pending, devfn;
 
-	if (pending & CAUSEF_IP6) {			/* int 22 */
-		int irq = i8259_irq();
+	mask = GALILEO_INL(GT_INTRMASK_OFS);
+	pending = GALILEO_INL(GT_INTRCAUSE_OFS) & mask;
 
-		if (irq >= 0)
-			do_IRQ(irq, regs);
-		return;
-	}
+	if (pending & GALILEO_INTR_T0EXP) {
 
-	if (pending & CAUSEF_IP3) {			/* int 19 */
-		do_IRQ(COBALT_ETH0_IRQ, regs);
-		return;
-	}
+		GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS);
+		do_IRQ(COBALT_GALILEO_IRQ, regs);
 
-	if (pending & CAUSEF_IP4) {			/* int 20 */
-		do_IRQ(COBALT_ETH1_IRQ, regs);
-		return;
-	}
+	} else if (pending & GALILEO_INTR_RETRY_CTR) {
 
-	if (pending & CAUSEF_IP5) {			/* int 21 */
-		do_IRQ(COBALT_SERIAL_IRQ, regs);
-		return;
-	}
+		devfn = GALILEO_INL(GT_PCI0_CFGADDR_OFS) >> 8;
+		GALILEO_OUTL(~GALILEO_INTR_RETRY_CTR, GT_INTRCAUSE_OFS);
+		printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n",
+			PCI_SLOT(devfn), PCI_FUNC(devfn));
+
+	} else {
 
-	if (pending & CAUSEF_IP7) {			/* int 23 */
-		do_IRQ(COBALT_QUBE_SLOT_IRQ, regs);
-		return;
+		GALILEO_OUTL(mask & ~pending, GT_INTRMASK_OFS);
+		printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending);
 	}
 }
 
+static inline void via_pic_irq(struct pt_regs *regs)
+{
+	int irq;
+
+	irq = i8259_irq();
+	if (irq >= 0)
+		do_IRQ(irq, regs);
+}
+
+asmlinkage void cobalt_irq(struct pt_regs *regs)
+{
+	unsigned pending;
+
+	pending = read_c0_status() & read_c0_cause();
+
+	if (pending & CAUSEF_IP2)			/* COBALT_GALILEO_IRQ (18) */
+
+		galileo_irq(regs);
+
+	else if (pending & CAUSEF_IP6)			/* COBALT_VIA_IRQ (22) */
+
+		via_pic_irq(regs);
+
+	else if (pending & CAUSEF_IP3)			/* COBALT_ETH0_IRQ (19) */
+
+		do_IRQ(COBALT_CPU_IRQ + 3, regs);
+
+	else if (pending & CAUSEF_IP4)			/* COBALT_ETH1_IRQ (20) */
+
+		do_IRQ(COBALT_CPU_IRQ + 4, regs);
+
+	else if (pending & CAUSEF_IP5)			/* COBALT_SERIAL_IRQ (21) */
+
+		do_IRQ(COBALT_CPU_IRQ + 5, regs);
+
+	else if (pending & CAUSEF_IP7)			/* IRQ 23 */
+
+		do_IRQ(COBALT_CPU_IRQ + 7, regs);
+}
+
+static struct irqaction irq_via = {
+	no_action, 0, { { 0, } }, "cascade", NULL, NULL
+};
+
 void __init arch_init_irq(void)
 {
+	/*
+	 * Mask all Galileo interrupts. The Galileo
+	 * handler is set in cobalt_timer_setup()
+	 */
+	GALILEO_OUTL(0, GT_INTRMASK_OFS);
+
 	set_except_vector(0, cobalt_handle_int);
 
 	init_i8259_irqs();				/*  0 ... 15 */
-	mips_cpu_irq_init(16);				/* 16 ... 23 */
+	mips_cpu_irq_init(COBALT_CPU_IRQ);		/* 16 ... 23 */
 
 	/*
 	 * Mask all cpu interrupts
 	 *  (except IE4, we already masked those at VIA level)
 	 */
 	change_c0_status(ST0_IM, IE_IRQ4);
+
+	setup_irq(COBALT_VIA_IRQ, &irq_via);
 }
diff --git a/arch/mips/cobalt/promcon.c b/arch/mips/cobalt/promcon.c
deleted file mode 100644
index f03df761e9f1..000000000000
--- a/arch/mips/cobalt/promcon.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * PROM console for Cobalt Raq2
- *
- * 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) 1995, 1996, 1997 by Ralf Baechle
- * Copyright (C) 2001 by Liam Davies (ldavies@agile.tv)
- *
- */
-
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kdev_t.h>
-#include <linux/serial_reg.h>
-
-#include <asm/delay.h>
-#include <asm/serial.h>
-#include <asm/io.h>
-
-static unsigned long port = 0xc800000;
-
-static __inline__ void ns16550_cons_put_char(char ch, unsigned long ioaddr)
-{
-	char lsr;
-
-	do {
-		lsr = inb(ioaddr + UART_LSR);
-	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
-	outb(ch, ioaddr + UART_TX);
-}
-
-static __inline__ char ns16550_cons_get_char(unsigned long ioaddr)
-{
-	while ((inb(ioaddr + UART_LSR) & UART_LSR_DR) == 0)
-		udelay(1);
-	return inb(ioaddr + UART_RX);
-}
-
-void ns16550_console_write(struct console *co, const char *s, unsigned count)
-{
-	char lsr, ier;
-	unsigned i;
-
-	ier = inb(port + UART_IER);
-	outb(0x00, port + UART_IER);
-	for (i=0; i < count; i++, s++) {
-
-		if(*s == '\n')
-			ns16550_cons_put_char('\r', port);
-		ns16550_cons_put_char(*s, port);
-	}
-
-	do {
-		lsr = inb(port + UART_LSR);
-   	} while ((lsr & (UART_LSR_TEMT | UART_LSR_THRE)) != (UART_LSR_TEMT | UART_LSR_THRE));
-
-	outb(ier, port + UART_IER);
-}
-
-char getDebugChar(void)
-{
-	return ns16550_cons_get_char(port);
-}
-
-void putDebugChar(char kgdb_char)
-{
-	ns16550_cons_put_char(kgdb_char, port);
-}
-
-static struct console ns16550_console = {
-    .name	= "prom",
-    .setup	= NULL,
-    .write	= ns16550_console_write,
-    .flags	= CON_PRINTBUFFER,
-    .index	= -1,
-};
-
-static int __init ns16550_setup_console(void)
-{
-	register_console(&ns16550_console);
-
-	return 0;
-}
-
-console_initcall(ns16550_setup_console);
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c
index 084c8e59f42c..805a0e88507b 100644
--- a/arch/mips/cobalt/reset.c
+++ b/arch/mips/cobalt/reset.c
@@ -16,48 +16,45 @@
 #include <asm/reboot.h>
 #include <asm/system.h>
 #include <asm/mipsregs.h>
+#include <asm/cobalt/cobalt.h>
 
-void cobalt_machine_restart(char *command)
+void cobalt_machine_halt(void)
 {
-	*(volatile char *)0xbc000000 = 0x0f;
+	int state, last, diff;
+	unsigned long mark;
 
 	/*
-	 * Ouch, we're still alive ... This time we take the silver bullet ...
-	 * ... and find that we leave the hardware in a state in which the
-	 * kernel in the flush locks up somewhen during of after the PCI
-	 * detection stuff.
+	 * turn off bar on Qube, flash power off LED on RaQ (0.5Hz)
+	 *
+	 * restart if ENTER and SELECT are pressed
 	 */
-	set_c0_status(ST0_BEV | ST0_ERL);
-	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
-	flush_cache_all();
-	write_c0_wired(0);
-	__asm__ __volatile__(
-		"jr\t%0"
-		:
-		: "r" (0xbfc00000));
-}
 
-extern int led_state;
-#define kLED            0xBC000000
-#define LEDSet(x)       (*(volatile unsigned char *) kLED) = (( unsigned char)x)
+	last = COBALT_KEY_PORT;
 
-void cobalt_machine_halt(void)
-{
-	int mark;
+	for (state = 0;;) {
+
+		state ^= COBALT_LED_POWER_OFF;
+		COBALT_LED_PORT = state;
+
+		diff = COBALT_KEY_PORT ^ last;
+		last ^= diff;
 
-	/* Blink our cute? little LED (number 3)... */
-	while (1) {
-		led_state = led_state | ( 1 << 3 );
-		LEDSet(led_state);
-		mark = jiffies;
-		while (jiffies<(mark+HZ));
-		led_state = led_state & ~( 1 << 3 );
-		LEDSet(led_state);
-		mark = jiffies;
-		while (jiffies<(mark+HZ));
+		if((diff & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)) && !(~last & (COBALT_KEY_ENTER | COBALT_KEY_SELECT)))
+			COBALT_LED_PORT = COBALT_LED_RESET;
+
+		for (mark = jiffies; jiffies - mark < HZ;)
+			;
 	}
 }
 
+void cobalt_machine_restart(char *command)
+{
+	COBALT_LED_PORT = COBALT_LED_RESET;
+
+	/* we should never get here */
+	cobalt_machine_halt();
+}
+
 /*
  * This triggers the luser mode device driver for the power switch ;-)
  */
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index f8138c15a535..d358a118fa31 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -13,6 +13,8 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
 
 #include <asm/bootinfo.h>
 #include <asm/time.h>
@@ -21,6 +23,7 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/gt64120.h>
+#include <asm/serial.h>
 
 #include <asm/cobalt/cobalt.h>
 
@@ -30,45 +33,44 @@ extern void cobalt_machine_power_off(void);
 
 int cobalt_board_id;
 
-static char my_cmdline[CL_SIZE] = {
- "console=ttyS0,115200 "
-#ifdef CONFIG_IP_PNP
- "ip=on "
-#endif
-#ifdef CONFIG_ROOT_NFS
- "root=/dev/nfs "
-#else
- "root=/dev/hda1 "
-#endif
- };
-
 const char *get_system_type(void)
 {
+	switch (cobalt_board_id) {
+		case COBALT_BRD_ID_QUBE1:
+			return "Cobalt Qube";
+		case COBALT_BRD_ID_RAQ1:
+			return "Cobalt RaQ";
+		case COBALT_BRD_ID_QUBE2:
+			return "Cobalt Qube2";
+		case COBALT_BRD_ID_RAQ2:
+			return "Cobalt RaQ2";
+	}
 	return "MIPS Cobalt";
 }
 
 static void __init cobalt_timer_setup(struct irqaction *irq)
 {
-	/* Load timer value for 150 Hz */
-	GALILEO_OUTL(500000, GT_TC0_OFS);
+	/* Load timer value for 1KHz (TCLK is 50MHz) */
+	GALILEO_OUTL(50*1000*1000 / 1000, GT_TC0_OFS);
 
-	/* Register our timer interrupt */
-	setup_irq(COBALT_TIMER_IRQ, irq);
+	/* Enable timer */
+	GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS);
 
-	/* Enable timer ints */
-	GALILEO_OUTL((GALILEO_ENTC0 | GALILEO_SELTC0), GT_TC_CONTROL_OFS);
-	/* Unmask timer int */
-	GALILEO_OUTL(0x100, GT_INTRMASK_OFS);
+	/* Register interrupt */
+	setup_irq(COBALT_GALILEO_IRQ, irq);
+
+	/* Enable interrupt */
+	GALILEO_OUTL(GALILEO_INTR_T0EXP | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS);
 }
 
 extern struct pci_ops gt64111_pci_ops;
 
 static struct resource cobalt_mem_resource = {
-	"GT64111 PCI MEM", GT64111_IO_BASE, 0xffffffffUL, IORESOURCE_MEM
+	"PCI memory", GT64111_MEM_BASE, GT64111_MEM_END, IORESOURCE_MEM
 };
 
 static struct resource cobalt_io_resource = {
-	"GT64111 IO MEM", 0x00001000UL, 0x0fffffffUL, IORESOURCE_IO
+	"PCI I/O", 0x1000, 0xffff, IORESOURCE_IO
 };
 
 static struct resource cobalt_io_resources[] = {
@@ -86,11 +88,12 @@ static struct pci_controller cobalt_pci_controller = {
 	.mem_resource	= &cobalt_mem_resource,
 	.mem_offset	= 0,
 	.io_resource	= &cobalt_io_resource,
-	.io_offset	= 0x00001000UL - GT64111_IO_BASE
+	.io_offset	= 0 - GT64111_IO_BASE
 };
 
 void __init plat_setup(void)
 {
+	static struct uart_port uart;
 	unsigned int devfn = PCI_DEVFN(COBALT_PCICONF_VIA, 0);
 	int i;
 
@@ -100,7 +103,10 @@ void __init plat_setup(void)
 
 	board_timer_setup = cobalt_timer_setup;
 
-        set_io_port_base(KSEG1ADDR(GT64111_IO_BASE));
+        set_io_port_base(CKSEG1ADDR(GT64111_IO_BASE));
+
+	/* I/O port resource must include UART and LCD/buttons */
+	ioport_resource.end = 0x0fffffff;
 
 	/*
 	 * This is a prom style console. We just poke at the
@@ -120,25 +126,61 @@ void __init plat_setup(void)
         cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8);
         cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id);
 
+	printk("Cobalt board ID: %d\n", cobalt_board_id);
+
 #ifdef CONFIG_PCI
 	register_pci_controller(&cobalt_pci_controller);
 #endif
+
+#ifdef CONFIG_SERIAL_8250
+	if (cobalt_board_id > COBALT_BRD_ID_RAQ1) {
+
+		uart.line	= 0;
+		uart.type	= PORT_UNKNOWN;
+		uart.uartclk	= 18432000;
+		uart.irq	= COBALT_SERIAL_IRQ;
+		uart.flags	= STD_COM_FLAGS;
+		uart.iobase	= 0xc800000;
+		uart.iotype	= UPIO_PORT;
+
+		early_serial_setup(&uart);
+	}
+#endif
 }
 
 /*
  * Prom init. We read our one and only communication with the firmware.
- * Grab the amount of installed memory
+ * Grab the amount of installed memory.
+ * Better boot loaders (CoLo) pass a command line too :-)
  */
 
 void __init prom_init(void)
 {
-	int argc = fw_arg0;
-
-	strcpy(arcs_cmdline, my_cmdline);
+	int narg, indx, posn, nchr;
+	unsigned long memsz;
+	char **argv;
 
 	mips_machgroup = MACH_GROUP_COBALT;
 
-	add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
+	memsz = fw_arg0 & 0x7fff0000;
+	narg = fw_arg0 & 0x0000ffff;
+
+	if (narg) {
+		arcs_cmdline[0] = '\0';
+		argv = (char **) fw_arg1;
+		posn = 0;
+		for (indx = 1; indx < narg; ++indx) {
+			nchr = strlen(argv[indx]);
+			if (posn + 1 + nchr + 1 > sizeof(arcs_cmdline))
+				break;
+			if (posn)
+				arcs_cmdline[posn++] = ' ';
+			strcpy(arcs_cmdline + posn, argv[indx]);
+			posn += nchr;
+		}
+	}
+
+	add_memory_region(0x0, memsz, BOOT_MEM_RAM);
 }
 
 unsigned long __init prom_free_prom_memory(void)
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index 57e1ca2116bb..909292f50d06 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -21,6 +21,20 @@
 
 extern int cobalt_board_id;
 
+static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
+{
+	if (dev->devfn == PCI_DEVFN(0, 0) &&
+		(dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) {
+
+		dev->class = (PCI_CLASS_BRIDGE_HOST << 8) | (dev->class & 0xff);
+
+		printk(KERN_INFO "Galileo: fixed bridge class\n");
+	}
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
+	 qube_raq_galileo_early_fixup);
+
 static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
 {
 	unsigned short cfgword;
@@ -48,6 +62,9 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
 {
 	unsigned short galileo_id;
 
+	if (dev->devfn != PCI_DEVFN(0, 0))
+		return;
+
 	/* Fix PCI latency-timer and cache-line-size values in Galileo
 	 * host bridge.
 	 */
@@ -55,6 +72,13 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
 	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
 
 	/*
+	 * The code described by the comment below has been removed
+	 * as it causes bus mastering by the Ethernet controllers
+	 * to break under any kind of network load. We always set
+	 * the retry timeouts to their maximum.
+	 *
+	 * --x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--
+	 *
 	 * On all machines prior to Q2, we had the STOP line disconnected
 	 * from Galileo to VIA on PCI.  The new Galileo does not function
 	 * correctly unless we have it connected.
@@ -64,21 +88,43 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev)
 	 */
 	pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
 	galileo_id &= 0xff;	/* mask off class info */
+
+ 	printk(KERN_INFO "Galileo: revision %u\n", galileo_id);
+
+#if 0
 	if (galileo_id >= 0x10) {
 		/* New Galileo, assumes PCI stop line to VIA is connected. */
 		GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS);
-	} else if (galileo_id == 0x1 || galileo_id == 0x2) {
+	} else if (galileo_id == 0x1 || galileo_id == 0x2)
+#endif
+	{
 		signed int timeo;
 		/* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
 		timeo = GALILEO_INL(GT_PCI0_TOR_OFS);
 		/* Old Galileo, assumes PCI STOP line to VIA is disconnected. */
-		GALILEO_OUTL(0xffff, GT_PCI0_TOR_OFS);
+		GALILEO_OUTL(
+			(0xff << 16) |		/* retry count */
+			(0xff << 8) |		/* timeout 1   */
+			0xff,			/* timeout 0   */
+			GT_PCI0_TOR_OFS);
+
+		/* enable PCI retry exceeded interrupt */
+		GALILEO_OUTL(GALILEO_INTR_RETRY_CTR | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS);
 	}
 }
 
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GALILEO, PCI_ANY_ID,
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
 	 qube_raq_galileo_fixup);
 
+static char irq_tab_qube1[] __initdata = {
+  [COBALT_PCICONF_CPU]     = 0,
+  [COBALT_PCICONF_ETH0]    = COBALT_QUBE1_ETH0_IRQ,
+  [COBALT_PCICONF_RAQSCSI] = COBALT_SCSI_IRQ,
+  [COBALT_PCICONF_VIA]     = 0,
+  [COBALT_PCICONF_PCISLOT] = COBALT_QUBE_SLOT_IRQ,
+  [COBALT_PCICONF_ETH1]    = 0
+};
+
 static char irq_tab_cobalt[] __initdata = {
   [COBALT_PCICONF_CPU]     = 0,
   [COBALT_PCICONF_ETH0]    = COBALT_ETH0_IRQ,
@@ -99,6 +145,9 @@ static char irq_tab_raq2[] __initdata = {
 
 int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
+	if (cobalt_board_id < COBALT_BRD_ID_QUBE2)
+		return irq_tab_qube1[slot];
+
 	if (cobalt_board_id == COBALT_BRD_ID_RAQ2)
 		return irq_tab_raq2[slot];
 
diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c
index c5b0fc184c2a..c1807934768d 100644
--- a/arch/mips/pci/ops-gt64111.c
+++ b/arch/mips/pci/ops-gt64111.c
@@ -18,15 +18,15 @@
 #include <asm/cobalt/cobalt.h>
 
 /*
- * Accessing device 31 hangs the GT64120.  Not sure if this will also hang
- * the GT64111, let's be paranoid for now.
+ * Device 31 on the GT64111 is used to generate PCI special
+ * cycles, so we shouldn't expected to find a device there ...
  */
 static inline int pci_range_ck(struct pci_bus *bus, unsigned int devfn)
 {
-	if (bus->number == 0 && devfn == PCI_DEVFN(31, 0))
-		return -1;
+	if (bus->number == 0 && PCI_SLOT(devfn) < 31)
+		return 0;
 
-	return 0;
+	return -1;
 }
 
 static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn,