[parisc-linux-cvs] HCRX support for stifb

Thomas Bogendoerfer tsbogend@alpha.franken.de
Tue, 9 Oct 2001 00:28:49 +0200


Hi,

the patch below, which I'm going to commit in a couple of seconds,
fixes the panic, if there is an additional framebuffer installed
in an old system. It adds also support for 8 bit HCRX cards (tested
on 715/100 and C100). Since stifb works now on ARTIST, VIS-EG and
HCRX, I've enabled them by default.

Thomas.

Index: sticore.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/sticore.c,v
retrieving revision 1.23
diff -u -r1.23 sticore.c
--- sticore.c	2001/09/26 18:15:19	1.23
+++ sticore.c	2001/10/08 22:19:20
@@ -839,12 +839,12 @@
 		rom = dev->addr[0];
 	}
 	if (!rom) {
-		rom = PAGE0->proc_sti;
-	}
-	if (!rom) {
 		rom = dev->hpa;
+		DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
+		if (sti_try_rom_generic(rom, dev->hpa, NULL))
+			return 0;
+		rom = PAGE0->proc_sti;
 	}
-
 	DPRINTK((KERN_DEBUG "Trying STI ROM at %08lx, hpa at %08lx\n", rom, dev->hpa));
 	if (sti_try_rom_generic(rom, dev->hpa, NULL))
 		return 0;
Index: stifb.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/stifb.c,v
retrieving revision 1.21
diff -u -r1.21 stifb.c
--- stifb.c	2001/09/29 16:45:08	1.21
+++ stifb.c	2001/10/08 22:19:22
@@ -165,6 +165,7 @@
 #define REG_32		0x21003c
 #define REG_33		0x210040
 #define REG_34		0x200008
+#define REG_35		0x018010
 #define REG_38		0x210020
 #define REG_39		0x210120
 #define REG_40		0x210130
@@ -401,7 +402,13 @@
 
 #define NGLE_REALLY_SET_IMAGE_FG_COLOR(fb_info, fg32) \
 	WRITE_WORD(fg32, fb_info->iobase + REG_35)
-	
+
+#define NGLE_SET_TRANSFERDATA(fb_info, val) \
+	WRITE_WORD(val, fb_info->iobase + REG_8)
+
+#define NGLE_SET_DSTXY(fb_info, val) \
+	WRITE_WORD(val, fb_info->iobase + REG_6)
+
 #define NGLE_LONG_FB_ADDRESS(fbaddrbase, x, y) (		\
 	(unsigned long) (fbaddrbase) +				\
 	    (	(unsigned int)  ( (y) << 13      ) |		\
@@ -422,7 +429,10 @@
 
 #define START_COLORMAPLOAD(fb_info, cmapBltCtlData32) \
 	WRITE_WORD((cmapBltCtlData32), fb_info->iobase + REG_38)
-	
+
+#define SET_LENXY_START_RECFILL(fb_info, lenxy) \
+	WRITE_WORD(lenxy, fb_info->iobase + REG_9)
+
 static void
 HYPER_ENABLE_DISABLE_DISPLAY(struct stifb_info *fb_info, int enable)
 {
@@ -638,13 +648,90 @@
 }
 
 static void
-ngleResetAttrPlanes(struct stifb_info *fb_info, int enable)
+ngleResetAttrPlanes(struct stifb_info *fb_info, unsigned int ctlPlaneReg)
 {
-	/* FIXME! */
+	int	nFreeFifoSlots = 0;
+	unsigned long packed_dst;
+	unsigned long packed_len;
+
+	NGLE_LOCK(fb_info);
+
+	GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 4);
+	NGLE_QUICK_SET_DST_BM_ACCESS(fb_info, 
+				     BA(IndexedDcd, Otc32, OtsIndirect,
+					AddrLong, BAJustPoint(0),
+					BINattr, BAIndexBase(0)));
+	NGLE_QUICK_SET_CTL_PLN_REG(fb_info, ctlPlaneReg);
+	NGLE_SET_TRANSFERDATA(fb_info, 0xffffffff);
+
+	NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb_info,
+				       IBOvals(RopSrc, MaskAddrOffset(0),
+					       BitmapExtent08, StaticReg(1),
+					       DataDynamic, MaskOtc,
+					       BGx(0), FGx(0)));
+	packed_dst = 0;
+	packed_len = (1280 << 16) | 1024;
+	GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 2);
+	NGLE_SET_DSTXY(fb_info, packed_dst);
+	SET_LENXY_START_RECFILL(fb_info, packed_len);
+
+	/*
+	 * In order to work around an ELK hardware problem (Buffy doesn't
+	 * always flush it's buffers when writing to the attribute
+	 * planes), at least 4 pixels must be written to the attribute
+	 * planes starting at (X == 1280) and (Y != to the last Y written
+	 * by BIF):
+	 */
+
+	if (fb_info->id == S9000_ID_A1659A) {   /* ELK_DEVICE_ID */
+		/* It's safe to use scanline zero: */
+		packed_dst = (1280 << 16);
+		GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 2);
+		NGLE_SET_DSTXY(fb_info, packed_dst);
+		packed_len = (4 << 16) | 1;
+		SET_LENXY_START_RECFILL(fb_info, packed_len);
+	}   /* ELK Hardware Kludge */
+
+	/**** Finally, set the Control Plane Register back to zero: ****/
+	GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 1);
+	NGLE_QUICK_SET_CTL_PLN_REG(fb_info, 0);
+	
+	NGLE_UNLOCK(fb_info);
 }
+    
 static void
-ngleClearOverlayPlanes(struct stifb_info *fb_info, int mask, int len)
+ngleClearOverlayPlanes(struct stifb_info *fb_info, int mask, int data)
 {
+    	int nFreeFifoSlots = 0;
+        unsigned long packed_dst;
+        unsigned long packed_len;
+    
+	NGLE_LOCK(fb_info);
+
+	/* Hardware setup */
+	GET_FIFO_SLOTS(fb_info, nFreeFifoSlots, 8);
+	NGLE_QUICK_SET_DST_BM_ACCESS(fb_info, 
+				     BA(IndexedDcd, Otc04, Ots08, AddrLong,
+					BAJustPoint(0), BINovly, BAIndexBase(0)));
+
+        NGLE_SET_TRANSFERDATA(fb_info, 0xffffffff);  /* Write foreground color */
+
+        NGLE_REALLY_SET_IMAGE_FG_COLOR(fb_info, data);
+        NGLE_REALLY_SET_IMAGE_PLANEMASK(fb_info, mask);
+    
+        packed_dst = 0;
+        packed_len = (1280 << 16) | 1024;
+        NGLE_SET_DSTXY(fb_info, packed_dst);
+    
+        /* Write zeroes to overlay planes */		       
+	NGLE_QUICK_SET_IMAGE_BITMAP_OP(fb_info,
+				       IBOvals(RopSrc, MaskAddrOffset(0),
+					       BitmapExtent08, StaticReg(0),
+					       DataDynamic, MaskOtc, BGx(0), FGx(0)));
+		       
+        SET_LENXY_START_RECFILL(fb_info, packed_len);
+
+	NGLE_UNLOCK(fb_info);
 }
 
 static void 
@@ -675,10 +762,7 @@
 		ngleResetAttrPlanes(fb_info, controlPlaneReg);
 
 		/* clear overlay planes */
-		if (fb_info->bpp == 8)
-			ngleClearOverlayPlanes(fb_info, 0xff, 0);
-		else
-			ngleClearOverlayPlanes(fb_info, 0xff, 255);
+	        ngleClearOverlayPlanes(fb_info, 0xff, 255);
 
 		/**************************************************
 		 ** Also need to counteract ITE settings 
@@ -978,11 +1062,19 @@
 	p->palette[regno].green = green;
 	p->palette[regno].blue = blue;
 
-	START_IMAGE_COLORMAP_ACCESS(p);
-	WRITE_IMAGE_COLOR(p, regno, color);
-
 	if (p->id == S9000_ID_HCRX) {
 		NgleLutBltCtl lutBltCtl;
+	        int i;
+
+	        START_IMAGE_COLORMAP_ACCESS(p);
+	        for (i = 0; i < 256; i++) {
+		    color = ((p->palette[i].red << 16) |
+			     (p->palette[i].green << 8) |
+			     (p->palette[i].blue));
+		    
+		    WRITE_IMAGE_COLOR(p, i, color);
+		}
+
 		lutBltCtl = setHyperLutBltCtl(p, 
 				0,	/* Offset w/i LUT */
 				256);	/* Load entire LUT */
@@ -992,6 +1084,8 @@
 		START_COLORMAPLOAD(p, lutBltCtl.all);
 		SETUP_FB(p);
 	} else {
+	        START_IMAGE_COLORMAP_ACCESS(p);
+	        WRITE_IMAGE_COLOR(p, regno, color);
 		/* cleanup colormap hardware */
 		FINISH_IMAGE_COLORMAP_ACCESS(p);
 	}
@@ -1176,7 +1270,9 @@
 
 #if 1
 	/* HACK: Only allow an Artist gfx */
-	if (fb_info.id != S9000_ID_ARTIST) {
+	if ((fb_info.id != S9000_ID_ARTIST) &&
+	    (fb_info.id != S9000_ID_HCRX) &&
+	    (fb_info.id != CRT_ID_VISUALIZE_EG)) {
 		return -ENXIO;
 	}
 #endif
@@ -1230,15 +1326,18 @@
 		break;
 	case S9000_ID_HCRX:	/* Hyperdrive/HCRX */
 		memset(&fb_info.ngle_rom, 0, sizeof(fb_info.ngle_rom));
-		fb_info.bpp = 24;
 		if ((fb_info.sti->regions_phys[0] & 0xfc000000) ==
 		    (fb_info.sti->regions_phys[2] & 0xfc000000))
 			sti_rom_address = fb_info.sti->regions_phys[2];
 		else
 			sti_rom_address = fb_info.sti->regions_phys[3];
+		fb_info.deviceSpecificConfig = gsc_readl(sti_rom_address);
+		if (IS_24_DEVICE((&fb_info)))
+			fb_info.bpp = 24;
+		else
+			fb_info.bpp = 8;
 		READ_WORD(fb_info.iobase + REG_15);
 		SETUP_HW(&fb_info);
-		fb_info.deviceSpecificConfig = gsc_readl(sti_rom_address);
 		break;
 	case CRT_ID_VISUALIZE_EG:
 	case S9000_ID_ARTIST:	/* Artist */

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.                                 [ Alexander Viro on linux-kernel ]