patch-2.2.3 linux/drivers/video/creatorfb.c

Next file: linux/drivers/video/cvisionppc.h
Previous file: linux/drivers/video/controlfb.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.2/linux/drivers/video/creatorfb.c linux/drivers/video/creatorfb.c
@@ -1,7 +1,7 @@
-/* $Id: creatorfb.c,v 1.17 1998/12/28 11:23:37 jj Exp $
+/* $Id: creatorfb.c,v 1.19 1999/02/22 16:20:25 jj Exp $
  * creatorfb.c: Creator/Creator3D frame buffer driver
  *
- * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
  */
 
 #include <linux/module.h>
@@ -276,16 +276,18 @@
 	volatile u32	mer;
 };
 
-static __inline__ void FFBFifo(struct ffb_fbc *ffb, int n)
+static __inline__ void FFBFifo(struct fb_info_sbusfb *fb, int n)
 {
-	int limit = 10000;
+	struct ffb_fbc *fbc;
+	int cache = fb->s.ffb.fifo_cache;
 
-	do {
-		if((ffb->ucsr & FFB_UCSR_FIFO_MASK) >= (n + 4))
-			break;
-		if((ffb->ucsr & FFB_UCSR_ALL_ERRORS) != 0)
-			ffb->ucsr = FFB_UCSR_ALL_ERRORS;
-	} while(--limit > 0);
+	if (cache - n < 0) {
+		fbc = fb->s.ffb.fbc;
+		do {
+			cache = (fbc->ucsr & FFB_UCSR_FIFO_MASK) - 4;
+		} while (cache - n < 0);
+	}
+	fb->s.ffb.fifo_cache = cache - n;
 }
 
 static __inline__ void FFBWait(struct ffb_fbc *ffb)
@@ -340,40 +342,45 @@
 {
 	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
 	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
-	int x, y, w, h;
+	u64 yx, hw;
+	int fg;
 	
-	FFBWait(fbc);
-	FFBFifo(fbc, 6);
-	fbc->fg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p,conp)];
-	fbc->drawop = FFB_DRAWOP_RECTANGLE;
+	fg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p,conp)];
+	if (fg != fb->s.ffb.fg_cache) {
+		FFBFifo(fb, 5);
+		fbc->fg = fg;
+		fb->s.ffb.fg_cache = fg;
+	} else
+		FFBFifo(fb, 4);
 
 	if (fontheightlog(p)) {
-		y = sy << fontheightlog(p); h = height << fontheightlog(p);
+		yx = (u64)sy << (fontheightlog(p) + 32); hw = (u64)height << (fontheightlog(p) + 32);
 	} else {
-		y = sy * fontheight(p); h = height * fontheight(p);
+		yx = (u64)(sy * fontheight(p)) << 32; hw = (u64)(height * fontheight(p)) << 32;
 	}
 	if (fontwidthlog(p)) {
-		x = sx << fontwidthlog(p); w = width << fontwidthlog(p);
+		yx += sx << fontwidthlog(p); hw += width << fontwidthlog(p);
 	} else {
-		x = sx * fontwidth(p); w = width * fontwidth(p);
+		yx += sx * fontwidth(p); hw += width * fontwidth(p);
 	}
-	fbc->by = y + fb->y_margin;
-	fbc->bx = x + fb->x_margin;
-	fbc->bh = h;
-	fbc->bw = w;
+	*(volatile u64 *)&fbc->by = yx + fb->s.ffb.yx_margin;
+	*(volatile u64 *)&fbc->bh = hw;
 }
 
 static void ffb_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
 		     int count, unsigned short *boxes)
 {
 	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
+	int fg;
 
-	FFBWait(fbc);
-	FFBFifo(fbc, 2);
-	fbc->fg = ((u32 *)p->dispsw_data)[attr_bgcol(p,s)];
-	fbc->drawop = FFB_DRAWOP_RECTANGLE;
+	fg = ((u32 *)p->dispsw_data)[attr_bgcol(p,s)];
+	if (fg != fb->s.ffb.fg_cache) {
+		FFBFifo(fb, 1);
+		fbc->fg = fg;
+		fb->s.ffb.fg_cache = fg;
+	}
 	while (count-- > 0) {
-		FFBFifo(fbc, 4);
+		FFBFifo(fb, 4);
 		fbc->by = boxes[1];
 		fbc->bx = boxes[0];
 		fbc->bh = boxes[3] - boxes[1];
@@ -388,6 +395,7 @@
 	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
 	int i, xy;
 	u8 *fd;
+	u64 fgbg;
 
 	if (fontheightlog(p)) {
 		xy = (yy << (16 + fontheightlog(p)));
@@ -404,14 +412,16 @@
 		xy += (xx << fontwidthlog(p)) + fb->s.ffb.xy_margin;
 	else
 		xy += (xx * fontwidth(p)) + fb->s.ffb.xy_margin;
-	FFBWait(fbc);
-	FFBFifo(fbc, 5);
-	fbc->fg = ((u32 *)p->dispsw_data)[attr_fgcol(p,c)];
-	fbc->bg = ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
-	fbc->fontw = fontwidth(p);
-	fbc->fontinc = 0x10000;
+	fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p,c)])) << 32) |
+	       ((u32 *)p->dispsw_data)[attr_bgcol(p,c)];
+	if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) {
+		FFBFifo(fb, 2);
+		*(volatile u64 *)&fbc->fg = fgbg;
+		*(u64 *)&fb->s.ffb.fg_cache = fgbg;
+	}
+	FFBFifo(fb, 2 + fontheight(p));
 	fbc->fontxy = xy;
-	FFBFifo(fbc, fontheight(p));
+	fbc->fontw = fontwidth(p);
 	if (fontwidth(p) <= 8) {
 		for (i = 0; i < fontheight(p); i++)
 			fbc->font = *fd++ << 24;
@@ -430,11 +440,15 @@
 	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
 	int i, xy;
 	u8 *fd1, *fd2, *fd3, *fd4;
+	u64 fgbg;
 
-	FFBWait(fbc);
-	FFBFifo(fbc, 2);
-	fbc->fg = ((u32 *)p->dispsw_data)[attr_fgcol(p,*s)];
-	fbc->bg = ((u32 *)p->dispsw_data)[attr_bgcol(p,*s)];
+	fgbg = (((u64)(((u32 *)p->dispsw_data)[attr_fgcol(p,scr_readw(s))])) << 32) |
+	       ((u32 *)p->dispsw_data)[attr_bgcol(p,scr_readw(s))];
+	if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) {
+		FFBFifo(fb, 2);
+		*(volatile u64 *)&fbc->fg = fgbg;
+		*(u64 *)&fb->s.ffb.fg_cache = fgbg;
+	}
 	xy = fb->s.ffb.xy_margin;
 	if (fontwidthlog(p))
 		xy += (xx << fontwidthlog(p));
@@ -447,22 +461,20 @@
 	if (fontwidth(p) <= 8) {
 		while (count >= 4) {
 			count -= 4;
-			FFBFifo(fbc, 3);
+			FFBFifo(fb, 2 + fontheight(p));
 			fbc->fontw = 4 * fontwidth(p);
-			fbc->fontinc = 0x10000;
 			fbc->fontxy = xy;
 			if (fontheightlog(p)) {
-				fd1 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-				fd2 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-				fd3 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
-				fd4 = p->fontdata + ((*s++ & p->charmask) << fontheightlog(p));
+				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+				fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
+				fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));
 			} else {
-				fd1 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-				fd2 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-				fd3 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
-				fd4 = p->fontdata + ((*s++ & p->charmask) * fontheight(p));
+				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+				fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
+				fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));
 			}
-			FFBFifo(fbc, fontheight(p));
 			if (fontwidth(p) == 8) {
 				for (i = 0; i < fontheight(p); i++)
 					fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 
@@ -478,18 +490,16 @@
 	} else {
 		while (count >= 2) {
 			count -= 2;
-			FFBFifo(fbc, 3);
+			FFBFifo(fb, 2 + fontheight(p));
 			fbc->fontw = 2 * fontwidth(p);
-			fbc->fontinc = 0x10000;
 			fbc->fontxy = xy;
 			if (fontheightlog(p)) {
-				fd1 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
-				fd2 = p->fontdata + ((*s++ & p->charmask) << (fontheightlog(p) + 1));
+				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
+				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));
 			} else {
-				fd1 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
-				fd2 = p->fontdata + (((*s++ & p->charmask) * fontheight(p)) << 1);
+				fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
+				fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);
 			}
-			FFBFifo(fbc, fontheight(p));
 			for (i = 0; i < fontheight(p); i++) {
 				fbc->font = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p));
 				fd1 += 2; fd2 += 2;
@@ -499,15 +509,13 @@
 	}
 	while (count) {
 		count--;
-		FFBFifo(fbc, 3);
+		FFBFifo(fb, 2 + fontheight(p));
 		fbc->fontw = fontwidth(p);
-		fbc->fontinc = 0x10000;
 		fbc->fontxy = xy;
 		if (fontheightlog(p))
-			i = ((*s++ & p->charmask) << fontheightlog(p));
+			i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));
 		else
-			i = ((*s++ & p->charmask) * fontheight(p));
-		FFBFifo(fbc, fontheight(p));
+			i = ((scr_readw(s++) & p->charmask) * fontheight(p));
 		if (fontwidth(p) <= 8) {
 			fd1 = p->fontdata + i;
 			for (i = 0; i < fontheight(p); i++)
@@ -554,8 +562,12 @@
 
 static void ffb_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
 {
+	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
+
 	fb->s.ffb.xy_margin = (y_margin << 16) + x_margin;
+	fb->s.ffb.yx_margin = (((u64)y_margin) << 32) + x_margin;
 	p->screen_base += 8192 * (y_margin - fb->y_margin) + 4 * (x_margin - fb->x_margin);
+	FFBWait(fbc);
 }
 
 static inline void ffb_curs_enable (struct fb_info_sbusfb *fb, int enable)
@@ -619,11 +631,16 @@
 	register struct ffb_fbc *fbc = fb->s.ffb.fbc;
 
 	FFBWait(fbc);
-	FFBFifo(fbc, 4);
+	fb->s.ffb.fifo_cache = 0;
+	FFBFifo(fb, 8);
 	fbc->ppc = FFB_PPC_VCE_DISABLE|FFB_PPC_TBE_OPAQUE|FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST;
 	fbc->fbc = 0x2000707f;
 	fbc->rop = FFB_ROP_NEW;
+	fbc->drawop = FFB_DRAWOP_RECTANGLE;
 	fbc->pmask = 0xffffffff;
+	fbc->fontinc = 0x10000;
+	fbc->fg = fb->s.ffb.fg_cache;
+	fbc->bg = fb->s.ffb.bg_cache;
 	FFBWait(fbc);
 }                                
 
@@ -675,6 +692,7 @@
 	disp->scrollmode = SCROLL_YREDRAW;
 	disp->screen_base = (char *)__va(regs[0].phys_addr) + FFB_DFB24_POFF + 8192 * fb->y_margin + 4 * fb->x_margin;
 	fb->s.ffb.xy_margin = (fb->y_margin << 16) + fb->x_margin;
+	fb->s.ffb.yx_margin = (((u64)fb->y_margin) << 32) + fb->x_margin;
 	fb->s.ffb.fbc = (struct ffb_fbc *)((char *)__va(regs[0].phys_addr) + FFB_FBC_REGS_POFF);
 	fb->s.ffb.dac = (struct ffb_dac *)((char *)__va(regs[0].phys_addr) + FFB_DAC_POFF);
 	fb->dispsw = ffb_dispsw;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)