cirrusfb: use modedb and add mode_option parameter
authorKrzysztof Helt <krzysztof.h1@wp.pl>
Thu, 16 Oct 2008 05:03:38 +0000 (22:03 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Oct 2008 18:21:43 +0000 (11:21 -0700)
Use modedb for initial mode instead of table of few predefined modes.

Add mode_option module parameter as a step toward unification of frame
buffers' parameters.

Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/video/cirrusfb.c

index 0eb429a..4c16b68 100644 (file)
@@ -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