|
@@ -372,98 +372,8 @@ struct cirrusfb_info {
|
|
|
void (*unmap)(struct fb_info *info);
|
|
|
};
|
|
|
|
|
|
-static unsigned cirrusfb_def_mode = 1;
|
|
|
static int noaccel;
|
|
|
-
|
|
|
-/*
|
|
|
- * Predefined Video Modes
|
|
|
- */
|
|
|
-
|
|
|
-static const struct {
|
|
|
- const char *name;
|
|
|
- struct fb_var_screeninfo var;
|
|
|
-} cirrusfb_predefined[] = {
|
|
|
- {
|
|
|
- /* autodetect mode */
|
|
|
- .name = "Autodetect",
|
|
|
- }, {
|
|
|
- /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
|
|
|
- .name = "640x480",
|
|
|
- .var = {
|
|
|
- .xres = 640,
|
|
|
- .yres = 480,
|
|
|
- .xres_virtual = 640,
|
|
|
- .yres_virtual = 480,
|
|
|
- .bits_per_pixel = 8,
|
|
|
- .red = { .length = 8 },
|
|
|
- .green = { .length = 8 },
|
|
|
- .blue = { .length = 8 },
|
|
|
- .width = -1,
|
|
|
- .height = -1,
|
|
|
- .pixclock = 40000,
|
|
|
- .left_margin = 48,
|
|
|
- .right_margin = 16,
|
|
|
- .upper_margin = 32,
|
|
|
- .lower_margin = 8,
|
|
|
- .hsync_len = 96,
|
|
|
- .vsync_len = 4,
|
|
|
- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
|
|
|
- .vmode = FB_VMODE_NONINTERLACED
|
|
|
- }
|
|
|
- }, {
|
|
|
- /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
|
|
|
- .name = "800x600",
|
|
|
- .var = {
|
|
|
- .xres = 800,
|
|
|
- .yres = 600,
|
|
|
- .xres_virtual = 800,
|
|
|
- .yres_virtual = 600,
|
|
|
- .bits_per_pixel = 8,
|
|
|
- .red = { .length = 8 },
|
|
|
- .green = { .length = 8 },
|
|
|
- .blue = { .length = 8 },
|
|
|
- .width = -1,
|
|
|
- .height = -1,
|
|
|
- .pixclock = 20000,
|
|
|
- .left_margin = 128,
|
|
|
- .right_margin = 16,
|
|
|
- .upper_margin = 24,
|
|
|
- .lower_margin = 2,
|
|
|
- .hsync_len = 96,
|
|
|
- .vsync_len = 6,
|
|
|
- .vmode = FB_VMODE_NONINTERLACED
|
|
|
- }
|
|
|
- }, {
|
|
|
- /*
|
|
|
- * Modeline from XF86Config:
|
|
|
- * Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805
|
|
|
- */
|
|
|
- /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
|
|
|
- .name = "1024x768",
|
|
|
- .var = {
|
|
|
- .xres = 1024,
|
|
|
- .yres = 768,
|
|
|
- .xres_virtual = 1024,
|
|
|
- .yres_virtual = 768,
|
|
|
- .bits_per_pixel = 8,
|
|
|
- .red = { .length = 8 },
|
|
|
- .green = { .length = 8 },
|
|
|
- .blue = { .length = 8 },
|
|
|
- .width = -1,
|
|
|
- .height = -1,
|
|
|
- .pixclock = 12500,
|
|
|
- .left_margin = 144,
|
|
|
- .right_margin = 32,
|
|
|
- .upper_margin = 30,
|
|
|
- .lower_margin = 2,
|
|
|
- .hsync_len = 192,
|
|
|
- .vsync_len = 6,
|
|
|
- .vmode = FB_VMODE_NONINTERLACED
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-#define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined)
|
|
|
+static char *mode_option __devinitdata = "640x480@60";
|
|
|
|
|
|
/****************************************************************************/
|
|
|
/**** BEGIN PROTOTYPES ******************************************************/
|
|
@@ -2267,23 +2177,27 @@ static int cirrusfb_register(struct fb_info *info)
|
|
|
/* sanity checks */
|
|
|
assert(btype != BT_NONE);
|
|
|
|
|
|
+ /* set all the vital stuff */
|
|
|
+ cirrusfb_set_fbinfo(info);
|
|
|
+
|
|
|
DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
|
|
|
|
|
|
- /* Make pretend we've set the var so our structures are in a "good" */
|
|
|
- /* state, even though we haven't written the mode to the hw yet... */
|
|
|
- info->var = cirrusfb_predefined[cirrusfb_def_mode].var;
|
|
|
+ err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
|
|
|
+ if (!err) {
|
|
|
+ DPRINTK("wrong initial video mode\n");
|
|
|
+ err = -EINVAL;
|
|
|
+ goto err_dealloc_cmap;
|
|
|
+ }
|
|
|
+
|
|
|
info->var.activate = FB_ACTIVATE_NOW;
|
|
|
|
|
|
err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
|
|
|
if (err < 0) {
|
|
|
/* should never happen */
|
|
|
DPRINTK("choking on default var... umm, no good.\n");
|
|
|
- goto err_unmap_cirrusfb;
|
|
|
+ goto err_dealloc_cmap;
|
|
|
}
|
|
|
|
|
|
- /* set all the vital stuff */
|
|
|
- cirrusfb_set_fbinfo(info);
|
|
|
-
|
|
|
err = register_framebuffer(info);
|
|
|
if (err < 0) {
|
|
|
printk(KERN_ERR "cirrusfb: could not register "
|
|
@@ -2296,7 +2210,6 @@ static int cirrusfb_register(struct fb_info *info)
|
|
|
|
|
|
err_dealloc_cmap:
|
|
|
fb_dealloc_cmap(&info->cmap);
|
|
|
-err_unmap_cirrusfb:
|
|
|
cinfo->unmap(info);
|
|
|
framebuffer_release(info);
|
|
|
return err;
|
|
@@ -2608,17 +2521,17 @@ static int __init cirrusfb_setup(char *options) {
|
|
|
return 0;
|
|
|
|
|
|
while ((this_opt = strsep(&options, ",")) != NULL) {
|
|
|
- if (!*this_opt) continue;
|
|
|
+ if (!*this_opt)
|
|
|
+ continue;
|
|
|
|
|
|
DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
|
|
|
|
|
|
- for (i = 0; i < NUM_TOTAL_MODES; i++) {
|
|
|
- sprintf(s, "mode:%s", cirrusfb_predefined[i].name);
|
|
|
- if (strcmp(this_opt, s) == 0)
|
|
|
- cirrusfb_def_mode = i;
|
|
|
- }
|
|
|
if (!strcmp(this_opt, "noaccel"))
|
|
|
noaccel = 1;
|
|
|
+ else if (!strncmp(this_opt, "mode:", 5))
|
|
|
+ mode_option = this_opt + 5;
|
|
|
+ else
|
|
|
+ mode_option = this_opt;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -2644,6 +2557,9 @@ static void __exit cirrusfb_exit(void)
|
|
|
|
|
|
module_init(cirrusfb_init);
|
|
|
|
|
|
+module_param(mode_option, charp, 0);
|
|
|
+MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
|
|
|
+
|
|
|
#ifdef MODULE
|
|
|
module_exit(cirrusfb_exit);
|
|
|
#endif
|