Resent-Date: Sun, 28 Feb 1999 14:36:24 +0100 (MET)
Date: Mon, 1 Mar 1999 00:19:54 +1100 (EST)
From: Ken Tyler <kent@werple.net.au>
Reply-To: Ken Tyler <kent@werple.net.au>
Subject: virge patch
To: linux-apus@sunsite.auc.dk
Cc: linux-m68k@lists.linux-m68k.org
Organization: Organization
Resent-From: linux-m68k@phil.uni-sb.de


This patch hopefully fixes the blitter problem in 16 bit modes, let me
know if it doesn't. 

Don't know the cause of the 'other' problem that appears now and
then - no scroll, just new bottom line. Suspect blitter not initialized
correctly sometimes...

Ken.

--- linux-2.2.1pre1/drivers/video/virgefb.c.save	Mon Mar  1 11:07:40 1999
+++ linux-2.2.1pre1/drivers/video/virgefb.c	Mon Mar  1 10:41:33 1999
@@ -85,10 +85,21 @@
                 (*((unsigned word volatile *)(CyberRegs + reg)) = dat)
 #define wl_3d(reg,dat) \
                 (*((unsigned long volatile *)(CyberRegs + reg)) = dat)
-
 #define rl_3d(reg) \
                 (*((unsigned long volatile *)(CyberRegs + reg)))
 
+#define Select_Zorro2_FrameBuffer(flag) \
+	do { \
+		*((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x08)) = \
+		((flag * 0x40) & 0xffff); asm volatile ("nop"); \
+	} while (0)
+/*
+ *	may be needed when we initialize the board?
+ *	8bit: flag = 2, 16 bit: flag = 1, 24/32bit: flag = 0 
+ *	_when_ the board is initialized, depth doesnt matter, we allways write
+ *	to the same address, aperture seems not to matter on Z2.
+ */
+
 struct virgefb_par {
    int xres;
    int yres;
@@ -236,28 +247,28 @@
 	"1024x768-16", {         /* Cybervision 16 bpp */
 	    1024, 768, 1024, 768, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
        }
     }, {
 	"1152x886-16", {         /* Cybervision 16 bpp */
 	    1152, 886, 1152, 886, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
        }
     }, {
 	"1280x1024-16", {         /* Cybervision 16 bpp */
 	    1280, 1024, 1280, 1024, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
        }
     }, {
 	"1600x1200-16", {         /* Cybervision 16 bpp */
 	    1600, 1200, 1600, 1200, 0, 0, 16, 0,
 	    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
-	    0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+	    0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
 	    FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
        }
     }
@@ -268,10 +279,6 @@
 
 
 static int Cyberfb_inverse = 0;
-#if 0
-static int Cyberfb_Cyber8 = 0;        /* Use Cybervision board */
-static int Cyberfb_Cyber16 = 0;       /* Use Cybervision board */
-#endif
 
 /*
  *    Some default modes
@@ -392,6 +399,7 @@
 	} else {
 		CyberSize = 0x00400000; /* 4 MB */
 	}
+
 	memset ((char*)CyberMem, 0, CyberSize);
 
 	/* Disable hardware cursor */
@@ -429,13 +437,17 @@
 {
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 	strcpy(fix->id, virgefb_name);
-	switch (par->bpp) {
-		case 8:
-			fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_8);
-			break;
-		case 16:
-			fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_16);
-			break;
+	if (cv3d_on_zorro2) {
+		fix->smem_start = (char*) CyberMem_phys;
+	} else {
+		switch (par->bpp) {
+			case 8:
+				fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_8);
+				break;
+			case 16:
+				fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_16);
+				break;
+		}
 	}
 	fix->smem_len = CyberSize;
 	fix->mmio_start = (char*) CyberRegs_phys;
@@ -663,7 +675,13 @@
  * CV3D low-level support
  */
 
-#define Cyber3D_WaitQueue(v)	 { do { while ((rl_3d(0x8504) & 0x1f00) < (((v)+2) << 8)); } while (0); }
+#define Cyber3D_WaitQueue(v) \
+{ \
+	 do { \
+		while ((rl_3d(0x8504) & 0x1f00) < (((v)+2) << 8)); \
+	 } \
+	while (0); \
+}
 
 static inline void Cyber3D_WaitBusy(void)
 {
@@ -695,11 +713,22 @@
   */
 
 static void Cyber3D_BitBLT(u_short curx, u_short cury, u_short destx,
-			   u_short desty, u_short width, u_short height)
+			   u_short desty, u_short width, u_short height, u_short depth)
 {
-	unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_DST_8BPP;
+	unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_BLT_COPY;
 
-	blitcmd |= S3V_BLT_COPY;
+	switch (depth) {
+#ifdef FBCON_HAS_CFB8
+		case 8 :
+			blitcmd |= S3V_DST_8BPP;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 16 :
+			blitcmd |= S3V_DST_16BPP;
+			break;
+#endif
+	}
 
 	/* Set drawing direction */
 	/* -Y, X maj, -X (default) */
@@ -744,16 +773,29 @@
  */
 
 static void Cyber3D_RectFill(u_short x, u_short y, u_short width,
-			     u_short height, u_short color)
+			     u_short height, u_short color, u_short depth)
 {
 	unsigned int tmp;
-	unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW | S3V_DST_8BPP |
+	unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW |
 		S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25);
 
 	if (blit_maybe_busy)
 		Cyber3D_WaitBusy();
 	blit_maybe_busy = 1;
 
+	switch (depth) {
+#ifdef FBCON_HAS_CFB8
+		case 8 :
+			blitcmd |= S3V_DST_8BPP;
+			break;
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 16 :
+			blitcmd |= S3V_DST_16BPP;
+			break;
+#endif
+	}
+
 	tmp = color & 0xff;
 	wl_3d(0xa4f4, tmp);
 
@@ -932,13 +974,17 @@
 	virgefb_get_fix(&fix, con, info);
 	if (con == -1)
 		con = 0;
-        switch (display->var.bits_per_pixel) {
-		case 8:
-			display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_8);
-			break;
-		case 16:
-			display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_16);
-			break;
+	if(cv3d_on_zorro2) {
+		display->screen_base = (char*) CyberMem;
+	} else {
+	        switch (display->var.bits_per_pixel) {
+			case 8:
+				display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_8);
+				break;
+			case 16:
+				display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_16);
+				break;
+		}
 	}
 	display->visual = fix.visual;
 	display->type = fix.type;
@@ -1149,7 +1195,6 @@
 	else
 	{
 		CyberVGARegs = (unsigned long)ioremap(board_addr +0x0c000000, 0x00010000);
-
 		CyberRegs_phys = board_addr + 0x05000000;
 		CyberMem_phys  = board_addr + 0x04000000;	/* was 0x04800000 */
 		CyberRegs = ioremap(CyberRegs_phys, 0x00010000);
@@ -1261,7 +1306,7 @@
         sx *= 8; dx *= 8; width *= 8;
         Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
                        (u_short)(dy*fontheight(p)), (u_short)width,
-                       (u_short)(height*fontheight(p)));
+                       (u_short)(height*fontheight(p)), 8);
 }
 
 static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
@@ -1273,7 +1318,7 @@
         bg = attr_bgcol_ec(p,conp);
         Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
                          (u_short)width, (u_short)(height*fontheight(p)),
-                         (u_short)bg);
+                         (u_short)bg, 8);
 }
 
 static void fbcon_virge8_putc(struct vc_data *conp, struct display *p, int c, int yy,
@@ -1318,10 +1363,10 @@
 static void fbcon_virge16_bmove(struct display *p, int sy, int sx, int dy,
                                int dx, int height, int width)
 {
-        sx *= 16; dx *= 16; width *= 16;
+        sx *= 8; dx *= 8; width *= 8;
         Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
                        (u_short)(dy*fontheight(p)), (u_short)width,
-                       (u_short)(height*fontheight(p)));
+                       (u_short)(height*fontheight(p)), 16);
 }
                 
 static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy,
@@ -1329,11 +1374,11 @@
 {
         unsigned char bg;   
                 
-        sx *= 16; width *= 16;
+        sx *= 8; width *= 8;
         bg = attr_bgcol_ec(p,conp);
         Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
                          (u_short)width, (u_short)(height*fontheight(p)),
-                         (u_short)bg);
+                         (u_short)bg, 16);
 }
    
 static void fbcon_virge16_putc(struct vc_data *conp, struct display *p, int c, int yy,


