patch-2.1.106 linux/arch/m68k/mac/via6522.c

Next file: linux/arch/m68k/mm/Makefile
Previous file: linux/arch/m68k/mac/psc.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.105/linux/arch/m68k/mac/via6522.c linux/arch/m68k/mac/via6522.c
@@ -1,4 +1,3 @@
-
 /*
  *	6522 Versatile Interface Adapter (VIA)
  *
@@ -6,6 +5,7 @@
  *	via them as are assorted bits and bobs - eg rtc, adb.
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -13,75 +13,27 @@
 #include <asm/macintosh.h> 
 #include <asm/macints.h> 
 #include "via6522.h"
+#include "psc.h"
 
 volatile unsigned char *via1=(unsigned char *)VIABASE;
 volatile unsigned char *via2=(unsigned char *)VIABASE2;
+volatile unsigned char *psc=(unsigned char *)PSCBASE;
 
 unsigned char via1_clock, via1_datab;
 
 static int rbv=0;
+static int oss=0;
+
+extern void adb_interrupt(int slot, void *via, struct pt_regs *regs);
 
 /*
- * Debugging the VBL ints
+ * hardware reset vector
  */
-
-extern int console_loglevel;
+static void (*rom_reset)(void);
 
 /*
- *	VIA1 - hardwired vectors
+ * Timer defs.
  */
-
-#if 0 /* gone to macints.[ch] */
-extern void via_wtf(int slot, void *via, struct pt_regs *regs);
-static void via_do_nubus(int slot, volatile void *via, struct pt_regs *regs);
-
-extern void adb_interrupt(int slot, void *via, struct pt_regs *regs);
-
-static struct via_irq_tab via1_func_tab=
-{
-	{
-		via_wtf,	/* One second interrupt */
-		via_wtf,	/* Vblank */
-		via_wtf,       	/* ADB data ready */
-		via_wtf,	/* ADB data */
-		via_wtf,	/* ADB clock */
-		via_wtf,
-		via_wtf,	/* Slot 6 is replaced by the timer */
-		via_wtf
-	}
-};
-
-static struct via_irq_tab via2_func_tab=
-{
-	{
-		via_wtf,
-		via_do_nubus,
-		via_wtf,
-		via_wtf,
-		via_wtf,
-		via_wtf,
-		via_wtf,
-		via_wtf
-	}
-};
-
-static struct via_irq_tab nubus_func_tab=
-{
-	{
-		via_wtf,
-		via_wtf,
-		via_wtf,
-		via_wtf,
-		via_wtf,
-		via_wtf,
-		via_wtf,
-		via_wtf
-	}
-};
-#endif
-
-extern void adb_interrupt(int slot, void *via, struct pt_regs *regs);
-
 #define MAC_CLOCK_TICK		(783300/HZ)	/* ticks per HZ */
 #define MAC_CLOCK_LOW		(MAC_CLOCK_TICK&0xFF)
 #define MAC_CLOCK_HIGH		(MAC_CLOCK_TICK>>8)
@@ -91,8 +43,6 @@
 {
 	unsigned char c;
 
-/*	mac_debugging_penguin(6);*/
-	
 	switch(macintosh_config->via_type)
 	{
 		/*
@@ -102,6 +52,10 @@
 			via1=(void *)0x50F00000;
 			via2=(void *)0x50F26000;
 			rbv=1;
+			if (macintosh_config->ident == MAC_MODEL_IIFX) {
+				via2=(void *)0x50F1A000;
+				oss=1;
+			}
 			break;
 		/*
 		 *      Quadra and early MacIIs agree on the VIA locations
@@ -162,7 +116,7 @@
 		via_write(via2,vT2CH,0);
 		via_write(via2,vIER, 0x7F);	 
 	}
-	else
+	else if (oss==0)
 	{
 		/*
 		 *	Init the RBV chip a bit
@@ -201,30 +155,18 @@
 	
 	request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func);
 
-/*	mac_debugging_penguin(7);*/
-
 	/* 
 	 * SE/30: disable video int. 
 	 * XXX: testing for SE/30 VBL
 	 */
 
-	if (macintosh_config->ident == MAC_MODEL_SE30 
-	    && console_loglevel != 10) {
+	if (macintosh_config->ident == MAC_MODEL_SE30) {
 		c = via_read(via1, vBufB);
 		via_write(via1, vBufB, c|(0x40));
 		c = via_read(via1, vDirB);
 		via_write(via1, vDirB, c|(0x40));
 	} 
 
-	/*
-	 * XXX: use positive edge
-	 */
-
-	if (console_loglevel == 10) {
-		c = via_read(via1, vPCR);
-		via_write(via1, vPCR, c|(0x1));
-	}
-
 #if 0 /* gone to mac_init_IRQ */
 	/*
 	 * Set vPCR for SCSI interrupts.
@@ -237,172 +179,29 @@
 
 }
 
-#if 0 /* moved to macints.c */
-
-static void via_irq(volatile unsigned char *via, struct via_irq_tab *irqtab,
-	struct pt_regs *regs)
-{
-	unsigned char events=(via_read(via, vIFR)&via_read(via,vIER))&0x7F;
-	int i;
-	int ct=0;	
-
-	/*
-	 *	Shouldnt happen
-	 */
-	 
-	if(events==0)
-	{
-		printk("via_irq: nothing pending!\n");
-		return;
-	}
-
-	do {
-		/*
-		 *	Clear the pending flag
-		 */
-
-		/* HACK HACK - FIXME !!! - just testing some keyboard ideas */
-	
-		/* events&=~(1<<4); */		 
-		via_write(via, vIFR, events);
-	 
-		/*
-		 *	Now see what bits are raised
-		 */
-	 
-		for(i=0;i<7;i++)
-		{
-			if(events&(1<<i))
-				(irqtab->vector[i])(i, via, regs);
-		}
-	
-		/*
-		 *	And done..
-		 */
-		events=(via_read(via, vIFR)&via_read(via,vIER))&0x7F;
-		ct++;
-		if(events && ct>8)
-		{
-		        printk("via: stuck events %x\n",events);
-		        break;
-		}
-	}
-	while(events);
-
-	scsi_mac_polled();
-}
-
-/*
- *
- *	The RBV is different. RBV appears to stand for randomly broken
- *	VIA.
- */
-
-static void rbv_irq(volatile unsigned char *via, struct via_irq_tab *irqtab,
-	struct pt_regs *regs)
-{
-	unsigned char events=(via_read(via, rIFR)&via_read(via,rIER))&0x7F;
-	int i;
-	int ct=0;	
-
-	/*
-	 *	Shouldnt happen
-	 */
-	 
-	if(events==0)
-	{
-		printk("rbv_irq: nothing pending!\n");
-		return;
-	}
-
-	do {
-		/*
-		 *	Clear the pending flag
-		 */
-
-		/* HACK HACK - FIXME !!! - just testing some keyboard ideas */
-	
-		/* events&=~(1<<4); */		 
-		via_write(via, rIFR, events);
-	 
-		/*
-		 *	Now see what bits are raised
-		 */
-	 
-		for(i=0;i<7;i++)
-		{
-			if(events&(1<<i))
-				(irqtab->vector[i])(i, via, regs);
-		}
-	
-		/*
-		 *	And done..
-		 */
-		events=(via_read(via, rIFR)&via_read(via,rIER))&0x7F;
-		ct++;
-		if(events && ct>8)
-		{
-		        printk("rbv: stuck events %x\n",events);
-			for(i=0;i<7;i++)
-			{
-				if(events&(1<<i))
-				{
-					printk("rbv - bashing source %d\n",
-						i);
-					via_write(via, rIER, i);
-					via_write(via, rIFR, i);
-				}
-			}
-		        break;
-		}
-	}
-	while(events);
-}
-
 /*
- *	System interrupts
+ *	PSC (AV Macs; level 3-6): initialize interrupt enable registers
  */
 
-void via1_irq(int irq, void *dev_id, struct pt_regs *regs)
+void psc_init(void)
 {
-	via_irq(via1, &via1_func_tab, regs);
+	via_write(psc, pIER3, 0x01);
+	via_write(psc, pIER4, 0x09);
+	via_write(psc, pIER4, 0x86);
+	via_write(psc, pIER5, 0x03);
+	via_write(psc, pIER6, 0x07);
 }
 
 /*
- *	Nubus interrupts
- */
- 
-void via2_irq(int irq, void *dev_id, struct pt_regs *regs)
-{
-/*	printk("via2 interrupt\n");*/
-	if(rbv)
-		rbv_irq(via2, &via2_func_tab, regs);
-	else
-		via_irq(via2, &via2_func_tab, regs);
-}
-
-/*
- *	Unexpected via interrupt
- */
- 
-void via_wtf(int slot, volatile void *via, struct pt_regs *regs)
-{
-	printk("Unexpected event %d on via %p\n",slot,via);
-}
-
-void nubus_wtf(int slot, volatile void *via, struct pt_regs *regs)
-{
-	printk("Unexpected interrupt on nubus slot %d\n",slot);
-}
-
-#endif
-
-/*
  *	The power switch - yes its software!
  */
  
-void mac_reset(void)
+void mac_poweroff(void)
 {
+#if 0
+	/*
+	 * Powerdown, for the Macs that support it
+	 */
 	if(rbv)	{
 		via_write(via2, rBufB, via_read(via2, rBufB)&~0x04);
 	} else {
@@ -411,7 +210,38 @@
 		/* Send a value of 0 on that line */
 		via_write(via2,vBufB,via_read(via2,vBufB)&~0x04);
 	}
+#endif
+	/* We should never make it this far... */
+	/* XXX - delay do we need to spin here ? */
+	while(1);	/* Just in case .. */
+}
+
+/* 
+ * Not all Macs support software power down; for the rest, just 
+ * try the ROM reset vector ...
+ */
+void mac_reset(void)
+{
+	unsigned long flags;
+	unsigned long *reset_hook;
+
+	save_flags(flags);
+	cli();
+
+#if 0	/* need ROMBASE in booter */
+#if 0	/* works on some */
+	rom_reset = (boot_info.bi_mac.rombase + 0xa);
+#else	/* testing, doesn't work on SE/30 either */
+	reset_hook = (unsigned long *) (boot_info.bi_mac.rombase + 0x4);
+	printk("ROM reset hook: %p\n", *reset_hook);
+	rom_reset = *reset_hook;
+#endif
+	rom_reset();
+#endif
+	restore_flags(flags);
+
 	/* We never make it this far... */
+	printk(" reboot failed, reboot manually!\n");
 	/* XXX - delay do we need to spin here ? */
 	while(1);	/* Just in case .. */
 }
@@ -442,140 +272,13 @@
 		via_write(via1, vBufA, via_read(via1, vBufA)|0x20);
 }
 
-#if 0 /* moved to macints.c */
-
-
-/*
- *    Set up the SCSI
- */
-
-void via_scsi_disable(void)
-{
-	if (rbv)
-		via_write(via2, rIER, (1<<3)|(1<<0));
-	else
-		via_write(via2, vIER, (1<<3)|(1<<0));
-}
-
-void via_scsi_enable(void)
-{
-	if (rbv)
-		via_write(via2, rIER, (1<<3)|(1<<0)|0x80);
-	else
-		via_write(via2, vIER, (1<<3)|(1<<0)|0x80);
-}
-
-void via_scsi_clear(void)
-{
-        if (rbv) 
-		via_write(via2, rIFR, (1<<3)|(1<<0)|0x80);
-	volatile unsigned char deep_magic=via_read(via2, vBufB);
-	via_scsi_enable();
-}
- 
-void via_setup_scsi(void (*handler)(int,volatile void *,struct pt_regs *))
-{
-	via2_func_tab.vector[0]=handler;        /* SCSI DRQ */
-	via2_func_tab.vector[3]=handler;        /* SCSI IRQ */
-	via_write(via2, vPCR, 0x66);		/* Edge direction! */
-	via_scsi_enable();
-}
-
-/*
- *	Nubus handling
- */
- 
-static int nubus_active=0;
- 
-int nubus_request_irq(int slot, void (*handler)(int,void *,struct pt_regs *))
-{
-	slot-=9;
-/*	printk("Nubus request irq for slot %d\n",slot);*/
-	if(nubus_func_tab.vector[slot]==nubus_wtf)
-		return -EBUSY;
-	nubus_func_tab.vector[slot]=handler;
-	nubus_active|=1<<slot;
-/*	printk("program slot %d\n",slot);*/
-/*	printk("via2=%p\n",via2);*/
-#if 0
-	via_write(via2, vDirA, 
-		via_read(via2, vDirA)|(1<<slot));
-	via_write(via2, vBufA, 0);
-#endif		
-	if (!rbv) {
-	/* Make sure the bit is an input */
-	via_write(via2, vDirA, 
-		via_read(via2, vDirA)&~(1<<slot));
-	}
-/*	printk("nubus irq on\n");*/
-	return 0;
-}
-
-int nubus_free_irq(int slot)
-{
-	slot-=9;
-	nubus_active&=~(1<<slot);
-	nubus_func_tab.vector[slot]=nubus_wtf;
-	if (rbv) {
-		via_write(via2, rBufA, 1<<slot);
-	} else {
-		via_write(via2, vDirA, 
-			via_read(via2, vDirA)|(1<<slot));
-		via_write(via2, vBufA, 1<<slot);
-		via_write(via2, vDirA, 
-			via_read(via2, vDirA)&~(1<<slot));
-	}
-	return 0;
-}
-
-static void via_do_nubus(int slot, volatile void *via, struct pt_regs *regs)
-{
-	unsigned char map;
-	int i;
-	int ct=0;
-
-/*	printk("nubus interrupt\n");*/
-		
-	if (rbv) {
-		via_write(via2, rIFR, 0x82);	/* lock the nubus interrupt */
-	} else {
-		via_write(via2, vIFR, 0x82);	/* lock the nubus interrupt */
-		
-	while(1)
-	{
-		if(rbv)
-			map=~via_read(via2, rBufA);
-		else
-			map=~via_read(via2, vBufA);
-		if((map=(map&nubus_active))==0)
-			break;
-		if(ct++>2)
-		{
-			printk("nubus stuck events - %d/%d\n", map, nubus_active);
-			return;
-		}
-		for(i=0;i<7;i++)
-		{
-			if(map&(1<<i))
-			{
-				(nubus_func_tab.vector[i])(i+9, via, regs);
-			}
-		}
-		if (rbv)
-			via_write(via2, rIFR, 0x02);	/* clear it */
-		else
-			via_write(via2, vIFR, 0x02);	/* clear it */
-	}
-	
-	/* And done */
-}
-#endif
-
 void nubus_init_via(void)
 {
 	if (rbv) {
-		via_write(via2, rBufB, via_read(via2, rBufB)|0x02);
-		via_write(via2, rIER, 0x82);	/* Interrupts on */
+		if (oss==0) {
+			via_write(via2, rBufB, via_read(via2, rBufB)|0x02);
+			via_write(via2, rIER, 0x82);	/* Interrupts on */
+		}
 	} else {
 		/* Assert the nubus active */
 		via_write(via2, vDirB, via_read(via2, vDirB)|0x02);
@@ -584,7 +287,13 @@
 		/* via_write(via2, vDirA, 0xFF); */
 		via_write(via2, vIER, 0x82);	/* Interrupts on */
 	}
-	printk("BTW  boot via1 acr=%X datab=%X pcr=%X\n",
-		(int)via1_clock, (int)via1_datab, (int)via_read(via1, vPCR));
-}
 
+	printk("nubus_init_via: via1 acr=%X datab=%X pcr=%X\n",
+		(int)via_read(via1, vACR), (int)via_read(via1, vBufB), 
+		(int)via_read(via1, vPCR));
+
+	if (rbv==0)
+		printk("nubus_init_via: via2 acr=%X datab=%X pcr=%X\n",
+			(int)via_read(via2, vACR), (int)via_read(via2, vBufB), 
+			(int)via_read(via2, vPCR));
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov