diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-05 06:47:02 +0000 |
commit | 99a7e12f34b3661a0d1354eef83a0eef4df5e34c (patch) | |
tree | 3560aca9ca86792f9ab7bd87861ea143a1b3c7a3 /drivers/video/creatorfb.c | |
parent | e73a04659c0b8cdee4dd40e58630e2cf63afb316 (diff) |
Merge with Linux 2.3.38.
Diffstat (limited to 'drivers/video/creatorfb.c')
-rw-r--r-- | drivers/video/creatorfb.c | 326 |
1 files changed, 225 insertions, 101 deletions
diff --git a/drivers/video/creatorfb.c b/drivers/video/creatorfb.c index e2fefe0f4..d01a4c9fc 100644 --- a/drivers/video/creatorfb.c +++ b/drivers/video/creatorfb.c @@ -1,4 +1,4 @@ -/* $Id: creatorfb.c,v 1.29 1999/08/10 15:56:07 davem Exp $ +/* $Id: creatorfb.c,v 1.31 1999/11/19 09:57:12 davem Exp $ * creatorfb.c: Creator/Creator3D frame buffer driver * * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz) @@ -21,6 +21,8 @@ #include <video/sbusfb.h> +#include <asm/upa.h> + #define FFB_SFB8R_VOFF 0x00000000 #define FFB_SFB8G_VOFF 0x00400000 #define FFB_SFB8B_VOFF 0x00800000 @@ -49,24 +51,24 @@ #define FFB_PROM_VOFF 0x0bc08000 #define FFB_EXP_VOFF 0x0bc18000 -#define FFB_SFB8R_POFF 0x04000000 -#define FFB_SFB8G_POFF 0x04400000 -#define FFB_SFB8B_POFF 0x04800000 -#define FFB_SFB8X_POFF 0x04c00000 -#define FFB_SFB32_POFF 0x05000000 -#define FFB_SFB64_POFF 0x06000000 -#define FFB_FBC_REGS_POFF 0x00600000 -#define FFB_BM_FBC_REGS_POFF 0x00600000 -#define FFB_DFB8R_POFF 0x01000000 -#define FFB_DFB8G_POFF 0x01400000 -#define FFB_DFB8B_POFF 0x01800000 -#define FFB_DFB8X_POFF 0x01c00000 -#define FFB_DFB24_POFF 0x02000000 -#define FFB_DFB32_POFF 0x03000000 -#define FFB_FBC_KREGS_POFF 0x00610000 -#define FFB_DAC_POFF 0x00400000 -#define FFB_PROM_POFF 0x00000000 -#define FFB_EXP_POFF 0x00200000 +#define FFB_SFB8R_POFF 0x04000000UL +#define FFB_SFB8G_POFF 0x04400000UL +#define FFB_SFB8B_POFF 0x04800000UL +#define FFB_SFB8X_POFF 0x04c00000UL +#define FFB_SFB32_POFF 0x05000000UL +#define FFB_SFB64_POFF 0x06000000UL +#define FFB_FBC_REGS_POFF 0x00600000UL +#define FFB_BM_FBC_REGS_POFF 0x00600000UL +#define FFB_DFB8R_POFF 0x01000000UL +#define FFB_DFB8G_POFF 0x01400000UL +#define FFB_DFB8B_POFF 0x01800000UL +#define FFB_DFB8X_POFF 0x01c00000UL +#define FFB_DFB24_POFF 0x02000000UL +#define FFB_DFB32_POFF 0x03000000UL +#define FFB_FBC_KREGS_POFF 0x00610000UL +#define FFB_DAC_POFF 0x00400000UL +#define FFB_PROM_POFF 0x00000000UL +#define FFB_EXP_POFF 0x00200000UL /* Draw operations */ #define FFB_DRAWOP_DOT 0x00 @@ -132,10 +134,18 @@ 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; @@ -275,7 +285,7 @@ static __inline__ void FFBFifo(struct fb_info_sbusfb *fb, int n) if (cache - n < 0) { fbc = fb->s.ffb.fbc; - do { cache = (fbc->ucsr & FFB_UCSR_FIFO_MASK) - 8; + do { cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK) - 8; } while (cache - n < 0); } fb->s.ffb.fifo_cache = cache - n; @@ -286,10 +296,11 @@ static __inline__ void FFBWait(struct ffb_fbc *ffb) int limit = 10000; do { - if((ffb->ucsr & FFB_UCSR_ALL_BUSY) == 0) + if ((upa_readl(&ffb->ucsr) & FFB_UCSR_ALL_BUSY) == 0) break; - if((ffb->ucsr & FFB_UCSR_ALL_ERRORS) != 0) - ffb->ucsr = FFB_UCSR_ALL_ERRORS; + if ((upa_readl(&ffb->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) { + upa_writel(FFB_UCSR_ALL_ERRORS, &ffb->ucsr); + } } while(--limit > 0); } @@ -333,13 +344,15 @@ 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; + unsigned long flags; u64 yx, hw; int fg; + spin_lock_irqsave(&fb->lock, flags); fg = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p,conp)]; if (fg != fb->s.ffb.fg_cache) { FFBFifo(fb, 5); - fbc->fg = fg; + upa_writel(fg, &fbc->fg); fb->s.ffb.fg_cache = fg; } else FFBFifo(fb, 4); @@ -354,40 +367,46 @@ static void ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx, } else { yx += sx * fontwidth(p); hw += width * fontwidth(p); } - *(volatile u64 *)&fbc->by = yx + fb->s.ffb.yx_margin; - *(volatile u64 *)&fbc->bh = hw; + upa_writeq(yx + fb->s.ffb.yx_margin, &fbc->by); + upa_writeq(hw, &fbc->bh); + spin_unlock_irqrestore(&fb->lock, flags); } 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; + unsigned long flags; int fg; + spin_lock_irqsave(&fb->lock, flags); fg = ((u32 *)p->dispsw_data)[attr_bgcol(p,s)]; if (fg != fb->s.ffb.fg_cache) { FFBFifo(fb, 1); - fbc->fg = fg; + upa_writel(fg, &fbc->fg); fb->s.ffb.fg_cache = fg; } while (count-- > 0) { FFBFifo(fb, 4); - fbc->by = boxes[1]; - fbc->bx = boxes[0]; - fbc->bh = boxes[3] - boxes[1]; - fbc->bw = boxes[2] - boxes[0]; + upa_writel(boxes[1], &fbc->by); + upa_writel(boxes[0], &fbc->bx); + upa_writel(boxes[3] - boxes[1], &fbc->bh); + upa_writel(boxes[2] - boxes[0], &fbc->bw); boxes += 4; } + spin_unlock_irqrestore(&fb->lock, flags); } static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx) { struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info; register struct ffb_fbc *fbc = fb->s.ffb.fbc; + unsigned long flags; int i, xy; u8 *fd; u64 fgbg; + spin_lock_irqsave(&fb->lock, flags); if (fontheightlog(p)) { xy = (yy << (16 + fontheightlog(p))); i = ((c & p->charmask) << fontheightlog(p)); @@ -407,21 +426,27 @@ static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int ((u32 *)p->dispsw_data)[attr_bgcol(p,c)]; if (fgbg != *(u64 *)&fb->s.ffb.fg_cache) { FFBFifo(fb, 2); - *(volatile u64 *)&fbc->fg = fgbg; + upa_writeq(fgbg, &fbc->fg); *(u64 *)&fb->s.ffb.fg_cache = fgbg; } FFBFifo(fb, 2 + fontheight(p)); - fbc->fontxy = xy; - fbc->fontw = fontwidth(p); + upa_writel(xy, &fbc->fontxy); + upa_writel(fontwidth(p), &fbc->fontw); if (fontwidth(p) <= 8) { - for (i = 0; i < fontheight(p); i++) - fbc->font = *fd++ << 24; + for (i = 0; i < fontheight(p); i++) { + u32 val = *fd++ << 24; + + upa_writel(val, &fbc->font); + } } else { for (i = 0; i < fontheight(p); i++) { - fbc->font = *(u16 *)fd << 16; + u32 val = *(u16 *)fd << 16; + + upa_writel(val, &fbc->font); fd += 2; } } + spin_unlock_irqrestore(&fb->lock, flags); } static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, @@ -429,15 +454,17 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh { struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info; register struct ffb_fbc *fbc = fb->s.ffb.fbc; + unsigned long flags; int i, xy; u8 *fd1, *fd2, *fd3, *fd4; u64 fgbg; + spin_lock_irqsave(&fb->lock, flags); 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; + upa_writeq(fgbg, &fbc->fg); *(u64 *)&fb->s.ffb.fg_cache = fgbg; } xy = fb->s.ffb.xy_margin; @@ -453,8 +480,8 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh while (count >= 4) { count -= 4; FFBFifo(fb, 2 + fontheight(p)); - fbc->fontw = 4 * fontwidth(p); - fbc->fontxy = xy; + upa_writel(4 * fontwidth(p), &fbc->fontw); + upa_writel(xy, &fbc->fontxy); if (fontheightlog(p)) { fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p)); fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p)); @@ -467,14 +494,20 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p)); } if (fontwidth(p) == 8) { - for (i = 0; i < fontheight(p); i++) - fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) + for (i = 0; i < fontheight(p); i++) { + u32 val; + + val = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8); + upa_writel(val, &fbc->font); + } xy += 32; } else { - for (i = 0; i < fontheight(p); i++) - fbc->font = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) + for (i = 0; i < fontheight(p); i++) { + u32 val = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << fontwidth(p))) << fontwidth(p))) << fontwidth(p))) << (24 - 3 * fontwidth(p)); + upa_writel(val, &fbc->font); + } xy += 4 * fontwidth(p); } } @@ -482,8 +515,8 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh while (count >= 2) { count -= 2; FFBFifo(fb, 2 + fontheight(p)); - fbc->fontw = 2 * fontwidth(p); - fbc->fontxy = xy; + upa_writel(2 * fontwidth(p), &fbc->fontw); + upa_writel(xy, &fbc->fontxy); if (fontheightlog(p)) { fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1)); fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1)); @@ -492,7 +525,9 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1); } for (i = 0; i < fontheight(p); i++) { - fbc->font = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p)); + u32 val = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p)); + + upa_writel(val, &fbc->font); fd1 += 2; fd2 += 2; } xy += 2 * fontwidth(p); @@ -501,25 +536,31 @@ static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned sh while (count) { count--; FFBFifo(fb, 2 + fontheight(p)); - fbc->fontw = fontwidth(p); - fbc->fontxy = xy; + upa_writel(fontwidth(p), &fbc->fontw); + upa_writel(xy, &fbc->fontxy); if (fontheightlog(p)) i = ((scr_readw(s++) & p->charmask) << fontheightlog(p)); else i = ((scr_readw(s++) & p->charmask) * fontheight(p)); if (fontwidth(p) <= 8) { fd1 = p->fontdata + i; - for (i = 0; i < fontheight(p); i++) - fbc->font = *fd1++ << 24; + for (i = 0; i < fontheight(p); i++) { + u32 val = *fd1++ << 24; + + upa_writel(val, &fbc->font); + } } else { fd1 = p->fontdata + (i << 1); for (i = 0; i < fontheight(p); i++) { - fbc->font = *(u16 *)fd1 << 16; + u32 val = *(u16 *)fd1 << 16; + + upa_writel(val, &fbc->font); fd1 += 2; } } xy += fontwidth(p); } + spin_unlock_irqrestore(&fb->lock, flags); } static void ffb_revc(struct display *p, int xx, int yy) @@ -527,23 +568,61 @@ static void ffb_revc(struct display *p, int xx, int yy) /* Not used if hw cursor */ } +#if 0 +static void ffb_blank(struct fb_info_sbusfb *fb) +{ + struct ffb_dac *dac = fb->s.ffb.dac; + unsigned long flags; + u32 tmp; + + spin_lock_irqsave(&fb->lock, flags); + upa_writel(0x6000, &dac->type); + tmp = (upa_readl(&dac->value) & ~0x1); + upa_writel(0x6000, &dac->type); + upa_writel(tmp, &dac->value); + spin_unlock_irqrestore(&fb->lock, flags); +} +#endif + +static void ffb_unblank(struct fb_info_sbusfb *fb) +{ + struct ffb_dac *dac = fb->s.ffb.dac; + unsigned long flags; + u32 tmp; + + spin_lock_irqsave(&fb->lock, flags); + upa_writel(0x6000, &dac->type); + tmp = (upa_readl(&dac->value) | 0x1); + upa_writel(0x6000, &dac->type); + upa_writel(tmp, &dac->value); + spin_unlock_irqrestore(&fb->lock, flags); +} + static void ffb_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count) { struct ffb_dac *dac = fb->s.ffb.dac; + unsigned long flags; int i, j = count; - dac->type = 0x2000 | index; - for (i = index; j--; i++) + spin_lock_irqsave(&fb->lock, flags); + upa_writel(0x2000 | index, &dac->type); + for (i = index; j--; i++) { + u32 val; + /* Feed the colors in :)) */ - dac->value = ((fb->color_map CM(i,0))) | - ((fb->color_map CM(i,1)) << 8) | - ((fb->color_map CM(i,2)) << 16); + val = ((fb->color_map CM(i,0))) | + ((fb->color_map CM(i,1)) << 8) | + ((fb->color_map CM(i,2)) << 16); + upa_writel(val, &dac->value); + } if (!p) - return; + goto out; for (i = index, j = count; i < 16 && j--; i++) ((u32 *)p->dispsw_data)[i] = ((fb->color_map CM(i,0))) | ((fb->color_map CM(i,1)) << 8) | ((fb->color_map CM(i,2)) << 16); +out: + spin_unlock_irqrestore(&fb->lock, flags); } static struct display_switch ffb_dispsw __initdata = { @@ -554,53 +633,67 @@ 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; + unsigned long flags; + spin_lock_irqsave(&fb->lock, flags); 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); + spin_unlock_irqrestore(&fb->lock, flags); } -static inline void ffb_curs_enable (struct fb_info_sbusfb *fb, int enable) +static __inline__ void __ffb_curs_enable (struct fb_info_sbusfb *fb, int enable) { struct ffb_dac *dac = fb->s.ffb.dac; - - dac->type2 = 0x100; - if (fb->s.ffb.dac_rev <= 2) - dac->value2 = enable ? 3 : 0; - else - dac->value2 = enable ? 0 : 3; + u32 val; + + upa_writel(0x100, &dac->type2); + if (fb->s.ffb.dac_rev <= 2) { + val = enable ? 3 : 0; + } else { + val = enable ? 0 : 3; + } + upa_writel(val, &dac->value2); } static void ffb_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue) { struct ffb_dac *dac = fb->s.ffb.dac; + unsigned long flags; - ffb_curs_enable (fb, 0); - dac->type2 = 0x102; - dac->value2 = (red[0] | (green[0]<<8) | (blue[0]<<16)); - dac->value2 = (red[1] | (green[1]<<8) | (blue[1]<<16)); + spin_lock_irqsave(&fb->lock, flags); + __ffb_curs_enable (fb, 0); + upa_writel(0x102, &dac->type2); + upa_writel((red[0] | (green[0]<<8) | (blue[0]<<16)), &dac->value2); + upa_writel((red[1] | (green[1]<<8) | (blue[1]<<16)), &dac->value2); + spin_unlock_irqrestore(&fb->lock, flags); } /* Set cursor shape */ static void ffb_setcurshape (struct fb_info_sbusfb *fb) { struct ffb_dac *dac = fb->s.ffb.dac; + unsigned long flags; int i, j; - ffb_curs_enable (fb, 0); + spin_lock_irqsave(&fb->lock, flags); + __ffb_curs_enable (fb, 0); for (j = 0; j < 2; j++) { - dac->type2 = j ? 0 : 0x80; + u32 val = j ? 0 : 0x80; + + upa_writel(val, &dac->type2); for (i = 0; i < 0x40; i++) { if (fb->cursor.size.fbx <= 32) { - dac->value2 = fb->cursor.bits [j][i]; - dac->value2 = 0; + upa_writel(fb->cursor.bits [j][i], &dac->value2); + upa_writel(0, &dac->value2); } else { - dac->value2 = fb->cursor.bits [j][2*i]; - dac->value2 = fb->cursor.bits [j][2*i+1]; + upa_writel(fb->cursor.bits [j][2*i], &dac->value2); + upa_writel(fb->cursor.bits [j][2*i+1], &dac->value2); } } } + spin_unlock_irqrestore(&fb->lock, flags); } /* Load cursor information */ @@ -608,31 +701,41 @@ static void ffb_setcursor (struct fb_info_sbusfb *fb) { struct ffb_dac *dac = fb->s.ffb.dac; struct cg_cursor *c = &fb->cursor; + unsigned long flags; + u32 val; - dac->type2 = 0x104; + spin_lock_irqsave(&fb->lock, flags); + upa_writel(0x104, &dac->type2); /* Should this be just 0x7ff?? Should I do some margin handling and setcurshape in that case? */ - dac->value2 = (((c->cpos.fby - c->chot.fby) & 0xffff) << 16) - |((c->cpos.fbx - c->chot.fbx) & 0xffff); - ffb_curs_enable (fb, fb->cursor.enable); + val = (((c->cpos.fby - c->chot.fby) & 0xffff) << 16) + |((c->cpos.fbx - c->chot.fbx) & 0xffff); + upa_writel(val, &dac->value2); + __ffb_curs_enable (fb, fb->cursor.enable); + spin_unlock_irqrestore(&fb->lock, flags); } static void ffb_switch_from_graph (struct fb_info_sbusfb *fb) { register struct ffb_fbc *fbc = fb->s.ffb.fbc; + unsigned long flags; + spin_lock_irqsave(&fb->lock, flags); FFBWait(fbc); 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; + upa_writel(FFB_PPC_VCE_DISABLE|FFB_PPC_TBE_OPAQUE| + FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST, + &fbc->ppc); + upa_writel(0x2000707f, &fbc->fbc); + upa_writel(FFB_ROP_NEW, &fbc->rop); + upa_writel(FFB_DRAWOP_RECTANGLE, &fbc->drawop); + upa_writel(0xffffffff, &fbc->pmask); + upa_writel(0x10000, &fbc->fontinc); + upa_writel(fb->s.ffb.fg_cache, &fbc->fg); + upa_writel(fb->s.ffb.bg_cache, &fbc->bg); FFBWait(fbc); + spin_unlock_irqrestore(&fb->lock, flags); } static int __init ffb_rasterimg (struct fb_info *info, int start) @@ -659,12 +762,15 @@ char __init *creatorfb_init(struct fb_info_sbusfb *fb) return NULL; disp->dispsw_data = (void *)kmalloc(16 * sizeof(u32), GFP_KERNEL); - if (!disp->dispsw_data) + if (disp->dispsw_data == NULL) return NULL; memset(disp->dispsw_data, 0, 16 * sizeof(u32)); fbops = kmalloc(sizeof(*fbops), GFP_KERNEL); - if (!fbops) return NULL; + if (fbops == NULL) { + kfree(disp->dispsw_data); + return NULL; + } *fbops = *fb->info.fbops; fbops->fb_rasterimg = ffb_rasterimg; @@ -698,8 +804,8 @@ char __init *creatorfb_init(struct fb_info_sbusfb *fb) 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->s.ffb.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF); + fb->s.ffb.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF); fb->dispsw = ffb_dispsw; fb->margins = ffb_margins; @@ -709,12 +815,22 @@ char __init *creatorfb_init(struct fb_info_sbusfb *fb) fb->setcurshape = ffb_setcurshape; fb->switch_from_graph = ffb_switch_from_graph; fb->fill = ffb_fill; +#if 0 + /* XXX Can't enable this for now, I've seen cases + * XXX where the VC was blanked, and Xsun24 was started + * XXX via a remote login, the sunfb code did not + * XXX unblank creator when it was mmap'd for some + * XXX reason, investigate later... -DaveM + */ + fb->blank = ffb_blank; + fb->unblank = ffb_unblank; +#endif /* If there are any read errors or fifo overflow conditions, * clear them now. */ - if((fb->s.ffb.fbc->ucsr & FFB_UCSR_ALL_ERRORS) != 0) - fb->s.ffb.fbc->ucsr = FFB_UCSR_ALL_ERRORS; + if((upa_readl(&fb->s.ffb.fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0) + upa_writel(FFB_UCSR_ALL_ERRORS, &fb->s.ffb.fbc->ucsr); ffb_switch_from_graph(fb); @@ -726,17 +842,25 @@ char __init *creatorfb_init(struct fb_info_sbusfb *fb) type->fb_depth = 24; - fb->s.ffb.dac->type = 0x8000; - fb->s.ffb.dac_rev = (fb->s.ffb.dac->value >> 0x1c); + upa_writel(0x8000, &fb->s.ffb.dac->type); + fb->s.ffb.dac_rev = (upa_readl(&fb->s.ffb.dac->value) >> 0x1c); i = prom_getintdefault (fb->prom_node, "board_type", 8); - - sprintf(idstring, "%s at %016lx type %d DAC %d", fix->id, regs[0].phys_addr, i, fb->s.ffb.dac_rev); + + 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; + /* Unblank it just to be sure. When there are multiple + * FFB/AFB cards in the system, or it is not the OBP + * chosen console, it will have video outputs off in + * the DAC. + */ + ffb_unblank(fb); + return idstring; } |