[parisc-linux-cvs] stifb.c 8bpp code (snapshot)

Helge Deller deller@gmx.de
Fri, 2 Mar 2001 01:36:32 +0100


This is just a snapshot of my current implementation of a cfb8-stifb.
I'm committing this now, because I will leave for 2 weeks and just want to 
have it in CVS instead of my HDD.

It's working for me so far, that it detects and initializes the framebuffer 
and enables software-cursor. Colors are currently not yet supported and all 
text is printed in pink.

Index: stifb.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/video/sti/stifb.c,v
retrieving revision 1.6
diff -u -r1.6 stifb.c
--- stifb.c	2001/02/15 23:25:45	1.6
+++ stifb.c	2001/03/02 00:24:21
@@ -22,6 +22,7 @@
  * packed-pixel this will probably work anyway even if it isn't.
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -34,123 +35,189 @@
 #include <linux/init.h>
 
 #include <video/fbcon.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
 
 #include "sticon-bmode.h"
 #include "sticore.h"
 
-static struct fb_ops stifb_ops;
+#define BPP 8	/* XXX FIXME !! */
 
+extern struct display_switch fbcon_sti;
+
 struct stifb_info {
 	struct fb_info_gen gen;
 	struct sti_struct *sti;
 };
 
 struct stifb_par {
+	int x, y;
+	int x_virt, y_virt;
+	int bpp;
 };
 
+static struct fb_var_screeninfo default_var;
 static struct stifb_info fb_info;
-static struct display disp;
 
-int stifb_init(void);
-int stifb_setup(char*);
+static struct stifb_par current_par;
+static int current_par_valid;
 
-extern struct display_switch fbcon_sti;
+static struct display disp;
 
 /* ------------------- chipset specific functions -------------------------- 
*/
 
 static int
-sti_encode_fix(struct fb_fix_screeninfo *fix,
-	       const void *par, struct fb_info_gen *info)
-{
-	/* XXX: what about smem_len? */
+stifb_encode_fix(struct fb_fix_screeninfo *fix,
+	       struct stifb_par *par, 
+	       struct fb_info_gen *info)
+{
+	memset(fix, 0, sizeof(*fix));
+	
+	strcpy(fix->id, "stifb");
+	fix->line_length = PTR_STI(fb_info.sti->glob_cfg)->total_x;
+	if (!fix->line_length)
+	    fix->line_length = 2048; /* default */
 	fix->smem_start = PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
-	fix->type = FB_TYPE_PLANES; /* well, sort of */
+	fix->smem_len = PTR_STI(fb_info.sti->glob_cfg)->total_y * fix->line_length;
 
+	if (par->bpp == 1) {
+	    fix->type = FB_TYPE_PLANES;	/* well, sort of */
+	    fix->visual = FB_VISUAL_MONO10;
+	} else { /* 8bpp */
+	    fix->type = FB_TYPE_PACKED_PIXELS;
+	    fix->visual = FB_VISUAL_TRUECOLOR; 
+	}
 	return 0;
 }
 
 static int
-sti_decode_var(const struct fb_var_screeninfo *var,
-	void *par, struct fb_info_gen *info)
-{
+stifb_decode_var(const struct fb_var_screeninfo *var,
+		struct stifb_par *par, 
+		struct fb_info_gen *info)
+{
+	par->x = var->xres;
+	par->y = var->yres;
+	par->x_virt = var->xres_virtual;
+	par->y_virt = var->yres_virtual;
+	par->bpp = var->bits_per_pixel;
 	return 0;
 }
 
 static int
-sti_encode_var(struct fb_var_screeninfo *var,
-	       const void *par, struct fb_info_gen *info)
-{
-	var->xres = sti_onscreen_x(fb_info.sti);
-	var->yres = sti_onscreen_y(fb_info.sti);
-	var->xres_virtual = PTR_STI(fb_info.sti->glob_cfg)->total_x;
-	var->yres_virtual = PTR_STI(fb_info.sti->glob_cfg)->total_y;
+stifb_encode_var(struct fb_var_screeninfo *var,
+		struct stifb_par *par, 
+		struct fb_info_gen *info)
+{
+	memset(var, 0, sizeof(*var));
+
+	var->xres = par->x;
+	var->yres = par->y;
+	var->xres_virtual = par->x_virt;
+	var->yres_virtual = par->y_virt;
 	var->xoffset = var->yoffset = 0;
-
-	var->bits_per_pixel = 1;
+	var->bits_per_pixel = par->bpp;
 	var->grayscale = 0;
+	var->height = -1;
+	var->width = -1;
+	var->vmode = FB_VMODE_NONINTERLACED;
 
 	return 0;
 }
 
 static void
-sti_get_par(void *par, struct fb_info_gen *info)
+stifb_get_par(struct stifb_par *par, struct fb_info_gen *info)
 {
+	*par = current_par; 
 }
 
 static void
-sti_set_par(const void *par, struct fb_info_gen *info)
+stifb_set_par(struct stifb_par *par, struct fb_info_gen *info)
 {
+	/* Set the hardware according to 'par'. */
+	current_par = *par;
+	current_par_valid = 1;
 }
 
 static int
-sti_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+stifb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
 	      unsigned *blue, unsigned *transp, struct fb_info *info)
 {
 	return 0;
 }
 
 static int
-sti_setcolreg(unsigned regno, unsigned red, unsigned green,
+stifb_setcolreg(unsigned regno, unsigned red, unsigned green,
 	      unsigned blue, unsigned transp, struct fb_info *info)
 {
 	return 0;
 }
 
 static void
-sti_set_disp(const void *par, struct display *disp,
-	     struct fb_info_gen *info)
+stifb_set_disp(struct stifb_par *par, 
+		struct display *disp,
+		struct fb_info_gen *info)
 {
 	disp->screen_base =
 		(void *) PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
-	disp->dispsw = &fbcon_sti;
+	
+	switch(par->bpp) {
+#ifdef FBCON_HAS_CFB8
+	case 8:	disp->dispsw = &fbcon_cfb8;
+        	break;
+#endif
+	case 1:	disp->dispsw = &fbcon_sti;
+		break;
+	default:disp->dispsw = &fbcon_dummy;
+    	}
 }
 
 static void
-sti_detect(void)
+stifb_detect(void)
 {
+	struct stifb_par par;
+	
+	par.x = sti_onscreen_x(fb_info.sti);
+	par.y = sti_onscreen_y(fb_info.sti);
+	par.x_virt = PTR_STI(fb_info.sti->glob_cfg)->total_x;
+	par.y_virt = PTR_STI(fb_info.sti->glob_cfg)->total_y;
+	par.bpp = BPP /* XXX */;
+	
+	stifb_set_par(&par, NULL);
+     	stifb_encode_var(&default_var, &par, NULL);
 }
 
 static int
-sti_blank(int blank_mode, struct fb_info_gen *info)
+stifb_blank(int blank_mode, struct fb_info_gen *info)
 {
 	return 0;
 }
 
 /* ------------ Interfaces to hardware functions ------------ */
 
-struct fbgen_hwswitch sti_switch = {
-	detect:		sti_detect,
-	encode_fix:	sti_encode_fix,
-	decode_var:	sti_decode_var,
-	encode_var:	sti_encode_var,
-	get_par:	sti_get_par,
-	set_par:	sti_set_par,
-	getcolreg:	sti_getcolreg,
-	setcolreg:	sti_setcolreg,
-	blank:		sti_blank,
-	set_disp:	sti_set_disp
+struct fbgen_hwswitch stifb_switch = {
+	detect:		stifb_detect,
+	encode_fix:	stifb_encode_fix,
+	decode_var:	stifb_decode_var,
+	encode_var:	stifb_encode_var,
+	get_par:	stifb_get_par,
+	set_par:	stifb_set_par,
+	getcolreg:	stifb_getcolreg,
+	setcolreg:	stifb_setcolreg,
+	blank:		stifb_blank,
+	set_disp:	stifb_set_disp
 };
 
+static struct fb_ops stifb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	fbgen_get_fix,
+	fb_get_var:	fbgen_get_var,
+	fb_set_var:	fbgen_set_var,
+	fb_get_cmap:	fbgen_get_cmap,
+	fb_set_cmap:	fbgen_set_cmap,
+//	fb_pan_display:	fbgen_pan_display,
+};
+
+
 
 /* ------------ Hardware Independent Functions ------------ */
 
@@ -162,9 +229,10 @@
 stifb_init(void)
 {
 	printk("%s: STARTUP\n", __FUNCTION__);
-	if ((fb_info.sti = sti_init_roms()) == NULL)
+	if (!(fb_info.sti = sti_init_roms()))
 		return -ENXIO;
 
+	strcpy(fb_info.gen.info.modename, "STI Generic");
 	fb_info.gen.info.node = -1;
 	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
 	fb_info.gen.info.fbops = &stifb_ops;
@@ -173,30 +241,48 @@
 	fb_info.gen.info.switch_con = &fbgen_switch;
 	fb_info.gen.info.updatevar = &fbgen_update_var;
 	fb_info.gen.info.blank = &fbgen_blank;
-	strcpy(fb_info.gen.info.modename, "STI Generic");
-	fb_info.gen.fbhw = &sti_switch;
+	fb_info.gen.parsize = sizeof(struct stifb_par);
+	fb_info.gen.fbhw = &stifb_switch;
 	fb_info.gen.fbhw->detect();
 
 	/* This should give a reasonable default video mode */
 	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
+	disp.var.activate = FB_ACTIVATE_NOW; 
 	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
 	fbgen_set_disp(-1, &fb_info.gen);
 	fbgen_install_cmap(0, &fb_info.gen);
-	pdc_console_die();
+
+	pdc_console_die();	/* XXX */
+
 	if (register_framebuffer(&fb_info.gen.info) < 0)
 		return -EINVAL;
 
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
 		GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename);
 
+#if 0
+	{
+	 int x,y,i;
+	 unsigned long sm;
+	 sm = PTR_STI(fb_info.sti->glob_cfg)->region_ptrs[1];
+	 for (i=1; i<2; i++) {
+	  for (y=0; y<1024/2; y++)
+	   for (x=0; x<1280/2; x++) {
+	     gsc_writeb(i, (void*)(sm + x + (y*2048)));
+	   }
+	   mdelay(10);
+	  }
+	}
+
+#endif
 	printk("%s: FINISHED\n", __FUNCTION__);
 	return 0;
 }
 
 
-    /*
-     *  Cleanup
-     */
+/*
+ *  Cleanup
+*/
 
 void
 stifb_cleanup(struct fb_info *info)
@@ -211,22 +297,8 @@
 	/* XXX: we should take the resolution, bpp as command line arguments. */
 	return 0;
 }
-
-
-/* ------------------------------------------------------------------------- 
*/
-
-
-static struct fb_ops stifb_ops = {
-	owner:		THIS_MODULE,
-	fb_open:	NULL,
-	fb_release:	NULL,
-	fb_get_fix:	fbgen_get_fix,
-	fb_get_var:	fbgen_get_var,
-	fb_set_var:	fbgen_set_var,
-	fb_get_cmap:	fbgen_get_cmap,
-	fb_set_cmap:	fbgen_set_cmap,
-	fb_pan_display:	fbgen_pan_display,
-	fb_ioctl:	NULL
-};
 
-/* module_init(stifb_init); */
+#ifdef MODULE
+module_init(stifb_init);
+__setup("stifb=", sti_setup);
+#endif