patch-2.2.3 linux/drivers/video/virgefb.c
Next file: linux/fs/Config.in
Previous file: linux/drivers/video/vesafb.c
Back to the patch index
Back to the overall index
- Lines: 574
- Date:
Thu Feb 25 10:02:11 1999
- Orig file:
v2.2.2/linux/drivers/video/virgefb.c
- Orig date:
Wed Jan 20 23:14:06 1999
diff -u --recursive --new-file v2.2.2/linux/drivers/video/virgefb.c linux/drivers/video/virgefb.c
@@ -89,11 +89,6 @@
#define rl_3d(reg) \
(*((unsigned long volatile *)(CyberRegs + reg)))
-
-
-
-
-
struct virgefb_par {
int xres;
int yres;
@@ -109,6 +104,11 @@
static struct display disp;
static struct fb_info fb_info;
+static union {
+#ifdef FBCON_HAS_CFB16
+ u16 cfb16[16];
+#endif
+} fbcon_cmap;
/*
* Switch for Chipset Independency
@@ -132,6 +132,7 @@
void (*blank)(int blank);
} *fbhw;
+static int blit_maybe_busy = 0;
/*
* Frame Buffer Name
@@ -148,7 +149,7 @@
#define VIRGE8_HEIGHT 886
#define VIRGE8_PIXCLOCK 12500 /* ++Geert: Just a guess */
-#if 0
+#if 1
#define VIRGE16_WIDTH 800
#define VIRGE16_HEIGHT 600
#endif
@@ -167,6 +168,8 @@
static unsigned long Cyber_vcode_switch_base;
static unsigned char cv3d_on_zorro2;
+#define CYBMEM_OFFSET_8 0x800000 /* offsets from start of video - */
+#define CYBMEM_OFFSET_16 0x400000 /* ram to appropriate aperture */
/*
* Predefined Video Modes
@@ -216,10 +219,17 @@
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
+ "640x480-16", { /* Cybervision 16 bpp */
+ 640, 480, 640, 480, 0, 0, 16, 0,
+ {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }
+ }, {
"800x600-16", { /* Cybervision 16 bpp */
800, 600, 800, 600, 0, 0, 16, 0,
{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
@@ -229,6 +239,27 @@
0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
+ }, {
+ "1152x886-16", { /* Cybervision 16 bpp */
+ 1152, 886, 1152, 886, 0, 0, 16, 0,
+ {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }
+ }, {
+ "1280x1024-16", { /* Cybervision 16 bpp */
+ 1280, 1024, 1280, 1024, 0, 0, 16, 0,
+ {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }
+ }, {
+ "1600x1200-16", { /* Cybervision 16 bpp */
+ 1600, 1200, 1600, 1200, 0, 0, 16, 0,
+ {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }
}
};
@@ -246,8 +277,8 @@
* Some default modes
*/
-#define VIRGE8_DEFMODE (0)
-#define VIRGE16_DEFMODE (6)
+#define VIRGE8_DEFMODE (1)
+#define VIRGE16_DEFMODE (7)
static struct fb_var_screeninfo virgefb_default;
@@ -294,6 +325,9 @@
static struct display_switch fbcon_virge8;
#endif
+#ifdef FBCON_HAS_CFB16
+static struct display_switch fbcon_virge16;
+#endif
/*
* Hardware Specific Routines
@@ -353,15 +387,14 @@
* (the 3D penguin might need texture memory :-) )
*/
- memset ((char*)CyberMem, 0, 1600 * 1200);
-
- /* Disable hardware cursor */
if (cv3d_on_zorro2) {
CyberSize = 0x00380000; /* 3.5 MB , we need some space for the registers? */
} else {
CyberSize = 0x00400000; /* 4 MB */
}
+ memset ((char*)CyberMem, 0, CyberSize);
+ /* Disable hardware cursor */
vgawb_3d(0x3c8, 255);
vgawb_3d(0x3c9, 56);
vgawb_3d(0x3c9, 100);
@@ -396,7 +429,18 @@
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, virgefb_name);
- fix->smem_start = (char*) CyberMem_phys;
+ if (cv3d_on_zorro2) {
+ fix->smem_start = (char*) CyberMem_phys;
+ } else {
+ switch (par->bpp) {
+ case 8:
+ fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_8);
+ break;
+ case 16:
+ fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_16);
+ break;
+ }
+ }
fix->smem_len = CyberSize;
fix->mmio_start = (char*) CyberRegs_phys;
fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
@@ -467,24 +511,27 @@
var->bits_per_pixel = par->bpp;
var->grayscale = 0;
- if (par->bpp == 8) {
- var->red.offset = 0;
- var->red.length = 6;
- var->red.msb_right = 0;
- var->blue = var->green = var->red;
- } else {
- var->red.offset = 11;
- var->red.length = 5;
- var->red.msb_right = 0;
- var->green.offset = 5;
- var->green.length = 6;
- var->green.msb_right = 0;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->blue.msb_right = 0;
- }
- var->transp.offset = 0;
- var->transp.length = 0;
+ switch (var->bits_per_pixel) {
+ case 8: /* CLUT */
+ var->red.offset = 0;
+ var->red.length = 6;
+ var->red.msb_right = 0;
+ var->blue = var->green = var->red;
+ break;
+ case 16: /* RGB 565 */
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ }
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
var->transp.msb_right = 0;
var->nonstd = 0;
@@ -493,8 +540,10 @@
var->height = -1;
var->width = -1;
- var->accel_flags = (par->accel && par->bpp == 8) ? FB_ACCELF_TEXT : 0;
- DPRINTK("accel CV64/3D\n");
+ var->accel_flags = (par->accel &&
+ ((par->bpp == 8) || (par->bpp == 16))) ? FB_ACCELF_TEXT : 0;
+
+/* printk("CV64/3D : %s\n",(var->accel_flags ? "accel" : "no accel")); */
var->vmode = FB_VMODE_NONINTERLACED;
@@ -525,28 +574,34 @@
static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{
- if (regno > 255)
- {
- return (1);
- }
-
- /*
- * No colors on the CV3D yet.
- */
+ if (((current_par.bpp==8) && (regno>255)) ||
+ ((current_par.bpp!=8) && (regno>15)))
+ return (1);
- vgawb_3d(0x3c8, (unsigned char) regno);
- red >>= 10;
- green >>= 10;
- blue >>= 10;
-
- Cyber_colour_table [regno][0] = red;
- Cyber_colour_table [regno][1] = green;
- Cyber_colour_table [regno][2] = blue;
-
- vgawb_3d(0x3c9, red);
- vgawb_3d(0x3c9, green);
- vgawb_3d(0x3c9, blue);
+ if (((current_par.bpp==8) && (regno<256)) || ((current_par.bpp==16) &&(regno<16))) {
+ Cyber_colour_table [regno][0] = red >> 10;
+ Cyber_colour_table [regno][1] = green >> 10;
+ Cyber_colour_table [regno][2] = blue >> 10;
+ }
+ switch (current_par.bpp) {
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ vgawb_3d(0x3c8, (unsigned char) regno);
+ vgawb_3d(0x3c9, ((unsigned char) (red >> 10)));
+ vgawb_3d(0x3c9, ((unsigned char) (green >> 10)));
+ vgawb_3d(0x3c9, ((unsigned char) (blue >> 10)));
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ fbcon_cmap.cfb16[regno] =
+ ((red & 0xf800) |
+ ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11));
+ break;
+#endif
+ }
return (0);
}
@@ -561,14 +616,18 @@
{
int t;
- if (regno >= 256)
+ if (regno > 255)
return (1);
- t = Cyber_colour_table [regno][0];
- *red = (t<<10) | (t<<4) | (t>>2);
- t = Cyber_colour_table [regno][1];
- *green = (t<<10) | (t<<4) | (t>>2);
- t = Cyber_colour_table [regno][2];
- *blue = (t<<10) | (t<<4) | (t>>2);
+
+ if (((current_par.bpp==8) && (regno<256)) || ((current_par.bpp==16) && (regno<16))) {
+
+ t = Cyber_colour_table [regno][0];
+ *red = (t<<10) | (t<<4) | (t>>2);
+ t = Cyber_colour_table [regno][1];
+ *green = (t<<10) | (t<<4) | (t>>2);
+ t = Cyber_colour_table [regno][2];
+ *blue = (t<<10) | (t<<4) | (t>>2);
+ }
*transp = 0;
return (0);
}
@@ -615,8 +674,10 @@
unsigned long status;
do {
+ mb();
status = rl_3d(0x8504);
} while (!(status & (1 << 13)));
+ blit_maybe_busy = 0;
}
#define S3V_BITBLT (0x0 << 27)
@@ -666,6 +727,10 @@
desty += (height - 1);
}
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ blit_maybe_busy = 1;
+
wl_3d(0xa4f4, 1); /* pattern fb color */
wl_3d(0xa4e8, ~0); /* mono pat 0 */
@@ -676,8 +741,6 @@
wl_3d(0xa50c, ((destx << 16) | desty)); /* rdest_xy */
wl_3d(0xa500, blitcmd); /* GO! */
-
- Cyber3D_WaitBusy();
}
/*
@@ -691,6 +754,10 @@
unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW | S3V_DST_8BPP |
S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25);
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ blit_maybe_busy = 1;
+
tmp = color & 0xff;
wl_3d(0xa4f4, tmp);
@@ -698,19 +765,20 @@
wl_3d(0xa50c, ((x << 16) | y)); /* rdest_xy */
wl_3d(0xa500, blitcmd); /* GO! */
- Cyber3D_WaitBusy();
}
/**************************************************************
* Move cursor to x, y
*/
+
+#if 0
static void Cyber_MoveCursor (u_short x, u_short y)
{
printk("Yuck .... MoveCursor on a 3D\n");
return;
}
-
+#endif
/* -------------------- Interfaces to hardware functions -------------------- */
@@ -868,7 +936,18 @@
virgefb_get_fix(&fix, con, info);
if (con == -1)
con = 0;
- display->screen_base = (char*) CyberMem;
+ if (cv3d_on_zorro2) {
+ display->screen_base = (char*) CyberMem;
+ } else {
+ switch (display->var.bits_per_pixel) {
+ case 8:
+ display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_8);
+ break;
+ case 16:
+ display->screen_base = (char*) (CyberMem + CYBMEM_OFFSET_16);
+ break;
+ }
+ }
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -878,22 +957,26 @@
display->inverse = Cyberfb_inverse;
switch (display->var.bits_per_pixel) {
#ifdef FBCON_HAS_CFB8
- case 8:
- if (display->var.accel_flags & FB_ACCELF_TEXT) {
- display->dispsw = &fbcon_virge8;
+ case 8:
+ if (display->var.accel_flags & FB_ACCELF_TEXT) {
+ display->dispsw = &fbcon_virge8;
#warning FIXME: We should reinit the graphics engine here
- } else
- display->dispsw = &fbcon_virge8;
- break;
+ } else
+ display->dispsw = &fbcon_cfb8;
+ break;
#endif
#ifdef FBCON_HAS_CFB16
- case 16:
- display->dispsw = &fbcon_cfb16;
- break;
+ case 16:
+ if (display->var.accel_flags & FB_ACCELF_TEXT) {
+ display->dispsw = &fbcon_virge16;
+ } else
+ display->dispsw = &fbcon_cfb16;
+ display->dispsw_data = &fbcon_cmap.cfb16;
+ break;
#endif
- default:
- display->dispsw = &fbcon_dummy;
- break;
+ default:
+ display->dispsw = &fbcon_dummy;
+ break;
}
}
@@ -962,7 +1045,7 @@
if (!fb_display[con].cmap.len) { /* no colormap allocated? */
if ((err = fb_alloc_cmap(&fb_display[con].cmap,
- 1<<fb_display[con].var.bits_per_pixel, 0)))
+ 1<<fb_display[con].var.bits_per_pixel, 0)))
return(err);
}
if (con == currcon) /* current console? */
@@ -987,8 +1070,8 @@
/*
- * Cybervision Frame Buffer Specific ioctls
- */
+ * Cybervision Frame Buffer Specific ioctls
+ */
static int virgefb_ioctl(struct inode *inode, struct file *file,
u_int cmd, u_long arg, int con, struct fb_info *info)
@@ -1073,12 +1156,12 @@
}
else
{
- CyberVGARegs = ioremap(board_addr +0x0c000000, 0x00010000);
+ CyberVGARegs = (unsigned long)ioremap(board_addr +0x0c000000, 0x00010000);
CyberRegs_phys = board_addr + 0x05000000;
- CyberMem_phys = board_addr + 0x04800000;
+ CyberMem_phys = board_addr + 0x04000000; /* was 0x04800000 */
CyberRegs = ioremap(CyberRegs_phys, 0x00010000);
- CyberMem = ioremap(CyberMem_phys, 0x00400000);
+ CyberMem = (unsigned long)ioremap(CyberMem_phys, 0x01000000); /* was 0x00400000 */
cv3d_on_zorro2 = 0;
printk("CV3D detected running in Z3 mode\n");
}
@@ -1146,8 +1229,8 @@
/*
- * Blank the display.
- */
+ * Blank the display.
+ */
static void Cyberfb_blank(int blank, struct fb_info *info)
{
@@ -1201,13 +1284,103 @@
(u_short)bg);
}
+static void fbcon_virge8_putc(struct vc_data *conp, struct display *p, int c, int yy,
+ int xx)
+{
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ fbcon_cfb8_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_virge8_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
+{
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
+}
+
+static void fbcon_virge8_revc(struct display *p, int xx, int yy)
+{
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ fbcon_cfb8_revc(p, xx, yy);
+}
+
+static void fbcon_virge8_clear_margins(struct vc_data *conp, struct display *p,
+ int bottom_only)
+{
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ fbcon_cfb8_clear_margins(conp, p, bottom_only);
+}
+
static struct display_switch fbcon_virge8 = {
- fbcon_cfb8_setup, fbcon_virge8_bmove, fbcon_virge8_clear, fbcon_cfb8_putc,
- fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_cfb8_clear_margins,
- FONTWIDTH(8)
+ fbcon_cfb8_setup, fbcon_virge8_bmove, fbcon_virge8_clear, fbcon_virge8_putc,
+ fbcon_virge8_putcs, fbcon_virge8_revc, NULL, NULL, fbcon_virge8_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
#endif
+#ifdef FBCON_HAS_CFB16
+static void fbcon_virge16_bmove(struct display *p, int sy, int sx, int dy,
+ int dx, int height, int width)
+{
+ sx *= 16; dx *= 16; width *= 16;
+ Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
+ (u_short)(dy*fontheight(p)), (u_short)width,
+ (u_short)(height*fontheight(p)));
+}
+
+static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy,
+ int sx, int height, int width)
+{
+ unsigned char bg;
+
+ sx *= 16; width *= 16;
+ bg = attr_bgcol_ec(p,conp);
+ Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
+ (u_short)width, (u_short)(height*fontheight(p)),
+ (u_short)bg);
+}
+
+static void fbcon_virge16_putc(struct vc_data *conp, struct display *p, int c, int yy,
+ int xx)
+{
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ fbcon_cfb16_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_virge16_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
+{
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
+}
+
+static void fbcon_virge16_revc(struct display *p, int xx, int yy)
+{
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ fbcon_cfb16_revc(p, xx, yy);
+}
+
+static void fbcon_virge16_clear_margins(struct vc_data *conp, struct display *p,
+ int bottom_only)
+{
+ if (blit_maybe_busy)
+ Cyber3D_WaitBusy();
+ fbcon_cfb16_clear_margins(conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_virge16 = {
+ fbcon_cfb16_setup, fbcon_virge16_bmove, fbcon_virge16_clear, fbcon_virge16_putc,
+ fbcon_virge16_putcs, fbcon_virge16_revc, NULL, NULL, fbcon_virge16_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
#ifdef MODULE
int init_module(void)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)