X-Aliased: From amigo@jeddeloh.Informatik.Uni-Oldenburg.DE (Frank Neumann)
From: "Frank Neumann" <Frank.Neumann@Informatik.Uni-Oldenburg.DE>
Subject: L68K: CLGen: Patch for A2000 systems
To: linux-m68k@lists.linux-m68k.org
Date: Fri, 30 Jan 1998 01:18:22 +0100 (MET)
Cc: Jes.Sorensen@cern.ch
Sender: owner-linux-m68k@phil.uni-sb.de


Hi, 
the following patch, to be applied on top of CLGen 1.3, will enable correct
support of The Picasso IV in Zorro II systems, aka the A2000.

Thanks go to Oliver Baesener for bringing this to my attention and testing it.

Frank

PS: This is still for 2.0.x kernels. I have not yet adapted the driver
for 2.1.x.
---- cut here ----
--- arch/m68k/amiga/clgen.c.orig	Thu Jan 29 14:37:15 1998
+++ arch/m68k/amiga/clgen.c	Thu Jan 29 14:34:51 1998
@@ -25,11 +25,12 @@
  *			correct behaviour when used with fbset
  *
  *  - 12-Jan-1998: v1.3 Public release
- *			correct CLUT handling for Picasso4 (was BGR, not RGB)
+ *			correct CLUT handling for Picasso IV (was BGR, not RGB)
  *			removed left-over printk for Picasso II
  *			now accepts monitorcap: and mode: on command line
  *			correct "scrolling" when height or width = 0
  * 			(though that's been done in console/fbcon.c)
+ * - 29-Jan-1998: v1.3b Added support for P4 in Zorro II (A2000)
  *
  * 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
@@ -81,7 +82,7 @@
 #include "clgen.h"
 
 /*** DEFINES ***/
-#define CLGEN_VERSION "1.3 (12-Jan-98)"
+#define CLGEN_VERSION "1.3b (29-Jan-98)"
 /* #define DEBUG if(1) */
 #define DEBUG if(0)
 
@@ -125,6 +126,7 @@
 	unsigned char *VirtRAMAddr; /* virtual start address of DRAM area */
 	unsigned long size;       /* length of board address space in bytes */
 	int smallboard;           /* board has small/large mem, shortcut */
+	int p4flag;		  /* auxiliary flag for P4 in Z2 mode */
 	unsigned char SFR;        /* shadow of "special function register" */
 	/* This maybe not really belongs here, but for now... */
 /* ###	int xres, yres; */
@@ -658,61 +660,71 @@
 	/* misc... */
 	WHDR(0); /* Hidden DAC register: - */
 
-	/* "pre-set" a RAMsize; if the test succeeds, double it */
-	if (clboards[slotnum].boardtype == BT_SD64 ||
-		clboards[slotnum].boardtype == BT_PICASSO4)
-		clboards[slotnum].size = 0x400000;
-	else
-		clboards[slotnum].size = 0x200000;
+	/* if p4flag is set, board RAM size has already been determined, so skip test */
+	if (!clboards[slotnum].p4flag)
+	{
+		/* "pre-set" a RAMsize; if the test succeeds, double it */
+		if (clboards[slotnum].boardtype == BT_SD64 ||
+			clboards[slotnum].boardtype == BT_PICASSO4)
+			clboards[slotnum].size = 0x400000;
+		else
+			clboards[slotnum].size = 0x200000;
 
-	/* assume it's a "large memory" board (2/4 MB) */
-	clboards[slotnum].smallboard = FALSE;
+		/* assume it's a "large memory" board (2/4 MB) */
+		clboards[slotnum].smallboard = FALSE;
 
-	/* check for 1/2 MB Piccolo/Picasso/Spectrum resp. 2/4 MB SD64 */
-	/* DRAM register has already been pre-set for "large", so it is*/
-	/* only modified if we find that this is a "small" version */
-	{
-		unsigned volatile char *ram = clboards[slotnum].VirtRAMAddr;
-		int i, flag = 0;
+		/* check for 1/2 MB Piccolo/Picasso/Spectrum resp. 2/4 MB SD64 */
+		/* DRAM register has already been pre-set for "large", so it is*/
+		/* only modified if we find that this is a "small" version */
+		{
+			unsigned volatile char *ram = clboards[slotnum].VirtRAMAddr;
+			int i, flag = 0;
 
-		ram += (clboards[slotnum].size >> 1);
+			ram += (clboards[slotnum].size >> 1);
 
-		for (i = 0; i < 256; i++)
-			*(ram+i) = (unsigned char)i;
+			for (i = 0; i < 256; i++)
+				*(ram+i) = (unsigned char)i;
 
-		for (i = 0; i < 256; i++)
-		{
-			if (*(ram + i) != i)
-				flag = 1;
-		}
+			for (i = 0; i < 256; i++)
+			{
+				if (*(ram + i) != i)
+					flag = 1;
+			}
 
-		/* if the DRAM test failed, halve RAM value */
-		if (flag)
-		{
-			clboards[slotnum].size /= 2;
-			clboards[slotnum].smallboard = TRUE;
-			switch(clboards[slotnum].boardtype)
+			/* if the DRAM test failed, halve RAM value */
+			if (flag)
 			{
-				case BT_SD64:
-					WSeq(SRF, 0x38);  /* 2 MB Ram SD64 */
-					break;
+				clboards[slotnum].size /= 2;
+				clboards[slotnum].smallboard = TRUE;
+				switch(clboards[slotnum].boardtype)
+				{
+					case BT_SD64:
+						WSeq(SRF, 0x38);  /* 2 MB Ram SD64 */
+						break;
 
-				case BT_PICCOLO:
-				case BT_PICASSO:
-				case BT_SPECTRUM:
-					WSeq(SRF, 0x30); /* 1 MB DRAM */
-					break;
+					case BT_PICCOLO:
+					case BT_PICASSO:
+					case BT_SPECTRUM:
+						WSeq(SRF, 0x30); /* 1 MB DRAM */
+						break;
 
-				case BT_PICASSO4:
-					WSeq(SRF, 0x38);   /* ### like SD64? */
-					break;
-				default:
-					printk(KERN_WARNING "clgen: Uuhh..?\n");
+					case BT_PICASSO4:
+						WSeq(SRF, 0x38);   /* ### like SD64? */
+						break;
+					default:
+						printk(KERN_WARNING "clgen: Uuhh..?\n");
+				}
 			}
 		}
-
-		printk(KERN_INFO "clgen: This board has %ld bytes of DRAM memory\n", clboards[slotnum].size);
 	}
+	else
+	{
+		/* In case of P4 in Z2 mode, set reg here */
+		if (clboards[slotnum].smallboard)
+			WSeq(SRF, 0x38);
+	}
+
+	printk(KERN_INFO "clgen: This board has %ld bytes of DRAM memory\n", clboards[slotnum].size);
 }
 
 
@@ -1689,7 +1701,7 @@
 				break;
 
 			case BT_PICASSO4:
-	DEBUG printk(KERN_INFO "(for Picasso 4)\n");
+	DEBUG printk(KERN_INFO "(for Picasso IV)\n");
 				WSeq(SR7, 0x20);
 /*				WSeq(SR1F, 0x1c); */
 /* SRF not being set here...	WSeq(SRF, 0xd0); */
@@ -2667,9 +2679,9 @@
 /********************************************************************/
 struct fb_info *clgen_fb_init(long *mem_start)
 {
-	int key, key2;
-	struct ConfigDev *cd = NULL, *cd2 = NULL;
-	int err, i, slotnum;
+	int key = 0, key2 = 0, key3 = 0;
+	struct ConfigDev *cd = NULL, *cd2 = NULL, *cd3 = NULL;
+	int err, i, slotnum, p4flag = 0;
 	int btype;
 	static int firstpass = 0;
 	static struct fb_var_screeninfo init_var;
@@ -2732,32 +2744,41 @@
 		}
 
 
-		/* none found, check next board type (Picasso 4, 4th ProdID) */
+		/* none found, check next board type (Picasso 4, 4th ProdID (Zorro 3)) */
 		if (btype == -1)
 		{
 			key  = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_IV_4, 0, 0);
 			if (key != 0)
 			{
 				btype = BT_PICASSO4;
-				printk(KERN_INFO "clgen: Picasso 4 board detected; ");
+				printk(KERN_INFO "clgen: Picasso IV board detected; ");
+				p4flag = 0;
+			}
+		}
+
+
+		/* none found, check next board type (Picasso 4 In Zorro 2) */
+		if (btype == -1)
+		{
+			key  = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_IV, 0, 0);
+			key2 = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_IV_2, 0, 0);
+			key3 = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_IV_3, 0, 0);
+			if (key != 0)
+			{
+				btype = BT_PICASSO4;
+				printk(KERN_INFO "clgen: Picasso IV board (in Zorro II) detected; ");
+				p4flag = 1;
 			}
 		}
 
+
 		/* When we get here with != -1, we have a board to be init'ed. */
 		if (btype != -1)
 		{
 			cd = zorro_get_board(key);
-			printk(" RAM (%d KB) at $%lx, ",
-				(unsigned int)(cd->cd_BoardSize/1024),
-				(unsigned long)(cd->cd_BoardAddr));
-
-			if (btype != BT_PICASSO4)
-			{
-				cd2 = zorro_get_board(key2);
-				printk(" REG at $%lx\n", (unsigned long)(cd2->cd_BoardAddr));
-			}
-			else
-				printk(" REG at $%lx\n", (unsigned long)(cd->cd_BoardAddr + 0x600000));
+			cd2 = zorro_get_board(key2);
+			if (p4flag)
+				cd3 = zorro_get_board(key3);
 
 			/* search for a free slot in the clboards[] array */
 			slotnum = find_clboard(-1);
@@ -2767,6 +2788,8 @@
 				return(NULL);
 			}
 
+			clboards[slotnum].p4flag = 0;
+
 			DEBUG printk(KERN_INFO "clgen: Found a free slot for this board at array elem #%d\n", slotnum);
 			/* set address for RAM area of board */
 			if (btype != BT_PICASSO4)
@@ -2776,10 +2799,32 @@
 			}
 			else
 			{
-				/* To be precise, for the P4 this is not the */
-				/* begin of the board, but the begin of RAM. */
-				clboards[slotnum].PhysAddr = (unsigned long)cd->cd_BoardAddr + 0x1000000;
-				clboards[slotnum].size = cd->cd_BoardSize;
+				/* p4flag set: P4 in Z2 mode, else in Z3 */
+				if (!p4flag)
+				{
+					/* To be precise, for the P4 this is not the */
+					/* begin of the board, but the begin of RAM. */
+					clboards[slotnum].PhysAddr = (unsigned long)cd->cd_BoardAddr + 0x1000000;
+					clboards[slotnum].size = cd->cd_BoardSize;
+				}
+				else
+				{
+					clboards[slotnum].PhysAddr = (unsigned long)cd->cd_BoardAddr;
+					clboards[slotnum].size = cd->cd_BoardSize;
+					clboards[slotnum].smallboard = TRUE;
+					if (key2)
+					{
+						DEBUG printk(KERN_INFO "clgen: detected Picasso IV in Z2 with both banks enabled (4 MB)\n");
+						clboards[slotnum].size += cd2->cd_BoardSize;
+						clboards[slotnum].smallboard = FALSE;
+					}
+					else
+					{
+						DEBUG printk(KERN_INFO "clgen: detected Picasso IV in Z2 with one bank enabled (2 MB)\n");
+					}
+					/* flag: this board needs no RAM amount check */
+					clboards[slotnum].p4flag = 1;
+				}
 			}
 
 			/* map the physical board address to a virtual address in */
@@ -2787,7 +2832,7 @@
 			/* space; Z2 boards (like the Picasso) are in the low 16 MB region */
 			/* which is automatically mapped so that no kernel_map is */
 			/* necessary there (only Z2 address translation) */
-			if (btype != BT_PICASSO4)
+			if (btype != BT_PICASSO4 || p4flag)
 			{
 				if (clboards[slotnum].PhysAddr > 0x01000000)
 				{
@@ -2803,7 +2848,7 @@
 			}
 			else
 			{
-				/* for P4, map in its address space in 2 chunks (### TEST! ) */
+				/* for P4 (Z3), map in its address space in 2 chunks (### TEST! ) */
 				/* (note the ugly hardcoded 16M number) */
 				clboards[slotnum].VirtRegBase = (unsigned char *)kernel_map(
 					(unsigned long)cd->cd_BoardAddr, 
@@ -2814,30 +2859,27 @@
 				clboards[slotnum].VirtRAMAddr = (unsigned char *)kernel_map(
 					(unsigned long)cd->cd_BoardAddr + 16777216, 
 					16777216, KERNELMAP_NOCACHE_SER, mem_start);
-
-#if 0
-				/* but for Picasso 4, it's at <board start + 16M> */
-				clboards[slotnum].VirtRAMAddr = clboards[slotnum].VirtAddr + 0x01000000;
-#endif
 			}
 
+			printk(KERN_INFO "clgen: Virtual address for board set to: $%p\n", clboards[slotnum].VirtAddr);
+			printk(KERN_INFO "clgen: (RAM start set to: $%p)\n", clboards[slotnum].VirtRAMAddr);
+#if 0
 			DEBUG printk(KERN_INFO "clgen: Virtual address for board set to: $%p\n", clboards[slotnum].VirtAddr);
 			DEBUG printk(KERN_INFO "clgen: (RAM start set to: $%p)\n", clboards[slotnum].VirtRAMAddr);
+#endif
 
 			/* set address for REG area of board */
-			if (btype != BT_PICASSO4)
+			if (btype != BT_PICASSO4 || p4flag)
 			{
-				clboards[slotnum].RegBase = cd2->cd_BoardAddr;
+				if (!p4flag)
+					clboards[slotnum].RegBase = cd2->cd_BoardAddr;
+				else
+					clboards[slotnum].RegBase = cd3->cd_BoardAddr + 0x10000;
+
 				clboards[slotnum].VirtRegBase = 
 					(unsigned char *)ZTWO_VADDR(clboards[slotnum].RegBase);
 			}
-			else
-			{
-#if 0
-				clboards[slotnum].RegBase = cd->cd_BoardAddr + 0x600000;
-				clboards[slotnum].VirtRegBase = clboards[slotnum].VirtAddr + 0x600000;
-#endif
-			}
+
 
 			/* set defaults for monitor specifications */
 			/* these should be careful values for most, even old, monitors */
@@ -2869,6 +2911,17 @@
 			zorro_config_board(key, 0);
 			if (btype != BT_PICASSO4)
 				zorro_config_board(key2, 0);
+			else
+			{
+				/* configure the other 2 areas of Z2 P4 if found */
+				if (p4flag)
+				{
+					if (key2)
+						zorro_config_board(key2, 0);
+					if (key3)
+						zorro_config_board(key3, 0);
+				}
+			}
 
 			num_inited++;
 			DEBUG printk(KERN_INFO "clgen: Number of init'ed CLGEN boards at this time: %d\n", num_inited);
@@ -2894,7 +2947,7 @@
 					DEBUG printk("GVP Spectrum\n");
 					break;
 				case BT_PICASSO4:
-					DEBUG printk("Picasso 4\n");
+					DEBUG printk("Picasso IV\n");
 					break;
 				default: 
 					DEBUG printk("Unidentified - Huh?\n");
@@ -2997,18 +3050,43 @@
 
 int clgen_probe()
 {
-	int bla1, bla2, bla3, bla4, bla5;
+	int bla;
 
 	/* if the DRAM area of any of these boards is found, I can be */
 	/* pretty sure the rest is also there - enough anyway to attempt */	
 	/* to start to initialize the console on it. */
-	bla1 = zorro_find(MANUF_HELFRICH2, PROD_SD64_RAM, 0, 0);
-	bla2 = zorro_find(MANUF_HELFRICH2, PROD_PICCOLO_RAM, 0, 0);
-	bla3 = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_II_RAM, 0, 0);
-	bla4 = zorro_find(MANUF_GVP2, PROD_SPECTRUM_RAM, 0, 0);
-	bla5 = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_IV_4, 0, 0);
 
-	return (bla1 || bla2 || bla3 || bla4 || bla5);
+	/* SD64? */
+	bla = zorro_find(MANUF_HELFRICH2, PROD_SD64_RAM, 0, 0);
+	if (bla)
+		return bla;
+
+	/* Piccolo? */
+	bla = zorro_find(MANUF_HELFRICH2, PROD_PICCOLO_RAM, 0, 0);
+	if (bla)
+		return bla;
+
+	/* Picasso II? */
+	bla = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_II_RAM, 0, 0);
+	if (bla)
+		return bla;
+
+	/* GVP Spectrum? */
+	bla = zorro_find(MANUF_GVP2, PROD_SPECTRUM_RAM, 0, 0);
+	if (bla)
+		return bla;
+
+	/* Picasso IV in Z3? */
+	bla = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_IV_4, 0, 0);
+	if (bla)
+		return bla;
+
+	/* Picasso IV in Z2? */
+	bla = zorro_find(MANUF_VILLAGE_TRONIC, PROD_PICASSO_IV, 0, 0);
+	if (bla)
+		return bla;
+
+	return 0;
 }
 
 
