patch-2.1.110 linux/drivers/video/cgsixfb.c
Next file: linux/drivers/video/chipsfb.c
Previous file: linux/drivers/video/atyfb.c
Back to the patch index
Back to the overall index
- Lines: 396
- Date:
Sat Jul 18 13:55:46 1998
- Orig file:
v2.1.109/linux/drivers/video/cgsixfb.c
- Orig date:
Thu Jul 16 18:09:27 1998
diff -u --recursive --new-file v2.1.109/linux/drivers/video/cgsixfb.c linux/drivers/video/cgsixfb.c
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.1 1998/07/06 15:51:09 jj Exp $
+/* $Id: cgsixfb.c,v 1.2 1998/07/13 12:47:14 jj Exp $
* cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
*
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -226,37 +226,6 @@
p->next_plane = 0;
}
-static void cg6_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
-{
-#if 0
- int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
- u8 *src, *dst;
-
- if (sx == 0 && dx == 0 && width * 32 == bytes)
- mymemmove(p->screen_base + dy * linesize,
- p->screen_base + sy * linesize,
- height * linesize);
- else if (dy < sy || (dy == sy && dx < sx)) {
- src = p->screen_base + sy * linesize + sx * 32;
- dst = p->screen_base + dy * linesize + dx * 32;
- for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 32);
- src += bytes;
- dst += bytes;
- }
- } else {
- src = p->screen_base + (sy+height) * linesize + sx * 32 - bytes;
- dst = p->screen_base + (dy+height) * linesize + dx * 32 - bytes;
- for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 32);
- src -= bytes;
- dst -= bytes;
- }
- }
-#endif
-}
-
static void cg6_clear(struct vc_data *conp, struct display *p, int sy, int sx,
int height, int width)
{
@@ -310,113 +279,160 @@
static void cg6_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
{
-#if 0
struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
register struct cg6_fbc *fbc = fb->s.cg6.fbc;
- int i, xy;
+ int i, x, y;
u8 *fd;
- if (p->fontheight == 16) {
- xy = (yy << (16 + 4));
- fd = p->fontdata + ((c & 0xff) << 4);
+ if (p->fontheightlog) {
+ y = fb->y_margin + (yy << p->fontheightlog);
+ i = ((c & 0xff) << p->fontheightlog);
} else {
- xy = ((yy * p->fontheight) << 16);
- fd = p->fontdata + (c & 0xff) * p->fontheight;
+ y = fb->y_margin + (yy * p->fontheight);
+ i = (c & 0xff) * p->fontheight;
+ }
+ if (p->fontwidth <= 8)
+ fd = p->fontdata + i;
+ else
+ fd = p->fontdata + (i << 1);
+ if (p->fontwidthlog)
+ x = fb->x_margin + (xx << p->fontwidthlog);
+ else
+ x = fb->x_margin + (xx * p->fontwidth);
+ do {
+ i = fbc->s;
+ } while (i & 0x10000000);
+ fbc->fg = attr_fg_col(c);
+ fbc->bg = attr_bg_col(c);
+ fbc->mode = 0x140000;
+ fbc->alu = 0xe880fc30;
+ fbc->pixelm = ~(0);
+ fbc->s = 0;
+ fbc->clip = 0;
+ fbc->pm = 0xff;
+ fbc->incx = 0;
+ fbc->incy = 1;
+ fbc->x0 = x;
+ fbc->x1 = x + p->fontwidth - 1;
+ fbc->y0 = y;
+ if (p->fontwidth <= 8) {
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = *fd++ << 24;
+ } else {
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = *(u16 *)fd << 16;
+ fd += 2;
+ }
}
- xy += (xx << 3) + fb->s.cg6.xy_margin;
- fbc->ppc = 0x203;
- fbc->fg = cg6_cmap[attr_fg_col(c)];
- fbc->fbc = 0x2000707f;
- fbc->rop = 0x83;
- fbc->pmask = 0xffffffff;
- fbc->bg = cg6_cmap[attr_bg_col(c)];
- fbc->fontw = 8;
- fbc->fontinc = 0x10000;
- fbc->fontxy = xy;
- for (i = 0; i < p->fontheight; i++)
- fbc->font = *fd++ << 24;
-#endif
}
static void cg6_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
int count, int yy, int xx)
{
-#if 0
struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
register struct cg6_fbc *fbc = fb->s.cg6.fbc;
- int i, xy;
+ int i, x, y;
u8 *fd1, *fd2, *fd3, *fd4;
- fbc->ppc = 0x203;
- fbc->fg = cg6_cmap[attr_fg_col(*s)];
- fbc->fbc = 0x2000707f;
- fbc->rop = 0x83;
- fbc->pmask = 0xffffffff;
- fbc->bg = cg6_cmap[attr_bg_col(*s)];
- if (p->fontheight == 16) {
- xy = (yy << (16 + 4)) + (xx << 3) + fb->s.cg6.xy_margin;
+ do {
+ i = fbc->s;
+ } while (i & 0x10000000);
+ fbc->fg = attr_fg_col(*s);
+ fbc->bg = attr_bg_col(*s);
+ fbc->mode = 0x140000;
+ fbc->alu = 0xe880fc30;
+ fbc->pixelm = ~(0);
+ fbc->s = 0;
+ fbc->clip = 0;
+ fbc->pm = 0xff;
+ x = fb->x_margin;
+ y = fb->y_margin;
+ if (p->fontwidthlog)
+ x += (xx << p->fontwidthlog);
+ else
+ x += xx * p->fontwidth;
+ if (p->fontheightlog)
+ y += (yy << p->fontheightlog);
+ else
+ y += (yy * p->fontheight);
+ if (p->fontwidth <= 8) {
while (count >= 4) {
count -= 4;
- fbc->fontw = 32;
- fbc->fontinc = 0x10000;
- fbc->fontxy = xy;
- fd1 = p->fontdata + ((*s++ & 0xff) << 4);
- fd2 = p->fontdata + ((*s++ & 0xff) << 4);
- fd3 = p->fontdata + ((*s++ & 0xff) << 4);
- fd4 = p->fontdata + ((*s++ & 0xff) << 4);
- for (i = 0; i < 16; i++)
- fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8);
- xy += 32;
- }
- while (count) {
- count--;
- fbc->fontw = 8;
- fbc->fontinc = 0x10000;
- fbc->fontxy = xy;
- fd1 = p->fontdata + ((*s++ & 0xff) << 4);
- for (i = 0; i < 16; i++)
- fbc->font = *fd1++ << 24;
- xy += 8;
+ fbc->incx = 0;
+ fbc->incy = 1;
+ fbc->x0 = x;
+ fbc->x1 = (x += 4 * p->fontwidth) - 1;
+ fbc->y0 = y;
+ if (p->fontheightlog) {
+ fd1 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+ fd2 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+ fd3 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+ fd4 = p->fontdata + ((*s++ & 0xff) << p->fontheightlog);
+ } else {
+ fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+ fd2 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+ fd3 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+ fd4 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
+ }
+ if (p->fontwidth == 8) {
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++)
+ << 8)) << 8)) << 8);
+ } else {
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++)
+ << p->fontwidth)) << p->fontwidth)) << p->fontwidth)) << (24 - 3 * p->fontwidth);
+ }
}
} else {
- xy = ((yy * p->fontheight) << 16) + (xx << 3) + fb->s.cg6.xy_margin;
- while (count >= 4) {
- count -= 4;
- fbc->fontw = 32;
- fbc->fontinc = 0x10000;
- fbc->fontxy = xy;
- fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
- fd2 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
- fd3 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
- fd4 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
- for (i = 0; i < p->fontheight; i++)
- fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) << 8)) << 8)) << 8);
- xy += 32;
+ while (count >= 2) {
+ count -= 2;
+ fbc->incx = 0;
+ fbc->incy = 1;
+ fbc->x0 = x;
+ fbc->x1 = (x += 2 * p->fontwidth) - 1;
+ fbc->y0 = y;
+ if (p->fontheightlog) {
+ fd1 = p->fontdata + ((*s++ & 0xff) << (p->fontheightlog + 1));
+ fd2 = p->fontdata + ((*s++ & 0xff) << (p->fontheightlog + 1));
+ } else {
+ fd1 = p->fontdata + (((*s++ & 0xff) * p->fontheight) << 1);
+ fd2 = p->fontdata + (((*s++ & 0xff) * p->fontheight) << 1);
+ }
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = ((((u32)*(u16 *)fd1) << p->fontwidth) | ((u32)*(u16 *)fd2)) << (16 - p->fontwidth);
+ fd1 += 2; fd2 += 2;
+ }
}
- while (count) {
- count--;
- fbc->fontw = 8;
- fbc->fontinc = 0x10000;
- fbc->fontxy = xy;
- fd1 = p->fontdata + ((*s++ & 0xff) * p->fontheight);
- for (i = 0; i < 16; i++)
+ }
+ while (count) {
+ count--;
+ fbc->incx = 0;
+ fbc->incy = 1;
+ fbc->x0 = x;
+ fbc->x1 = (x += p->fontwidth) - 1;
+ fbc->y0 = y;
+ if (p->fontheightlog)
+ i = ((*s++ & 0xff) << p->fontheightlog);
+ else
+ i = ((*s++ & 0xff) * p->fontheight);
+ if (p->fontwidth <= 8) {
+ fd1 = p->fontdata + i;
+ for (i = 0; i < p->fontheight; i++)
fbc->font = *fd1++ << 24;
- xy += 8;
+ } else {
+ fd1 = p->fontdata + (i << 1);
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = *(u16 *)fd1 << 16;
+ fd1 += 2;
+ }
}
}
-#endif
}
static void cg6_revc(struct display *p, int xx, int yy)
{
- u8 *dest;
- int bytes=p->next_line, rows;
-
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
- for (rows = p->fontheight ; rows-- ; dest += bytes) {
- ((u32 *)dest)[0] ^= 0x0f0f0f0f;
- ((u32 *)dest)[1] ^= 0x0f0f0f0f;
- }
+ /* Not used if hw cursor */
}
static void cg6_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
@@ -433,7 +449,8 @@
}
static struct display_switch cg6_dispsw __initdata = {
- cg6_setup, cg6_bmove, cg6_clear, cg6_putc, cg6_putcs, cg6_revc, NULL
+ cg6_setup, fbcon_redraw_bmove, cg6_clear, cg6_putc, cg6_putcs, cg6_revc,
+ NULL, NULL, FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
};
static void cg6_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
@@ -477,6 +494,63 @@
fb->s.cg6.thc->thc_cursxy = v;
}
+static void cg6_blank (struct fb_info_sbusfb *fb)
+{
+ fb->s.cg6.thc->thc_misc &= ~CG6_THC_MISC_VIDEO;
+}
+
+static void cg6_unblank (struct fb_info_sbusfb *fb)
+{
+ fb->s.cg6.thc->thc_misc |= CG6_THC_MISC_VIDEO;
+}
+
+static void cg6_reset (struct fb_info_sbusfb *fb)
+{
+ unsigned int rev, conf;
+
+ /* Turn off stuff in the Transform Engine. */
+ fb->s.cg6.tec->tec_matrix = 0;
+ fb->s.cg6.tec->tec_clip = 0;
+ fb->s.cg6.tec->tec_vdc = 0;
+
+ /* Take care of bugs in old revisions. */
+ rev = (*(fb->s.cg6.fhc) >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK;
+ if (rev < 5) {
+ conf = (*(fb->s.cg6.fhc) & CG6_FHC_RES_MASK) |
+ CG6_FHC_CPU_68020 | CG6_FHC_TEST |
+ (11 << CG6_FHC_TEST_X_SHIFT) |
+ (11 << CG6_FHC_TEST_Y_SHIFT);
+ if (rev < 2)
+ conf |= CG6_FHC_DST_DISABLE;
+ *(fb->s.cg6.fhc) = conf;
+ }
+
+ /* Set things in the FBC. */
+ fb->s.cg6.fbc->mode &= ~(CG6_FBC_BLIT_MASK | CG6_FBC_MODE_MASK |
+ CG6_FBC_DRAW_MASK | CG6_FBC_BWRITE0_MASK |
+ CG6_FBC_BWRITE1_MASK | CG6_FBC_BREAD_MASK |
+ CG6_FBC_BDISP_MASK);
+ fb->s.cg6.fbc->mode |= (CG6_FBC_BLIT_SRC | CG6_FBC_MODE_COLOR8 |
+ CG6_FBC_DRAW_RENDER | CG6_FBC_BWRITE0_ENABLE |
+ CG6_FBC_BWRITE1_DISABLE | CG6_FBC_BREAD_0 |
+ CG6_FBC_BDISP_0);
+ fb->s.cg6.fbc->clip = 0;
+ fb->s.cg6.fbc->offx = 0;
+ fb->s.cg6.fbc->offy = 0;
+ fb->s.cg6.fbc->clipminx = 0;
+ fb->s.cg6.fbc->clipminy = 0;
+ fb->s.cg6.fbc->clipmaxx = fb->type.fb_width - 1;
+ fb->s.cg6.fbc->clipmaxy = fb->type.fb_height - 1;
+ /* Enable cursor in Brooktree DAC. */
+ fb->s.cg6.bt->addr = 0x06 << 24;
+ fb->s.cg6.bt->control |= 0x03 << 24;
+}
+
+static void cg6_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
+{
+ p->screen_base += (y_margin - fb->y_margin) * p->line_length + (x_margin - fb->x_margin);
+}
+
static char idstring[60] __initdata = { 0 };
__initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
@@ -504,8 +578,10 @@
disp->screen_base = (char *)sparc_alloc_io(phys + CG6_RAM_OFFSET, 0,
type->fb_size, "cgsix_ram", fb->iospace, 0);
disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
- fb->s.cg6.fbc = (struct cg6_fbc *)(char *)sparc_alloc_io(phys + CG6_FBC_OFFSET, 0,
+ fb->s.cg6.fbc = (struct cg6_fbc *)sparc_alloc_io(phys + CG6_FBC_OFFSET, 0,
4096, "cgsix_fbc", fb->iospace, 0);
+ fb->s.cg6.tec = (struct cg6_tec *)sparc_alloc_io(phys + CG6_TEC_OFFSET, 0,
+ sizeof(struct cg6_tec), "cgsix_tec", fb->iospace, 0);
fb->s.cg6.thc = (struct cg6_thc *)sparc_alloc_io(phys + CG6_THC_OFFSET, 0,
sizeof(struct cg6_thc), "cgsix_thc", fb->iospace, 0);
fb->s.cg6.bt = (struct bt_regs *)sparc_alloc_io(phys + CG6_BROOKTREE_OFFSET, 0,
@@ -514,11 +590,15 @@
sizeof(u32), "cgsix_fhc", fb->iospace, 0);
fb->dispsw = cg6_dispsw;
+ fb->margins = cg6_margins;
fb->loadcmap = cg6_loadcmap;
fb->setcursor = cg6_setcursor;
fb->setcursormap = cg6_setcursormap;
fb->setcurshape = cg6_setcurshape;
fb->fill = cg6_fill;
+ fb->blank = cg6_blank;
+ fb->unblank = cg6_unblank;
+ fb->reset = cg6_reset;
fb->physbase = phys;
fb->mmap_map = cg6_mmap_map;
@@ -543,6 +623,8 @@
sprintf(idstring, "cgsix at %02x.%08lx TEC Rev %x CPU %s Rev %x", fb->iospace, phys,
(fb->s.cg6.thc->thc_misc >> CG6_THC_MISC_REV_SHIFT) & CG6_THC_MISC_REV_MASK,
p, conf >> CG6_FHC_REV_SHIFT & CG6_FHC_REV_MASK);
+
+ cg6_reset(fb);
return idstring;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov