patch-2.2.7 linux/drivers/video/leofb.c

Next file: linux/drivers/video/matroxfb.c
Previous file: linux/drivers/video/fbmem.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.6/linux/drivers/video/leofb.c linux/drivers/video/leofb.c
@@ -1,7 +1,7 @@
-/* $Id: leofb.c,v 1.5 1999/03/09 14:02:29 davem Exp $
+/* $Id: leofb.c,v 1.6 1999/04/01 13:03:25 jj Exp $
  * leofb.c: Leo (ZX) 24/8bit frame buffer driver
  *
- * Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
  * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz)
  */
 
@@ -80,12 +80,12 @@
 
 struct leo_lc_ss0_usr {
 	volatile u32	csr;
-	volatile u32	attrs;
-	volatile u32 	fontc;
-	volatile u32	fontc2;
+	volatile u32	addrspace;
+	volatile u32 	fontmsk;
+	volatile u32	fontt;
 	volatile u32	extent;
 	volatile u32	src;
-	u32		xxx1[1];
+	u32		dst;
 	volatile u32	copy;
 	volatile u32	fill;
 };
@@ -98,19 +98,42 @@
 	u8	unknown;
 };
 
-struct leo_ld_ss0 {
+struct leo_ld {
 	u8		xxx0[0xe00];
-	u32		xxx1[2];
-	volatile u32	unk;
-	u32		xxx2[1];
-	volatile u32	unk2;
-	volatile u32	unk3;
-	u32		xxx3[2];
+	volatile u32	csr;
+	volatile u32	wid;
+	volatile u32	wmask;
+	volatile u32	widclip;
+	volatile u32	vclipmin;
+	volatile u32	vclipmax;
+	volatile u32	pickmin;	/* SS1 only */
+	volatile u32	pickmax;	/* SS1 only */
 	volatile u32	fg;
 	volatile u32	bg;
-	u8		xxx4[0x05c];
+	volatile u32	src;		/* Copy/Scroll (SS0 only) */
+	volatile u32	dst;		/* Copy/Scroll/Fill (SS0 only) */
+	volatile u32	extent;		/* Copy/Scroll/Fill size (SS0 only) */
+	u32		xxx1[3];
+	volatile u32	setsem;		/* SS1 only */
+	volatile u32	clrsem;		/* SS1 only */
+	volatile u32	clrpick;	/* SS1 only */
+	volatile u32	clrdat;		/* SS1 only */
+	volatile u32	alpha;		/* SS1 only */
+	u8		xxx2[0x2c];
+	volatile u32	winbg;
 	volatile u32	planemask;
 	volatile u32	rop;
+	volatile u32	z;
+	volatile u32	dczf;		/* SS1 only */
+	volatile u32	dczb;		/* SS1 only */
+	volatile u32	dcs;		/* SS1 only */
+	volatile u32	dczs;		/* SS1 only */
+	volatile u32	pickfb;		/* SS1 only */
+	volatile u32	pickbb;		/* SS1 only */
+	volatile u32	dcfc;		/* SS1 only */
+	volatile u32	forcecol;	/* SS1 only */
+	volatile u32	door[8];	/* SS1 only */
+	volatile u32	pick[5];	/* SS1 only */
 };
 
 #define LEO_SS1_MISC_ENABLE	0x00000001
@@ -126,17 +149,17 @@
 
 static struct sbus_mmap_map leo_mmap_map[] = {
 	{ LEO_SS0_MAP,		LEO_OFF_SS0,		0x800000	},
-	{ LEO_LC_SS0_USR_MAP,	LEO_OFF_LC_SS0_USR,	PAGE_SIZE	},
-	{ LEO_LD_SS0_MAP,	LEO_OFF_LD_SS0,		PAGE_SIZE	},
-	{ LEO_LX_CURSOR_MAP,	LEO_OFF_LX_CURSOR,	PAGE_SIZE	},
+	{ LEO_LC_SS0_USR_MAP,	LEO_OFF_LC_SS0_USR,	0x1000		},
+	{ LEO_LD_SS0_MAP,	LEO_OFF_LD_SS0,		0x1000		},
+	{ LEO_LX_CURSOR_MAP,	LEO_OFF_LX_CURSOR,	0x1000		},
 	{ LEO_SS1_MAP,		LEO_OFF_SS1,		0x800000	},
-	{ LEO_LC_SS1_USR_MAP,	LEO_OFF_LC_SS1_USR,	PAGE_SIZE	},
-	{ LEO_LD_SS1_MAP,	LEO_OFF_LD_SS1,		PAGE_SIZE	},
-	{ LEO_UNK_MAP,		LEO_OFF_UNK,		PAGE_SIZE	},
-	{ LEO_LX_KRN_MAP,	LEO_OFF_LX_KRN,		PAGE_SIZE	},
-	{ LEO_LC_SS0_KRN_MAP,	LEO_OFF_LC_SS0_KRN,	PAGE_SIZE	},
-	{ LEO_LC_SS1_KRN_MAP,	LEO_OFF_LC_SS1_KRN,	PAGE_SIZE	},
-	{ LEO_LD_GBL_MAP,	LEO_OFF_LD_GBL,		PAGE_SIZE	},
+	{ LEO_LC_SS1_USR_MAP,	LEO_OFF_LC_SS1_USR,	0x1000		},
+	{ LEO_LD_SS1_MAP,	LEO_OFF_LD_SS1,		0x1000		},
+	{ LEO_UNK_MAP,		LEO_OFF_UNK,		0x1000		},
+	{ LEO_LX_KRN_MAP,	LEO_OFF_LX_KRN,		0x1000		},
+	{ LEO_LC_SS0_KRN_MAP,	LEO_OFF_LC_SS0_KRN,	0x1000		},
+	{ LEO_LC_SS1_KRN_MAP,	LEO_OFF_LC_SS1_KRN,	0x1000		},
+	{ LEO_LD_GBL_MAP,	LEO_OFF_LD_GBL,		0x1000		},
 	{ LEO_UNK2_MAP,		LEO_OFF_UNK2,		0x100000	},
 	{ 0,			0,			0	  	}
 };
@@ -152,19 +175,14 @@
 {
 	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
 	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
-	register struct leo_ld_ss0 *ss = fb->s.leo.ld_ss0;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
 	int x, y, w, h;
 	int i;
 
 	do {
 		i = us->csr;
 	} while (i & 0x20000000);
-	ss->unk = 0xffff;
-	ss->unk2 = 0;
-	ss->unk3 = fb->s.leo.extent;
-	ss->fg = (attr_bgcol_ec(p,conp)<<24) | 0x030703;
-	ss->planemask = 0xff000000;
-	ss->rop = 0xd0840;
+	ss->fg = (attr_bgcol_ec(p,conp)<<24);
 	if (fontheightlog(p)) {
 		y = sy << fontheightlog(p); h = height << fontheightlog(p);
 	} else {
@@ -176,9 +194,8 @@
 		x = sx * fontwidth(p); w = width * fontwidth(p);
 	}
 	us->extent = (w - 1) | ((h - 1) << 11);
-	i = us->attrs;
 	us->fill = (x + fb->x_margin) | ((y + fb->y_margin) << 11) |
-		   ((i & 3) << 29) | ((i & 8) ? 0x80000000 : 0);
+		   0x80000000;
 }
 
 static void leo_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
@@ -186,23 +203,17 @@
 {
 	int i;
 	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
-	register struct leo_ld_ss0 *ss = fb->s.leo.ld_ss0;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
 	
-	do {
-		i = us->csr;
-	} while (i & 0x20000000);
-	ss->unk = 0xffff;
-	ss->unk2 = 0;
-	ss->unk3 = fb->s.leo.extent;
-	ss->fg = (attr_bgcol(p,s)<<24) | 0x030703;
-	ss->planemask = 0xff000000;
-	ss->rop = 0xd0840;
+	ss->fg = (attr_bgcol(p,s)<<24);
 	while (count-- > 0) {
+		do {
+			i = us->csr;
+		} while (i & 0x20000000);
 		us->extent = (boxes[2] - boxes[0] - 1) | 
 			     ((boxes[3] - boxes[1] - 1) << 11);
-		i = us->attrs;
-		us->fill = boxes[0] | (boxes[1] << 11) |
-			   ((i & 3) << 29) | ((i & 8) ? 0x80000000 : 0);
+		us->fill = boxes[0] | (boxes[1] << 11) | 0x80000000;
+		boxes += 4;
 	}
 }
 
@@ -210,7 +221,7 @@
 {
 	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
 	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
-	register struct leo_ld_ss0 *ss = fb->s.leo.ld_ss0;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
 	int i, x, y;
 	u8 *fd;
 	u32 *u;
@@ -235,11 +246,7 @@
 	} while (i & 0x20000000);
 	ss->fg = attr_fgcol(p,c) << 24;
 	ss->bg = attr_bgcol(p,c) << 24;
-	ss->rop = 0x310040;
-	ss->planemask = 0xff000000;
-	us->fontc2 = 0xFFFFFFFE;
-	us->attrs = 4;
-	us->fontc = 0xFFFFFFFF<<(32-fontwidth(p));
+	us->fontmsk = 0xFFFFFFFF<<(32-fontwidth(p));
 	u = ((u32 *)p->screen_base) + y + x;
 	if (fontwidth(p) <= 8) {
 		for (i = 0; i < fontheight(p); i++, u += 2048)
@@ -257,7 +264,7 @@
 {
 	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
 	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
-	register struct leo_ld_ss0 *ss = fb->s.leo.ld_ss0;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
 	int i, x, y;
 	u8 *fd1, *fd2, *fd3, *fd4;
 	u32 *u;
@@ -267,11 +274,7 @@
 	} while (i & 0x20000000);
 	ss->fg = attr_fgcol(p,scr_readw(s)) << 24;
 	ss->bg = attr_bgcol(p,scr_readw(s)) << 24;
-	ss->rop = 0x310040;
-	ss->planemask = 0xff000000;
-	us->fontc2 = 0xFFFFFFFE;
-	us->attrs = 4;
-	us->fontc = 0xFFFFFFFF<<(32-fontwidth(p));
+	us->fontmsk = 0xFFFFFFFF<<(32-fontwidth(p));
 	if (fontwidthlog(p))
 		x = (xx << fontwidthlog(p));
 	else
@@ -282,7 +285,7 @@
 		y = (yy * fontheight(p)) << 11;
 	u = ((u32 *)p->screen_base) + y + x;
 	if (fontwidth(p) <= 8) {
-		us->fontc = 0xFFFFFFFF<<(32-4*fontwidth(p));
+		us->fontmsk = 0xFFFFFFFF<<(32-4*fontwidth(p));
 		x = 4*fontwidth(p) - fontheight(p)*2048;
 		while (count >= 4) {
 			count -= 4;
@@ -310,7 +313,7 @@
 			}
 		}
 	} else {
-		us->fontc = 0xFFFFFFFF<<(32-2*fontwidth(p));
+		us->fontmsk = 0xFFFFFFFF<<(32-2*fontwidth(p));
 		x = 2*fontwidth(p) - fontheight(p)*2048;
 		while (count >= 2) {
 			count -= 2;
@@ -328,7 +331,7 @@
 			u += x;
 		}
 	}
-	us->fontc = 0xFFFFFFFF<<(32-fontwidth(p));
+	us->fontmsk = 0xFFFFFFFF<<(32-fontwidth(p));
 	x = fontwidth(p) - fontheight(p)*2048;
 	while (count) {
 		count--;
@@ -457,8 +460,8 @@
 		fb->s.leo.lx_krn->krn_csr |= LEO_KRN_CSR_ENABLE;
 }
 
-__initfunc(static int
-leo_wid_put (struct fb_info_sbusfb *fb, struct fb_wid_list *wl))
+static int __init
+leo_wid_put (struct fb_info_sbusfb *fb, struct fb_wid_list *wl)
 {
 	struct leo_lx_krn *lx_krn = fb->s.leo.lx_krn;
 	struct fb_wid_item *wi;
@@ -476,6 +479,8 @@
 		lx_krn->krn_type = 0x5800 + j;
 		lx_krn->krn_value = wi->wi_values[0];
 	}
+	lx_krn->krn_type = LEO_KRN_TYPE_WID;
+	lx_krn->krn_csr = 3;
 	return 0;
 }
 
@@ -484,9 +489,43 @@
 	p->screen_base += 8192 * (y_margin - fb->y_margin) + 4 * (x_margin - fb->x_margin);
 }
 
+static void leo_switch_from_graph (struct fb_info_sbusfb *fb)
+{
+	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
+
+	ss->wid = 0xffffffff;	
+	ss->wmask = 0xffff;
+	ss->vclipmin = 0;
+	ss->vclipmax = fb->s.leo.extent;
+	ss->planemask = 0xff000000;
+	ss->rop = 0x310850;
+	ss->widclip = 0;
+	us->addrspace = 4;
+	us->fontt = 0;
+}
+
+static void __init leo_rasterimg (struct fb_info_sbusfb *fb, int start)
+{
+	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
+	register struct leo_ld *ss = fb->s.leo.ld_ss0;
+
+	if (start) {
+		ss->wid = 1;
+		ss->planemask = 0xffffff;
+		ss->rop = 0x310b90;
+		us->addrspace = 0;
+	} else {
+		ss->wid = 0xffffffff;
+		ss->planemask = 0xff000000;
+		ss->rop = 0x310850;
+		us->addrspace = 4;
+	}
+}
+
 static char idstring[40] __initdata = { 0 };
 
-__initfunc(char *leofb_init(struct fb_info_sbusfb *fb))
+char * __init leofb_init(struct fb_info_sbusfb *fb)
 {
 	struct fb_fix_screeninfo *fix = &fb->fix;
 	struct fb_var_screeninfo *var = &fb->var;
@@ -496,44 +535,53 @@
 	struct fb_wid_item wi;
 	struct fb_wid_list wl;
 	int i;
+	register struct leo_lc_ss0_usr *us;
+	register struct leo_ld *ss;
+	struct fb_ops *fbops;
 
 	strcpy(fb->info.modename, "Leo");
 		
 	strcpy(fix->id, "Leo");
-	fix->visual = 0xff; /* We only know how to do acceleration and know nothing
-	                       about the actual memory layout */
+	fix->visual = FB_VISUAL_TRUECOLOR;
 	fix->line_length = 8192;
 	fix->accel = FB_ACCEL_SUN_LEO;
 	
+	var->bits_per_pixel = 32;
+	var->green.offset = 8;
+	var->blue.offset = 16;
 	var->accel_flags = FB_ACCELF_TEXT;
 	
+	fbops = kmalloc(sizeof(*fbops), GFP_KERNEL);
+	if (!fbops) return NULL;
+	
+	*fbops = *fb->info.fbops;
+	fbops->fb_rasterimg = leo_rasterimg;
+	fb->info.fbops = fbops;
+	
 	disp->scrollmode = SCROLL_YREDRAW;
 	if (!disp->screen_base)
 		disp->screen_base = (char *)sparc_alloc_io(phys + LEO_OFF_SS0, 0, 
 			0x800000, "leo_ram", fb->iospace, 0);
 	disp->screen_base += 8192 * fb->y_margin + 4 * fb->x_margin;
-	fb->s.leo.lc_ss0_usr = (struct leo_lc_ss0_usr *)
+	us = fb->s.leo.lc_ss0_usr = (struct leo_lc_ss0_usr *)
 			sparc_alloc_io(phys + LEO_OFF_LC_SS0_USR, 0, 
-			PAGE_SIZE, "leo_lc_ss0_usr", fb->iospace, 0);
-	fb->s.leo.ld_ss0 = (struct leo_ld_ss0 *)
+			0x1000, "leo_lc_ss0_usr", fb->iospace, 0);
+	ss = fb->s.leo.ld_ss0 = (struct leo_ld *)
 			sparc_alloc_io(phys + LEO_OFF_LD_SS0, 0, 
-			PAGE_SIZE, "leo_ld_ss0", fb->iospace, 0);
+			0x1000, "leo_ld_ss0", fb->iospace, 0);
 	fb->s.leo.ld_ss1 = (struct leo_ld_ss1 *)
 			sparc_alloc_io(phys + LEO_OFF_LD_SS1, 0, 
-			PAGE_SIZE, "leo_ld_ss1", fb->iospace, 0);
+			0x1000, "leo_ld_ss1", fb->iospace, 0);
 	fb->s.leo.lx_krn = (struct leo_lx_krn *)
 			sparc_alloc_io(phys + LEO_OFF_LX_KRN, 0, 
-			PAGE_SIZE, "leo_lx_krn", fb->iospace, 0);
+			0x1000, "leo_lx_krn", fb->iospace, 0);
 	fb->s.leo.cursor = (struct leo_cursor *)
 			sparc_alloc_io(phys + LEO_OFF_LX_CURSOR, 0, 
 			sizeof(struct leo_cursor), "leo_lx_cursor", fb->iospace, 0);
 	fb->dispsw = leo_dispsw;
-
+	
 	fb->s.leo.extent = (type->fb_width-1) | ((type->fb_height-1) << 16);
 
-	fb->s.leo.ld_ss0->unk = 0xffff;
-	fb->s.leo.ld_ss0->unk2 = 0;
-	fb->s.leo.ld_ss0->unk3 = fb->s.leo.extent;
 	wl.wl_count = 1;
 	wl.wl_list = &wi;
 	wi.wi_type = FB_WID_DBL_8;
@@ -546,17 +594,27 @@
 	wi.wi_index = 2;
 	wi.wi_values [0] = 0x20;
 	leo_wid_put (fb, &wl);
+	wi.wi_type = FB_WID_DBL_24;
+	wi.wi_index = 1;
+	wi.wi_values [0] = 0x30;
+	leo_wid_put (fb, &wl);
 
 	fb->s.leo.ld_ss1->ss1_misc |= LEO_SS1_MISC_ENABLE;
 
-	fb->s.leo.ld_ss0->fg = 0x30703;
-	fb->s.leo.ld_ss0->planemask = 0xff000000;
-	fb->s.leo.ld_ss0->rop = 0xd0840;
-	fb->s.leo.lc_ss0_usr->extent = (type->fb_width-1) | ((type->fb_height-1) << 11);
-	i = fb->s.leo.lc_ss0_usr->attrs;
-	fb->s.leo.lc_ss0_usr->fill = (0) | ((0) << 11) | ((i & 3) << 29) | ((i & 8) ? 0x80000000 : 0);
+	ss->wid = 0xffffffff;
+	ss->wmask = 0xffff;
+	ss->vclipmin = 0;
+	ss->vclipmax = fb->s.leo.extent;
+	ss->fg = 0;
+	ss->planemask = 0xff000000;
+	ss->rop = 0x310850;
+	ss->widclip = 0;
+	us->extent = (type->fb_width-1) | ((type->fb_height-1) << 11);
+	us->addrspace = 4;
+	us->fill = 0x80000000;
+	us->fontt = 0;
 	do {
-		i = fb->s.leo.lc_ss0_usr->csr;
+		i = us->csr;
 	} while (i & 0x20000000);
 
 	fb->margins = leo_margins;
@@ -565,6 +623,7 @@
 	fb->setcursormap = leo_setcursormap;
 	fb->setcurshape = leo_setcurshape;
 	fb->restore_palette = leo_restore_palette;
+	fb->switch_from_graph = leo_switch_from_graph;
 	fb->fill = leo_fill;
 	fb->blank = leo_blank;
 	fb->unblank = leo_unblank;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)