diff options
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/cirrusfb.c | 126 |
1 files changed, 21 insertions, 105 deletions
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 0eb429a35732..4c16b68a9c5a 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -372,98 +372,8 @@ struct cirrusfb_info { | |||
372 | void (*unmap)(struct fb_info *info); | 372 | void (*unmap)(struct fb_info *info); |
373 | }; | 373 | }; |
374 | 374 | ||
375 | static unsigned cirrusfb_def_mode = 1; | ||
376 | static int noaccel; | 375 | static int noaccel; |
377 | 376 | static char *mode_option __devinitdata = "640x480@60"; | |
378 | /* | ||
379 | * Predefined Video Modes | ||
380 | */ | ||
381 | |||
382 | static const struct { | ||
383 | const char *name; | ||
384 | struct fb_var_screeninfo var; | ||
385 | } cirrusfb_predefined[] = { | ||
386 | { | ||
387 | /* autodetect mode */ | ||
388 | .name = "Autodetect", | ||
389 | }, { | ||
390 | /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */ | ||
391 | .name = "640x480", | ||
392 | .var = { | ||
393 | .xres = 640, | ||
394 | .yres = 480, | ||
395 | .xres_virtual = 640, | ||
396 | .yres_virtual = 480, | ||
397 | .bits_per_pixel = 8, | ||
398 | .red = { .length = 8 }, | ||
399 | .green = { .length = 8 }, | ||
400 | .blue = { .length = 8 }, | ||
401 | .width = -1, | ||
402 | .height = -1, | ||
403 | .pixclock = 40000, | ||
404 | .left_margin = 48, | ||
405 | .right_margin = 16, | ||
406 | .upper_margin = 32, | ||
407 | .lower_margin = 8, | ||
408 | .hsync_len = 96, | ||
409 | .vsync_len = 4, | ||
410 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
411 | .vmode = FB_VMODE_NONINTERLACED | ||
412 | } | ||
413 | }, { | ||
414 | /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */ | ||
415 | .name = "800x600", | ||
416 | .var = { | ||
417 | .xres = 800, | ||
418 | .yres = 600, | ||
419 | .xres_virtual = 800, | ||
420 | .yres_virtual = 600, | ||
421 | .bits_per_pixel = 8, | ||
422 | .red = { .length = 8 }, | ||
423 | .green = { .length = 8 }, | ||
424 | .blue = { .length = 8 }, | ||
425 | .width = -1, | ||
426 | .height = -1, | ||
427 | .pixclock = 20000, | ||
428 | .left_margin = 128, | ||
429 | .right_margin = 16, | ||
430 | .upper_margin = 24, | ||
431 | .lower_margin = 2, | ||
432 | .hsync_len = 96, | ||
433 | .vsync_len = 6, | ||
434 | .vmode = FB_VMODE_NONINTERLACED | ||
435 | } | ||
436 | }, { | ||
437 | /* | ||
438 | * Modeline from XF86Config: | ||
439 | * Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805 | ||
440 | */ | ||
441 | /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */ | ||
442 | .name = "1024x768", | ||
443 | .var = { | ||
444 | .xres = 1024, | ||
445 | .yres = 768, | ||
446 | .xres_virtual = 1024, | ||
447 | .yres_virtual = 768, | ||
448 | .bits_per_pixel = 8, | ||
449 | .red = { .length = 8 }, | ||
450 | .green = { .length = 8 }, | ||
451 | .blue = { .length = 8 }, | ||
452 | .width = -1, | ||
453 | .height = -1, | ||
454 | .pixclock = 12500, | ||
455 | .left_margin = 144, | ||
456 | .right_margin = 32, | ||
457 | .upper_margin = 30, | ||
458 | .lower_margin = 2, | ||
459 | .hsync_len = 192, | ||
460 | .vsync_len = 6, | ||
461 | .vmode = FB_VMODE_NONINTERLACED | ||
462 | } | ||
463 | } | ||
464 | }; | ||
465 | |||
466 | #define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined) | ||
467 | 377 | ||
468 | /****************************************************************************/ | 378 | /****************************************************************************/ |
469 | /**** BEGIN PROTOTYPES ******************************************************/ | 379 | /**** BEGIN PROTOTYPES ******************************************************/ |
@@ -2267,23 +2177,27 @@ static int cirrusfb_register(struct fb_info *info) | |||
2267 | /* sanity checks */ | 2177 | /* sanity checks */ |
2268 | assert(btype != BT_NONE); | 2178 | assert(btype != BT_NONE); |
2269 | 2179 | ||
2180 | /* set all the vital stuff */ | ||
2181 | cirrusfb_set_fbinfo(info); | ||
2182 | |||
2270 | DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); | 2183 | DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); |
2271 | 2184 | ||
2272 | /* Make pretend we've set the var so our structures are in a "good" */ | 2185 | err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); |
2273 | /* state, even though we haven't written the mode to the hw yet... */ | 2186 | if (!err) { |
2274 | info->var = cirrusfb_predefined[cirrusfb_def_mode].var; | 2187 | DPRINTK("wrong initial video mode\n"); |
2188 | err = -EINVAL; | ||
2189 | goto err_dealloc_cmap; | ||
2190 | } | ||
2191 | |||
2275 | info->var.activate = FB_ACTIVATE_NOW; | 2192 | info->var.activate = FB_ACTIVATE_NOW; |
2276 | 2193 | ||
2277 | err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); | 2194 | err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); |
2278 | if (err < 0) { | 2195 | if (err < 0) { |
2279 | /* should never happen */ | 2196 | /* should never happen */ |
2280 | DPRINTK("choking on default var... umm, no good.\n"); | 2197 | DPRINTK("choking on default var... umm, no good.\n"); |
2281 | goto err_unmap_cirrusfb; | 2198 | goto err_dealloc_cmap; |
2282 | } | 2199 | } |
2283 | 2200 | ||
2284 | /* set all the vital stuff */ | ||
2285 | cirrusfb_set_fbinfo(info); | ||
2286 | |||
2287 | err = register_framebuffer(info); | 2201 | err = register_framebuffer(info); |
2288 | if (err < 0) { | 2202 | if (err < 0) { |
2289 | printk(KERN_ERR "cirrusfb: could not register " | 2203 | printk(KERN_ERR "cirrusfb: could not register " |
@@ -2296,7 +2210,6 @@ static int cirrusfb_register(struct fb_info *info) | |||
2296 | 2210 | ||
2297 | err_dealloc_cmap: | 2211 | err_dealloc_cmap: |
2298 | fb_dealloc_cmap(&info->cmap); | 2212 | fb_dealloc_cmap(&info->cmap); |
2299 | err_unmap_cirrusfb: | ||
2300 | cinfo->unmap(info); | 2213 | cinfo->unmap(info); |
2301 | framebuffer_release(info); | 2214 | framebuffer_release(info); |
2302 | return err; | 2215 | return err; |
@@ -2608,17 +2521,17 @@ static int __init cirrusfb_setup(char *options) { | |||
2608 | return 0; | 2521 | return 0; |
2609 | 2522 | ||
2610 | while ((this_opt = strsep(&options, ",")) != NULL) { | 2523 | while ((this_opt = strsep(&options, ",")) != NULL) { |
2611 | if (!*this_opt) continue; | 2524 | if (!*this_opt) |
2525 | continue; | ||
2612 | 2526 | ||
2613 | DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); | 2527 | DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); |
2614 | 2528 | ||
2615 | for (i = 0; i < NUM_TOTAL_MODES; i++) { | ||
2616 | sprintf(s, "mode:%s", cirrusfb_predefined[i].name); | ||
2617 | if (strcmp(this_opt, s) == 0) | ||
2618 | cirrusfb_def_mode = i; | ||
2619 | } | ||
2620 | if (!strcmp(this_opt, "noaccel")) | 2529 | if (!strcmp(this_opt, "noaccel")) |
2621 | noaccel = 1; | 2530 | noaccel = 1; |
2531 | else if (!strncmp(this_opt, "mode:", 5)) | ||
2532 | mode_option = this_opt + 5; | ||
2533 | else | ||
2534 | mode_option = this_opt; | ||
2622 | } | 2535 | } |
2623 | return 0; | 2536 | return 0; |
2624 | } | 2537 | } |
@@ -2644,6 +2557,9 @@ static void __exit cirrusfb_exit(void) | |||
2644 | 2557 | ||
2645 | module_init(cirrusfb_init); | 2558 | module_init(cirrusfb_init); |
2646 | 2559 | ||
2560 | module_param(mode_option, charp, 0); | ||
2561 | MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); | ||
2562 | |||
2647 | #ifdef MODULE | 2563 | #ifdef MODULE |
2648 | module_exit(cirrusfb_exit); | 2564 | module_exit(cirrusfb_exit); |
2649 | #endif | 2565 | #endif |