From db7d4daea91e105e3859cf461d7e53b9b77454b2 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 13 Jun 1999 16:29:25 +0000 Subject: Merge with Linux 2.2.8. --- drivers/video/creatorfb.c | 166 +++++++++++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 76 deletions(-) (limited to 'drivers/video/creatorfb.c') diff --git a/drivers/video/creatorfb.c b/drivers/video/creatorfb.c index 69242992d..81421a7ff 100644 --- a/drivers/video/creatorfb.c +++ b/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.27 1999/03/28 12:37:12 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 @@ -132,18 +132,10 @@ struct ffb_fbc { /* Next vertex registers */ - u32 xxx1[3]; - volatile u32 alpha; - volatile u32 red; - volatile u32 green; - volatile u32 blue; - volatile u32 depth; - volatile u32 y; - volatile u32 x; - u32 xxx2[2]; - volatile u32 ryf; - volatile u32 rxf; - u32 xxx3[2]; + u32 xxx1[3]; volatile u32 alpha; volatile u32 red; + volatile u32 green; volatile u32 blue; volatile u32 depth; volatile + u32 y; volatile u32 x; u32 xxx2[2]; volatile u32 ryf; volatile u32 + rxf; u32 xxx3[2]; volatile u32 dmyf; volatile u32 dmxf; @@ -276,16 +268,17 @@ struct ffb_fbc { 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) - 8; + } while (cache - n < 0); + } + fb->s.ffb.fifo_cache = cache - n; } static __inline__ void FFBWait(struct ffb_fbc *ffb) @@ -340,40 +333,45 @@ static void ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx, { 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 +386,7 @@ static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int 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 +403,16 @@ static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int 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 +431,15 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh register struct ffb_fbc *fbc = fb->s.ffb.fbc; int i, xy; u8 *fd1, *fd2, *fd3, *fd4; - - 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)]; + u64 fgbg; + + 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 +452,20 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh 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 +481,16 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh } 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 +500,13 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh } 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 +553,12 @@ static struct display_switch ffb_dispsw __initdata = { 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 +622,16 @@ static void ffb_switch_from_graph (struct fb_info_sbusfb *fb) 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 +683,7 @@ __initfunc(char *creatorfb_init(struct fb_info_sbusfb *fb)) 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; @@ -710,5 +719,10 @@ __initfunc(char *creatorfb_init(struct fb_info_sbusfb *fb)) sprintf(idstring, "%s at %016lx type %d DAC %d", fix->id, regs[0].phys_addr, i, fb->s.ffb.dac_rev); + /* Elite3D has different DAC revision numbering, and no DAC revisions + have the reversed meaning of cursor enable */ + if (afb) + fb->s.ffb.dac_rev = 10; + return idstring; } -- cgit v1.2.3