summaryrefslogtreecommitdiffstats
path: root/drivers/video/controlfb.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
commit78c388aed2b7184182c08428db1de6c872d815f5 (patch)
tree4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /drivers/video/controlfb.c
parenteb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff)
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'drivers/video/controlfb.c')
-rw-r--r--drivers/video/controlfb.c191
1 files changed, 139 insertions, 52 deletions
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 466bf52ee..d1a63b64f 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -49,16 +49,19 @@
#include <asm/adb.h>
#include <asm/cuda.h>
-#include "fbcon.h"
-#include "fbcon-cfb8.h"
-#include "fbcon-cfb16.h"
-#include "fbcon-cfb32.h"
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb32.h>
+#include <video/macmodes.h>
-#include "macmodes.h"
#include "controlfb.h"
static int currcon = 0;
static int switching = 0;
+static char fontname[40] __initdata = { 0 };
+static int default_vmode = VMODE_NVRAM;
+static int default_cmode = CMODE_NVRAM;
struct fb_par_control {
int vmode, cmode;
@@ -88,13 +91,24 @@ struct fb_info_control {
int sense, control_use_bank2;
unsigned long total_vram;
+ union {
+#ifdef FBCON_HAS_CFB16
+ u16 cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+ u32 cfb32[16];
+#endif
+ } fbcon_cmap;
};
/*
* Exported functions
*/
void control_init(void);
+#ifdef CONFIG_FB_OF
void control_of_init(struct device_node *dp);
+#endif
+void controlfb_setup(char *options, int *ints);
static int control_open(struct fb_info *info, int user);
static int control_release(struct fb_info *info, int user);
@@ -198,7 +212,7 @@ static int control_set_var(struct fb_var_screeninfo *var, int con,
}
if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) {
- printk("Not activating, in control_set_var.\n");
+ /* printk("Not activating, in control_set_var.\n"); */
control_par_to_var(&par, var);
return 0;
}
@@ -211,7 +225,7 @@ static int control_set_var(struct fb_var_screeninfo *var, int con,
p->var = disp->var = *var;
return 0;
}
-printk("Original bpp is %d, new bpp %d.\n", p->var.bits_per_pixel, var->bits_per_pixel);
+ /* printk("Original bpp is %d, new bpp %d.\n", p->var.bits_per_pixel, var->bits_per_pixel); */
/* OK, we're getting here at the right times... */
p->par = par;
control_par_to_var(&par, var);
@@ -244,8 +258,7 @@ static int control_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
if (con == currcon) /* current console? */
- return fb_get_cmap(cmap, &fb_display[con].var, kspc,
- controlfb_getcolreg, info);
+ return fb_get_cmap(cmap, kspc, controlfb_getcolreg, info);
if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc? 0: 2);
else {
@@ -269,8 +282,7 @@ static int control_set_cmap(struct fb_cmap *cmap, int kspc, int con,
}
if (con == currcon)
- return fb_set_cmap(cmap, &disp->var, kspc, controlfb_setcolreg,
- info);
+ return fb_set_cmap(cmap, kspc, controlfb_setcolreg, info);
fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
return 0;
}
@@ -284,8 +296,7 @@ static int control_ioctl(struct inode *inode, struct file *file, u_int cmd,
static int controlfb_switch(int con, struct fb_info *info)
{
if (fb_display[currcon].cmap.len)
- fb_get_cmap(&fb_display[currcon].cmap,
- &fb_display[currcon].var, 1, controlfb_getcolreg,
+ fb_get_cmap(&fb_display[currcon].cmap, 1, controlfb_getcolreg,
info);
currcon = con;
#if 0
@@ -346,9 +357,10 @@ static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green,
if (regno > 255)
return 1;
- *red = p->palette[regno].red;
- *green = p->palette[regno].green;
- *blue = p->palette[regno].blue;
+ *red = (p->palette[regno].red<<8) | p->palette[regno].red;
+ *green = (p->palette[regno].green<<8) | p->palette[regno].green;
+ *blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;
+ *transp = 0;
return 0;
}
@@ -356,9 +368,13 @@ static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{
struct fb_info_control *p = (struct fb_info_control *) info;
+ int i;
- if (regno > 255 || regno < 0)
+ if (regno > 255)
return 1;
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
p->palette[regno].red = red;
p->palette[regno].green = green;
p->palette[regno].blue = blue;
@@ -368,25 +384,29 @@ static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
out_8(&p->cmap_regs->lut, green); /* a time... */
out_8(&p->cmap_regs->lut, blue);
- if(regno < 16) {
-#if 0
+ if (regno < 16)
+ switch (p->var.bits_per_pixel) {
#ifdef FBCON_HAS_CFB16
- fbcon_cfb16_cmap[regno] = (red << 10) | (green << 5) | blue;
-#endif
-#ifdef FBCON_HAS_CFB32
- fbcon_cfb32_cmap[regno] = (red << 16) | (green << 8) | blue;
- /* I think. */
-#endif
+ case 16:
+#if 0
+ p->fbcon_cmap.cfb16[regno] = (red << 10) | (green << 5) | blue;
#else
-#ifdef FBCON_HAS_CFB16
- fbcon_cfb16_cmap[regno] = (regno << 10) | (regno << 5) | regno;
+ p->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno;
+#endif
+ break;
#endif
#ifdef FBCON_HAS_CFB32
- fbcon_cfb32_cmap[regno] = (regno << 24) | (regno << 16) | (regno << 8) | regno;
- /* I think. */
+ case 32:
+#if 0
+ p->fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | blue;
+#else
+ i = (regno << 8) | regno;
+ p->fbcon_cmap.cfb32[regno] = (i << 16) | i;
+ /* I think */
#endif
+ break;
#endif
- }
+ }
return 0;
}
@@ -395,12 +415,12 @@ static void do_install_cmap(int con, struct fb_info *info)
if (con != currcon)
return;
if (fb_display[con].cmap.len)
- fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
- controlfb_setcolreg, info);
+ fb_set_cmap(&fb_display[con].cmap, 1, controlfb_setcolreg,
+ info);
else {
int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
- fb_set_cmap(fb_default_cmap(size), &fb_display[con].var, 1,
- controlfb_setcolreg, info);
+ fb_set_cmap(fb_default_cmap(size), 1, controlfb_setcolreg,
+ info);
}
}
@@ -440,7 +460,7 @@ __initfunc(static void init_control(struct fb_info_control *p))
struct fb_par_control *par = &p->par;
p->sense = read_control_sense(p);
- printk("Monitor sense value = 0x%x, ", p->sense);
+ printk(KERN_INFO "Monitor sense value = 0x%x, ", p->sense);
/* Try to pick a video mode out of NVRAM if we have one. */
par->vmode = nvram_read_byte(NV_VMODE);
if(par->vmode <= 0 || par->vmode > VMODE_MAX || !control_reg_init[par->vmode - 1])
@@ -467,13 +487,14 @@ __initfunc(static void init_control(struct fb_info_control *p))
control_par_to_all(p, 1);
+ p->info.flags = FBINFO_FLAG_DEFAULT;
if (register_framebuffer(&p->info) < 0) {
kfree(p);
return;
}
control_set_hardware(p);
- printk("fb%d: control display adapter\n", GET_FB_IDX(p->info.node));
+ printk(KERN_INFO "fb%d: control display adapter\n", GET_FB_IDX(p->info.node));
}
/* Now how about actually saying, Make it so! */
@@ -523,8 +544,9 @@ static void control_set_hardware(struct fb_info_control *p)
out_le32(&p->control_regs->reg19.r, 0);
for (i = 0; i < 16; ++i) {
- controlfb_setcolreg(color_table[i], default_red[i], default_grn[i],
- default_blu[i], 0, (struct fb_info *)p);
+ controlfb_setcolreg(color_table[i], default_red[i]<<8,
+ default_grn[i]<<8, default_blu[i]<<8,
+ 0, (struct fb_info *)p);
}
/* Does the above need to be here each time? -- danj */
@@ -568,16 +590,24 @@ __initfunc(void control_of_init(struct device_node *dp))
struct fb_info_control *p;
unsigned long addr, size;
int i, bank1, bank2;
-
+
+#if 0
if(dp->next != 0)
printk("Warning: only using first control display device.\n");
/* danj: I have a feeling this no longer applies - if we somehow *
- * had two of them, they'd be two framebuffers, right? */
- if(dp->n_addrs != 2)
- panic("expecting 2 address for control (got %d)", dp->n_addrs);
+ * had two of them, they'd be two framebuffers, right?
+ * Yep. - paulus
+ */
+#endif
+
+ if(dp->n_addrs != 2) {
+ printk(KERN_ERR "expecting 2 address for control (got %d)", dp->n_addrs);
+ return;
+ }
p = kmalloc(sizeof(*p), GFP_ATOMIC);
if (p == 0)
return;
+ memset(p, 0, sizeof(*p));
/* Map in frame buffer and registers */
for (i = 0; i < dp->n_addrs; ++i) {
@@ -657,7 +687,7 @@ static int read_control_sense(struct fb_info_control *p)
#if 1
/* This routine takes a user-supplied var, and picks the best vmode/cmode from it. */
-static int control_var_to_par(struct fb_var_screeninfo *var,
+static int control_var_to_par(struct fb_var_screeninfo *var,
struct fb_par_control *par, const struct fb_info *fb_info)
{
int xres = var->xres;
@@ -758,7 +788,7 @@ static int control_var_to_par(struct fb_var_screeninfo *var,
}
#else
/* This routine takes a user-supplied var, and picks the best vmode/cmode from it. */
-static int control_var_to_par(struct fb_var_screeninfo *var,
+static int control_var_to_par(struct fb_var_screeninfo *var,
struct fb_par_control *par, const struct fb_info *fb_info)
{
struct fb_info_control *p = (struct fb_info_control *) fb_info;
@@ -901,7 +931,7 @@ static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeni
p->fix.smem_len = control_vram_reqd(par->vmode, par->cmode);
/* Hmm, jonh used total_vram here. */
p->fix.visual = (par->cmode == CMODE_8) ?
- FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
p->fix.line_length = par->vxres << par->cmode;
/* ywrapstep, xpanstep, ypanstep */
}
@@ -935,8 +965,28 @@ if(disp->scrollmode != SCROLL_YREDRAW) {
printk(KERN_ERR "Scroll mode not YREDRAW in control_par_to_display!!\n");
disp->scrollmode = SCROLL_YREDRAW;
}
- disp->dispsw = (par->cmode == CMODE_32) ? &fbcon_cfb32 :
- ((par->cmode == CMODE_16) ? &fbcon_cfb16 : &fbcon_cfb8);
+ switch (par->cmode) {
+#ifdef FBCON_HAS_CFB8
+ case CMODE_8:
+ disp->dispsw = &fbcon_cfb8;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case CMODE_16:
+ disp->dispsw = &fbcon_cfb16;
+ disp->dispsw_data = p->fbcon_cmap.cfb16;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case CMODE_32:
+ disp->dispsw = &fbcon_cfb32;
+ disp->dispsw_data = p->fbcon_cmap.cfb32;
+ break;
+#endif
+ default:
+ disp->dispsw = &fbcon_dummy;
+ break;
+ }
}
static void control_init_info(struct fb_info *info, struct fb_info_control *p)
@@ -945,7 +995,7 @@ static void control_init_info(struct fb_info *info, struct fb_info_control *p)
info->node = -1; /* ??? danj */
info->fbops = &controlfb_ops;
info->disp = &p->disp;
- info->fontname[0] = 0;
+ strcpy(info->fontname, fontname);
info->changevar = NULL;
info->switch_con = &controlfb_switch;
info->updatevar = &controlfb_updatevar;
@@ -972,13 +1022,51 @@ static void control_par_to_all(struct fb_info_control *p, int init)
}
}
-#if 0
+/* Parse user speficied options (`video=controlfb:') */
__initfunc(void controlfb_setup(char *options, int *ints))
{
- /* Parse user speficied options (`video=controlfb:') */
- FUNCID;
+ char *this_opt;
+
+ if (!options || !*options)
+ return;
+
+ for (this_opt = strtok(options, ","); this_opt;
+ this_opt = strtok(NULL, ",")) {
+ if (!strncmp(this_opt, "font:", 5)) {
+ char *p;
+ int i;
+
+ p = this_opt +5;
+ for (i = 0; i < sizeof(fontname) - 1; i++)
+ if (!*p || *p == ' ' || *p == ',')
+ break;
+ memcpy(fontname, this_opt + 5, i);
+ fontname[i] = 0;
+ }
+ if (!strncmp(this_opt, "vmode:", 6)) {
+ int vmode = simple_strtoul(this_opt+6, NULL, 0);
+ if (vmode > 0 && vmode <= VMODE_MAX)
+ default_vmode = vmode;
+ } else if (!strncmp(this_opt, "cmode:", 6)) {
+ int depth = simple_strtoul(this_opt+6, NULL, 0);
+ switch (depth) {
+ case 8:
+ default_cmode = CMODE_8;
+ break;
+ case 15:
+ case 16:
+ default_cmode = CMODE_16;
+ break;
+ case 24:
+ case 32:
+ default_cmode = CMODE_32;
+ break;
+ }
+ }
+ }
}
+#if 0
static int controlfb_pan_display(struct fb_var_screeninfo *var,
struct controlfb_par *par,
const struct fb_info *fb_info)
@@ -993,5 +1081,4 @@ static int controlfb_pan_display(struct fb_var_screeninfo *var,
return 0;
}
-
#endif