summaryrefslogtreecommitdiffstats
path: root/arch/mips/dec/setup.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-17 03:49:37 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-17 03:49:37 +0000
commit317b660279d583d4db3fc112e3ef2e56b20bec87 (patch)
treeedd0330546242932075dae028c437a613e2ad6b8 /arch/mips/dec/setup.c
parent78c388aed2b7184182c08428db1de6c872d815f5 (diff)
First round of commits for support for DECstations and Bagets.
Diffstat (limited to 'arch/mips/dec/setup.c')
-rw-r--r--arch/mips/dec/setup.c484
1 files changed, 484 insertions, 0 deletions
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
new file mode 100644
index 000000000..9999de881
--- /dev/null
+++ b/arch/mips/dec/setup.c
@@ -0,0 +1,484 @@
+/*
+ * Setup the interrupt stuff.
+ *
+ * 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) 1998 Harald Koerfgen
+ */
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/param.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+#include <asm/init.h>
+#include <asm/irq.h>
+#include <asm/reboot.h>
+
+#include <asm/dec/interrupts.h>
+#include <asm/dec/kn01.h>
+#include <asm/dec/kn02.h>
+#include <asm/dec/kn02xa.h>
+#include <asm/dec/kn03.h>
+#include <asm/dec/ioasic_ints.h>
+
+extern asmlinkage void decstation_handle_int(void);
+
+void dec_init_kn01(void);
+void dec_init_kn230(void);
+void dec_init_kn02(void);
+void dec_init_kn02ba(void);
+void dec_init_kn02ca(void);
+void dec_init_kn03(void);
+
+char *dec_rtc_base = (char *) KN01_RTC_BASE; /* Assume DS2100/3100 initially */
+
+decint_t dec_interrupt[NR_INTS];
+
+/*
+ * Information regarding the IRQ Controller
+ *
+ * isr and imr are also hardcoded for different machines in int_handler.S
+ */
+
+volatile unsigned int *isr = 0L; /* address of the interrupt status register */
+volatile unsigned int *imr = 0L; /* address of the interrupt mask register */
+
+extern void dec_machine_restart(char *command);
+extern void dec_machine_halt(void);
+extern void dec_machine_power_off(void);
+
+extern void wbflush_setup(void);
+
+extern struct rtc_ops dec_rtc_ops;
+
+extern void intr_halt(void);
+
+extern int setup_dec_irq(int, struct irqaction *);
+
+void (*board_time_init) (struct irqaction * irq);
+
+__initfunc(static void dec_irq_setup(void))
+{
+ switch (mips_machtype) {
+ case MACH_DS23100:
+ dec_init_kn01();
+ break;
+ case MACH_DS5100: /* DS5100 MIPSMATE */
+ dec_init_kn230();
+ break;
+ case MACH_DS5000_200: /* DS5000 3max */
+ dec_init_kn02();
+ break;
+ case MACH_DS5000_1XX: /* DS5000/100 3min */
+ dec_init_kn02ba();
+ break;
+ case MACH_DS5000_2X0: /* DS5000/240 3max+ */
+ dec_init_kn03();
+ break;
+ case MACH_DS5000_XX: /* Personal DS5000/2x */
+ dec_init_kn02ca();
+ break;
+ case MACH_DS5800: /* DS5800 Isis */
+ panic("Don't know how to set this up!");
+ break;
+ case MACH_DS5400: /* DS5400 MIPSfair */
+ panic("Don't know how to set this up!");
+ break;
+ case MACH_DS5500: /* DS5500 MIPSfair-2 */
+ panic("Don't know how to set this up!");
+ break;
+ }
+ set_except_vector(0, decstation_handle_int);
+}
+
+/*
+ * enable the periodic interrupts
+ */
+__initfunc(static void dec_time_init(struct irqaction *irq))
+{
+ /*
+ * Here we go, enable periodic rtc interrupts.
+ * Frequency is 128 Hz.
+ */
+ CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x9, RTC_REG_A);
+ CMOS_WRITE(CMOS_READ(RTC_REG_B) | RTC_PIE, RTC_REG_B);
+ setup_dec_irq(CLOCK, irq);
+}
+
+__initfunc(void decstation_setup(void))
+{
+ irq_setup = dec_irq_setup;
+ board_time_init = dec_time_init;
+
+ wbflush_setup();
+
+ _machine_restart = dec_machine_restart;
+ _machine_halt = dec_machine_halt;
+ _machine_power_off = dec_machine_power_off;
+
+ rtc_ops = &dec_rtc_ops;
+}
+
+/*
+ * Machine-specific initialisation for kn01, aka Pmax, aka DS2100, DS3100,
+ * and possibly also the DS5100.
+ */
+__initfunc(void dec_init_kn01(void))
+{
+ /*
+ * Setup some memory addresses.
+ */
+ dec_rtc_base = (char *) KN01_RTC_BASE;
+
+ /*
+ * Setup interrupt structure
+ */
+ dec_interrupt[CLOCK].cpu_mask = IE_IRQ3;
+ dec_interrupt[CLOCK].iemask = 0;
+ cpu_mask_tbl[0] = IE_IRQ3;
+ cpu_irq_nr[0] = CLOCK;
+
+ dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0;
+ dec_interrupt[SCSI_INT].iemask = 0;
+ cpu_mask_tbl[1] = IE_IRQ0;
+ cpu_irq_nr[1] = SCSI_INT;
+
+ dec_interrupt[ETHER].cpu_mask = IE_IRQ1;
+ dec_interrupt[ETHER].iemask = 0;
+ cpu_mask_tbl[2] = IE_IRQ1;
+ cpu_irq_nr[2] = ETHER;
+
+ dec_interrupt[SERIAL].cpu_mask = IE_IRQ2;
+ dec_interrupt[SERIAL].iemask = 0;
+ cpu_mask_tbl[3] = IE_IRQ2;
+ cpu_irq_nr[3] = SERIAL;
+
+ dec_interrupt[MEMORY].cpu_mask = IE_IRQ4;
+ dec_interrupt[MEMORY].iemask = 0;
+ cpu_mask_tbl[4] = IE_IRQ4;
+ cpu_irq_nr[4] = MEMORY;
+
+ dec_interrupt[FPU].cpu_mask = IE_IRQ5;
+ dec_interrupt[FPU].iemask = 0;
+ cpu_mask_tbl[5] = IE_IRQ5;
+ cpu_irq_nr[5] = FPU;
+} /* dec_init_kn01 */
+
+/*
+ * Machine-specific initialisation for kn230, aka MIPSmate, aka DS5100
+ *
+ * There are a lot of experiments to do, this is definitely incomplete.
+ */
+__initfunc(void dec_init_kn230(void))
+{
+ /*
+ * Setup some memory addresses.
+ */
+ dec_rtc_base = (char *) KN01_RTC_BASE;
+
+ /*
+ * Setup interrupt structure
+ */
+ dec_interrupt[CLOCK].cpu_mask = IE_IRQ2;
+ dec_interrupt[CLOCK].iemask = 0;
+ cpu_mask_tbl[0] = IE_IRQ2;
+ cpu_irq_nr[0] = CLOCK;
+
+ dec_interrupt[FPU].cpu_mask = IE_IRQ5;
+ dec_interrupt[FPU].iemask = 0;
+ cpu_mask_tbl[5] = IE_IRQ5;
+ cpu_irq_nr[5] = FPU;
+} /* dec_init_kn230 */
+
+/*
+ * Machine-specific initialisation for kn02, aka 3max, aka DS5000/2xx.
+ */
+__initfunc(void dec_init_kn02(void))
+{
+ /*
+ * Setup some memory addresses. FIXME: probably incomplete!
+ */
+ dec_rtc_base = (char *) KN02_RTC_BASE;
+ isr = (volatile unsigned int *) KN02_CSR_ADDR;
+ imr = (volatile unsigned int *) KN02_CSR_ADDR;
+
+ /*
+ * Setup IOASIC interrupt
+ */
+ cpu_ivec_tbl[1] = kn02_io_int;
+ cpu_mask_tbl[1] = IE_IRQ0;
+ cpu_irq_nr[1] = -1;
+ *imr = *imr & 0xff00ff00;
+
+ /*
+ * Setup interrupt structure
+ */
+ dec_interrupt[CLOCK].cpu_mask = IE_IRQ1;
+ dec_interrupt[CLOCK].iemask = 0;
+ cpu_mask_tbl[0] = IE_IRQ1;
+ cpu_irq_nr[0] = CLOCK;
+
+ dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0;
+ dec_interrupt[SCSI_INT].iemask = KN02_SLOT5;
+ asic_mask_tbl[0] = KN02_SLOT5;
+ asic_irq_nr[0] = SCSI_INT;
+
+ dec_interrupt[ETHER].cpu_mask = IE_IRQ0;
+ dec_interrupt[ETHER].iemask = KN02_SLOT6;
+ asic_mask_tbl[1] = KN02_SLOT6;
+ asic_irq_nr[1] = ETHER;
+
+ dec_interrupt[SERIAL].cpu_mask = IE_IRQ0;
+ dec_interrupt[SERIAL].iemask = KN02_SLOT7;
+ asic_mask_tbl[2] = KN02_SLOT7;
+ asic_irq_nr[2] = SERIAL;
+
+ dec_interrupt[TC0].cpu_mask = IE_IRQ0;
+ dec_interrupt[TC0].iemask = KN02_SLOT0;
+ asic_mask_tbl[3] = KN02_SLOT0;
+ asic_irq_nr[3] = TC0;
+
+ dec_interrupt[TC1].cpu_mask = IE_IRQ0;
+ dec_interrupt[TC1].iemask = KN02_SLOT1;
+ asic_mask_tbl[4] = KN02_SLOT1;
+ asic_irq_nr[4] = TC1;
+
+ dec_interrupt[TC2].cpu_mask = IE_IRQ0;
+ dec_interrupt[TC2].iemask = KN02_SLOT2;
+ asic_mask_tbl[5] = KN02_SLOT2;
+ asic_irq_nr[5] = TC2;
+
+ dec_interrupt[MEMORY].cpu_mask = IE_IRQ3;
+ dec_interrupt[MEMORY].iemask = 0;
+ cpu_mask_tbl[1] = IE_IRQ3;
+ cpu_irq_nr[1] = MEMORY;
+
+ dec_interrupt[FPU].cpu_mask = IE_IRQ5;
+ dec_interrupt[FPU].iemask = 0;
+ cpu_mask_tbl[2] = IE_IRQ5;
+ cpu_irq_nr[2] = FPU;
+
+} /* dec_init_kn02 */
+
+/*
+ * Machine-specific initialisation for kn02ba, aka 3min, aka DS5000/1xx.
+ */
+__initfunc(void dec_init_kn02ba(void))
+{
+ /*
+ * Setup some memory addresses.
+ */
+ dec_rtc_base = (char *) KN02XA_RTC_BASE;
+ isr = (volatile unsigned int *) KN02XA_SIR_ADDR;
+ imr = (volatile unsigned int *) KN02XA_SIRM_ADDR;
+
+ /*
+ * Setup IOASIC interrupt
+ */
+ cpu_mask_tbl[0] = IE_IRQ3;
+ cpu_irq_nr[0] = -1;
+ cpu_ivec_tbl[0] = kn02ba_io_int;
+ *imr = 0;
+
+ /*
+ * Setup interrupt structure
+ */
+ dec_interrupt[CLOCK].cpu_mask = IE_IRQ3;
+ dec_interrupt[CLOCK].iemask = KMIN_CLOCK;
+ asic_mask_tbl[0] = KMIN_CLOCK;
+ asic_irq_nr[0] = CLOCK;
+
+ dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ3;
+ dec_interrupt[SCSI_INT].iemask = KMIN_SCSI_INTS;
+ asic_mask_tbl[1] = KMIN_SCSI_INTS;
+ asic_irq_nr[1] = SCSI_INT;
+
+ dec_interrupt[ETHER].cpu_mask = IE_IRQ3;
+ dec_interrupt[ETHER].iemask = LANCE_INTS;
+ asic_mask_tbl[2] = LANCE_INTS;
+ asic_irq_nr[2] = ETHER;
+
+ dec_interrupt[SERIAL].cpu_mask = IE_IRQ3;
+ dec_interrupt[SERIAL].iemask = SERIAL_INTS;
+ asic_mask_tbl[3] = SERIAL_INTS;
+ asic_irq_nr[3] = SERIAL;
+
+ dec_interrupt[MEMORY].cpu_mask = IE_IRQ3;
+ dec_interrupt[MEMORY].iemask = KMIN_TIMEOUT;
+ asic_mask_tbl[4] = KMIN_TIMEOUT;
+ asic_irq_nr[4] = MEMORY;
+
+ dec_interrupt[TC0].cpu_mask = IE_IRQ0;
+ dec_interrupt[TC0].iemask = 0;
+ cpu_mask_tbl[1] = IE_IRQ0;
+ cpu_irq_nr[1] = TC0;
+
+ dec_interrupt[TC1].cpu_mask = IE_IRQ1;
+ dec_interrupt[TC1].iemask = 0;
+ cpu_mask_tbl[2] = IE_IRQ1;
+ cpu_irq_nr[2] = TC1;
+
+ dec_interrupt[TC2].cpu_mask = IE_IRQ2;
+ dec_interrupt[TC2].iemask = 0;
+ cpu_mask_tbl[3] = IE_IRQ2;
+ cpu_irq_nr[3] = TC2;
+
+ dec_interrupt[HALT].cpu_mask = IE_IRQ4;
+ dec_interrupt[HALT].iemask = 0;
+ cpu_mask_tbl[4] = IE_IRQ4;
+ cpu_irq_nr[4] = HALT;
+
+ dec_interrupt[FPU].cpu_mask = IE_IRQ5;
+ dec_interrupt[FPU].iemask = 0;
+ cpu_mask_tbl[5] = IE_IRQ5;
+ cpu_irq_nr[5] = FPU;
+
+} /* dec_init_kn02ba */
+
+/*
+ * Machine-specific initialisation for kn02ca, aka maxine, aka DS5000/2x.
+ */
+__initfunc(void dec_init_kn02ca(void))
+{
+ /*
+ * Setup some memory addresses. FIXME: probably incomplete!
+ */
+ dec_rtc_base = (char *) KN02XA_RTC_BASE;
+ isr = (volatile unsigned int *) KN02XA_SIR_ADDR;
+ imr = (volatile unsigned int *) KN02XA_SIRM_ADDR;
+
+ /*
+ * Setup IOASIC interrupt
+ */
+ cpu_ivec_tbl[1] = kn02ba_io_int;
+ cpu_irq_nr[1] = -1;
+ cpu_mask_tbl[1] = IE_IRQ3;
+ *imr = 0;
+
+ /*
+ * Setup interrupt structure
+ */
+ dec_interrupt[CLOCK].cpu_mask = IE_IRQ1;
+ dec_interrupt[CLOCK].iemask = 0;
+ cpu_mask_tbl[0] = IE_IRQ1;
+ cpu_irq_nr[0] = CLOCK;
+
+ dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ3;
+ dec_interrupt[SCSI_INT].iemask = SCSI_INTS;
+ asic_mask_tbl[0] = SCSI_INTS;
+ asic_irq_nr[0] = SCSI_INT;
+
+ dec_interrupt[ETHER].cpu_mask = IE_IRQ3;
+ dec_interrupt[ETHER].iemask = LANCE_INTS;
+ asic_mask_tbl[1] = LANCE_INTS;
+ asic_irq_nr[1] = ETHER;
+
+ dec_interrupt[SERIAL].cpu_mask = IE_IRQ3;
+ dec_interrupt[SERIAL].iemask = XINE_SERIAL_INTS;
+ asic_mask_tbl[2] = XINE_SERIAL_INTS;
+ asic_irq_nr[2] = SERIAL;
+
+ dec_interrupt[TC0].cpu_mask = IE_IRQ3;
+ dec_interrupt[TC0].iemask = MAXINE_TC0;
+ asic_mask_tbl[3] = MAXINE_TC0;
+ asic_irq_nr[3] = TC0;
+
+ dec_interrupt[TC1].cpu_mask = IE_IRQ3;
+ dec_interrupt[TC1].iemask = MAXINE_TC1;
+ asic_mask_tbl[4] = MAXINE_TC1;
+ asic_irq_nr[4] = TC1;
+
+ dec_interrupt[MEMORY].cpu_mask = IE_IRQ2;
+ dec_interrupt[MEMORY].iemask = 0;
+ cpu_mask_tbl[2] = IE_IRQ2;
+ cpu_irq_nr[2] = MEMORY;
+
+ dec_interrupt[HALT].cpu_mask = IE_IRQ4;
+ dec_interrupt[HALT].iemask = 0;
+ cpu_mask_tbl[3] = IE_IRQ4;
+ cpu_irq_nr[3] = HALT;
+
+ dec_interrupt[FPU].cpu_mask = IE_IRQ5;
+ dec_interrupt[FPU].iemask = 0;
+ cpu_mask_tbl[4] = IE_IRQ5;
+ cpu_irq_nr[4] = FPU;
+
+} /* dec_init_kn02ca */
+
+/*
+ * Machine-specific initialisation for kn03, aka 3max+, aka DS5000/240.
+ */
+__initfunc(void dec_init_kn03(void))
+{
+ /*
+ * Setup some memory addresses. FIXME: probably incomplete!
+ */
+ dec_rtc_base = (char *) KN03_RTC_BASE;
+ isr = (volatile unsigned int *) KN03_SIR_ADDR;
+ imr = (volatile unsigned int *) KN03_SIRM_ADDR;
+
+ /*
+ * Setup IOASIC interrupt
+ */
+ cpu_ivec_tbl[1] = kn03_io_int;
+ cpu_mask_tbl[1] = IE_IRQ0;
+ cpu_irq_nr[1] = -1;
+ *imr = 0;
+
+ /*
+ * Setup interrupt structure
+ */
+ dec_interrupt[CLOCK].cpu_mask = IE_IRQ1;
+ dec_interrupt[CLOCK].iemask = 0;
+ cpu_mask_tbl[0] = IE_IRQ1;
+ cpu_irq_nr[0] = CLOCK;
+
+ dec_interrupt[SCSI_INT].cpu_mask = IE_IRQ0;
+ dec_interrupt[SCSI_INT].iemask = SCSI_INTS;
+ asic_mask_tbl[0] = SCSI_INTS;
+ asic_irq_nr[0] = SCSI_INT;
+
+ dec_interrupt[ETHER].cpu_mask = IE_IRQ0;
+ dec_interrupt[ETHER].iemask = LANCE_INTS;
+ asic_mask_tbl[1] = LANCE_INTS;
+ asic_irq_nr[1] = ETHER;
+
+ dec_interrupt[SERIAL].cpu_mask = IE_IRQ0;
+ dec_interrupt[SERIAL].iemask = SERIAL_INTS;
+ asic_mask_tbl[2] = SERIAL_INTS;
+ asic_irq_nr[2] = SERIAL;
+
+ dec_interrupt[TC0].cpu_mask = IE_IRQ0;
+ dec_interrupt[TC0].iemask = KN03_TC0;
+ asic_mask_tbl[3] = KN03_TC0;
+ asic_irq_nr[3] = TC0;
+
+ dec_interrupt[TC1].cpu_mask = IE_IRQ0;
+ dec_interrupt[TC1].iemask = KN03_TC1;
+ asic_mask_tbl[4] = KN03_TC1;
+ asic_irq_nr[4] = TC1;
+
+ dec_interrupt[TC2].cpu_mask = IE_IRQ0;
+ dec_interrupt[TC2].iemask = KN03_TC2;
+ asic_mask_tbl[5] = KN03_TC2;
+ asic_irq_nr[5] = TC2;
+
+ dec_interrupt[MEMORY].cpu_mask = IE_IRQ3;
+ dec_interrupt[MEMORY].iemask = 0;
+ cpu_mask_tbl[2] = IE_IRQ3;
+ cpu_irq_nr[2] = MEMORY;
+
+ dec_interrupt[HALT].cpu_mask = IE_IRQ4;
+ dec_interrupt[HALT].iemask = 0;
+ cpu_mask_tbl[3] = IE_IRQ4;
+ cpu_irq_nr[3] = HALT;
+
+ dec_interrupt[FPU].cpu_mask = IE_IRQ5;
+ dec_interrupt[FPU].iemask = 0;
+ cpu_mask_tbl[4] = IE_IRQ5;
+ cpu_irq_nr[4] = FPU;
+
+} /* dec_init_kn03 */