patch-2.3.8 linux/arch/alpha/kernel/sys_dp264.c

Next file: linux/arch/alpha/kernel/sys_takara.c
Previous file: linux/arch/alpha/kernel/smp.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.7/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
@@ -2,8 +2,8 @@
  *	linux/arch/alpha/kernel/sys_dp264.c
  *
  *	Copyright (C) 1995 David A Rusling
- *	Copyright (C) 1996 Jay A Estabrook
- *	Copyright (C) 1998 Richard Henderson
+ *	Copyright (C) 1996, 1999 Jay A Estabrook
+ *	Copyright (C) 1998, 1999 Richard Henderson
  *
  * Code supporting the DP264 (EV6+TSUNAMI).
  */
@@ -35,7 +35,7 @@
 #define dev2hose(d) (bus2hose[(d)->bus->number]->pci_hose_index)
 
 /*
- * HACK ALERT! only CPU#0 is used currently
+ * HACK ALERT! only the boot cpu is used for interrupts.
  */
 
 static void
@@ -66,34 +66,60 @@
 }
 
 static void
+clipper_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+	if (irq >= 16) {
+		volatile unsigned long *csr;
+
+		if (TSUNAMI_bootcpu < 2)
+			if (!TSUNAMI_bootcpu)
+				csr = &TSUNAMI_cchip->dim0.csr;
+			else
+				csr = &TSUNAMI_cchip->dim1.csr;
+		else
+			if (TSUNAMI_bootcpu == 2)
+				csr = &TSUNAMI_cchip->dim2.csr;
+			else
+				csr = &TSUNAMI_cchip->dim3.csr;
+		
+		*csr = (~mask >> 16) | (1UL << 55); /* master ISA enable */
+		mb();
+		*csr;
+	}
+	else if (irq >= 8)
+		outb(mask >> 8, 0xA1);	/* ISA PIC2 */
+	else
+		outb(mask, 0x21);	/* ISA PIC1 */
+}
+
+static void
 dp264_device_interrupt(unsigned long vector, struct pt_regs * regs)
 {
 #if 1
 	printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n");
 #else
-        unsigned long pld;
-        unsigned int i;
+	unsigned long pld;
+	unsigned int i;
 
-        /* Read the interrupt summary register of TSUNAMI */
-        pld = TSUNAMI_cchip->dir0.csr;
+	/* Read the interrupt summary register of TSUNAMI */
+	pld = TSUNAMI_cchip->dir0.csr;
 
-        /*
-         * Now for every possible bit set, work through them and call
-         * the appropriate interrupt handler.
-         */
-        while (pld) {
-                i = ffz(~pld);
-                pld &= pld - 1; /* clear least bit set */
-                if (i == 55) {
-                        isa_device_interrupt(vector, regs);
-		} else { /* if not timer int */
-                        handle_irq(16 + i, 16 + i, regs);
-                }
+	/*
+	 * Now for every possible bit set, work through them and call
+	 * the appropriate interrupt handler.
+	 */
+	while (pld) {
+		i = ffz(~pld);
+		pld &= pld - 1; /* clear least bit set */
+		if (i == 55)
+			isa_device_interrupt(vector, regs);
+		else
+			handle_irq(16 + i, 16 + i, regs);
 #if 0
 		TSUNAMI_cchip->dir0.csr = 1UL << i; mb();
 		tmp = TSUNAMI_cchip->dir0.csr;
 #endif
-        }
+	}
 #endif
 }
 
@@ -104,24 +130,48 @@
 
 	ack = irq = (vector - 0x800) >> 4;
 
-        /*
-         * The DP264 SRM console reports PCI interrupts with a vector
-	 * 0x100 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
-	 * shows up as IRQ 16, etc, etc. We adjust it down by 16 to have
-	 * it line up with the actual bit numbers from the DIM registers,
-	 * which is how we manage the interrupts/mask. Sigh...
-         */
-        if (irq >= 32)
-                ack = irq = irq - 16;
+	/*
+	 * The SRM console reports PCI interrupts with a vector calculated by:
+	 *
+	 *	0x900 + (0x10 * DRIR-bit)
+	 *
+	 * So bit 16 shows up as IRQ 32, etc.
+	 * 
+	 * On DP264/BRICK/MONET, we adjust it down by 16 because at least
+	 * that many of the low order bits of the DRIR are not used, and
+	 * so we don't count them.
+	 */
+	if (irq >= 32)
+		ack = irq = irq - 16;
+
+	handle_irq(irq, ack, regs);
+}
+
+static void 
+clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+	int irq, ack;
+
+	ack = irq = (vector - 0x800) >> 4;
 
+	/*
+	 * The SRM console reports PCI interrupts with a vector calculated by:
+	 *
+	 *	0x900 + (0x10 * DRIR-bit)
+	 *
+	 * So bit 16 shows up as IRQ 32, etc.
+	 * 
+	 * CLIPPER uses bits 8-47 for PCI interrupts, so we do not need
+	 * to scale down the vector reported, we just use it.
+	 *
+	 * Eg IRQ 24 is DRIR bit 8, etc, etc
+	 */
 	handle_irq(irq, ack, regs);
 }
 
 static void __init
 dp264_init_irq(void)
 {
-	volatile unsigned long *csr;
-
 	outb(0, DMA1_RESET_REG);
 	outb(0, DMA2_RESET_REG);
 	outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
@@ -130,23 +180,26 @@
 	if (alpha_using_srm)
 		alpha_mv.device_interrupt = dp264_srm_device_interrupt;
 
-	if (TSUNAMI_bootcpu < 2)
-		if (!TSUNAMI_bootcpu)
-			csr = &TSUNAMI_cchip->dim0.csr;
-		else
-			csr = &TSUNAMI_cchip->dim1.csr;
-	else
-		if (TSUNAMI_bootcpu == 2)
-			csr = &TSUNAMI_cchip->dim2.csr;
-		else
-			csr = &TSUNAMI_cchip->dim3.csr;
-		
-	/* Note invert on MASK bits.  */
-        *csr = ~(alpha_irq_mask);
-	mb();
-        *csr;
+	dp264_update_irq_hw(16, alpha_irq_mask, 0);
 
-        enable_irq(55);     /* Enable CYPRESS interrupt controller (ISA).  */
+        enable_irq(55);     /* Enable ISA interrupt controller.  */
+	enable_irq(2);
+}
+
+static void __init
+clipper_init_irq(void)
+{
+	outb(0, DMA1_RESET_REG);
+	outb(0, DMA2_RESET_REG);
+	outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+	outb(0, DMA2_MASK_REG);
+
+	if (alpha_using_srm)
+		alpha_mv.device_interrupt = clipper_srm_device_interrupt;
+
+	clipper_update_irq_hw(16, alpha_irq_mask, 0);
+
+        enable_irq(55);     /* Enable ISA interrupt controller.  */
 	enable_irq(2);
 }
 
@@ -221,7 +274,7 @@
 	const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;
 	int irq = COMMON_TABLE_LOOKUP;
 
-	if (irq >= 0)
+	if (irq > 0)
 		irq += 16 * dev2hose(dev);
 
 	return irq;
@@ -250,42 +303,38 @@
 		{    32,    32,    33,    34,    35}, /* IdSel 13 slot 3 PCI0*/
 		{    28,    28,    29,    30,    31}, /* IdSel 14 slot 4 PCI2*/
 		{    24,    24,    25,    26,    27}  /* IdSel 15 slot 5 PCI2*/
-};
+	};
 	const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;
-	int irq = COMMON_TABLE_LOOKUP;
-
-	return irq;
+	return COMMON_TABLE_LOOKUP;
 }
 
 static int __init
 monet_swizzle(struct pci_dev *dev, int *pinp)
 {
-        int slot, pin = *pinp;
+	int slot, pin = *pinp;
 
-        /* Check first for the built-in bridge on hose 1. */
-        if (dev2hose(dev) == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
-	  slot = PCI_SLOT(dev->devfn);
-        }
-        else
-        {
-                /* Must be a card-based bridge.  */
-                do {
+	/* Check first for the built-in bridge on hose 1. */
+	if (dev2hose(dev) == 1 && PCI_SLOT(dev->bus->self->devfn) == 8) {
+		slot = PCI_SLOT(dev->devfn);
+	} else {
+		/* Must be a card-based bridge.  */
+		do {
 			/* Check for built-in bridge on hose 1. */
-                        if (dev2hose(dev) == 1 &&
+			if (dev2hose(dev) == 1 &&
 			    PCI_SLOT(dev->bus->self->devfn) == 8) {
 				slot = PCI_SLOT(dev->devfn);
 				break;
-                        }
-                        pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ;
+			}
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)) ;
 
-                        /* Move up the chain of bridges.  */
-                        dev = dev->bus->self;
-                        /* Slot of the next bridge.  */
-                        slot = PCI_SLOT(dev->devfn);
-                } while (dev->bus->self);
-        }
-        *pinp = pin;
-        return slot;
+			/* Move up the chain of bridges.  */
+			dev = dev->bus->self;
+			/* Slot of the next bridge.  */
+			slot = PCI_SLOT(dev->devfn);
+		} while (dev->bus->self);
+	}
+	*pinp = pin;
+	return slot;
 }
 
 static int __init
@@ -300,14 +349,34 @@
 		{    30,    30,    30,    30,    30}, /* IdSel 11 21143 #2 */
 		{    -1,    -1,    -1,    -1,    -1}, /* IdSel 12 unused */
 		{    -1,    -1,    -1,    -1,    -1}, /* IdSel 13 unused */
-		{    47,    47,    46,    45,    44}, /* IdSel 14 slot 0 */
+		{    35,    35,    34,    33,    32}, /* IdSel 14 slot 0 */
 		{    39,    39,    38,    37,    36}, /* IdSel 15 slot 1 */
 		{    43,    43,    42,    41,    40}, /* IdSel 16 slot 2 */
-		{    35,    35,    34,    33,    32}, /* IdSel 17 slot 3 */
-};
+		{    47,    47,    46,    45,    44}, /* IdSel 17 slot 3 */
+	};
 	const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;
+	return COMMON_TABLE_LOOKUP;
+}
+
+static int __init
+clipper_map_irq(struct pci_dev *dev, int slot, int pin)
+{
+	static char irq_tab[7][5] __initlocaldata = {
+		/*INT    INTA   INTB   INTC   INTD */
+		{ 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 1 slot 1 */
+		{ 16+12, 16+12, 16+13, 16+14, 16+15}, /* IdSel 2 slot 2 */
+		{ 16+16, 16+16, 16+17, 16+18, 16+19}, /* IdSel 3 slot 3 */
+		{ 16+20, 16+20, 16+21, 16+22, 16+23}, /* IdSel 4 slot 4 */
+		{ 16+24, 16+24, 16+25, 16+26, 16+27}, /* IdSel 5 slot 5 */
+		{ 16+28, 16+28, 16+29, 16+30, 16+31}, /* IdSel 6 slot 6 */
+		{    -1,    -1,    -1,    -1,    -1}  /* IdSel 7 ISA Bridge */
+	};
+	const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;
 	int irq = COMMON_TABLE_LOOKUP;
 
+	if (irq > 0)
+		irq += 16 * dev2hose(dev);
+
 	return irq;
 }
 
@@ -336,6 +405,13 @@
 	SMC669_Init(0);
 }
 
+static void __init
+clipper_pci_fixup(void)
+{
+	layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE);
+	common_pci_fixup(clipper_map_irq, common_swizzle);
+}
+
 
 /*
  * The System Vectors
@@ -407,5 +483,28 @@
 	pci_fixup:		webbrick_pci_fixup,
 	kill_arch:		generic_kill_arch,
 };
-/* No alpha_mv alias for webbrick, since we compile it in unconditionally
-   with DP264; setup_arch knows how to cope.  */
+
+struct alpha_machine_vector clipper_mv __initmv = {
+	vector_name:		"Clipper",
+	DO_EV6_MMU,
+	DO_DEFAULT_RTC,
+	DO_TSUNAMI_IO,
+	DO_TSUNAMI_BUS,
+	machine_check:		tsunami_machine_check,
+	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
+
+	nr_irqs:		64,
+	irq_probe_mask:		_PROBE_MASK(64),
+	update_irq_hw:		clipper_update_irq_hw,
+	ack_irq:		generic_ack_irq,
+	device_interrupt:	dp264_device_interrupt,
+
+	init_arch:		tsunami_init_arch,
+	init_irq:		clipper_init_irq,
+	init_pit:		generic_init_pit,
+	pci_fixup:		clipper_pci_fixup,
+	kill_arch:		generic_kill_arch,
+};
+
+/* No alpha_mv alias for webbrick/monet/clipper, since we compile them
+   in unconditionally with DP264; setup_arch knows how to cope.  */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)