[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