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
- Lines: 267
- Date:
Thu Feb 25 10:02:12 1999
- Orig file:
v2.2.2/linux/drivers/video/creatorfb.c
- Orig date:
Wed Jan 20 23:14:06 1999
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)