diff --git a/Documentation/fb/sm501.txt b/Documentation/fb/sm501.txt new file mode 100644 index 00000000000..8d17aebd264 --- /dev/null +++ b/Documentation/fb/sm501.txt @@ -0,0 +1,10 @@ +Configuration: + +You can pass the following kernel command line options to sm501 videoframebuffer: + + sm501fb.bpp= SM501 Display driver: + Specifiy bits-per-pixel if not specified by 'mode' + + sm501fb.mode= SM501 Display driver: + Specify resolution as + "x[-][@]" diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 5df406c87c5..f31252ce889 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c @@ -41,6 +41,26 @@ #include #include +#include "edid.h" + +static char *fb_mode = "640x480-16@60"; +static unsigned long default_bpp = 16; + +static struct fb_videomode __devinitdata sm501_default_mode = { + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 20833, + .left_margin = 142, + .right_margin = 13, + .upper_margin = 21, + .lower_margin = 1, + .hsync_len = 69, + .vsync_len = 3, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED +}; + #define NR_PALETTE 256 enum sm501_controller { @@ -77,6 +97,7 @@ struct sm501fb_info { void __iomem *regs2d; /* 2d remapped registers */ void __iomem *fbmem; /* remapped framebuffer */ size_t fbmem_len; /* length of remapped region */ + u8 *edid_data; }; /* per-framebuffer private data */ @@ -1725,9 +1746,16 @@ static int sm501fb_init_fb(struct fb_info *fb, fb->var.vmode = FB_VMODE_NONINTERLACED; fb->var.bits_per_pixel = 16; + if (info->edid_data) { + /* Now build modedb from EDID */ + fb_edid_to_monspecs(info->edid_data, &fb->monspecs); + fb_videomode_to_modelist(fb->monspecs.modedb, + fb->monspecs.modedb_len, + &fb->modelist); + } + if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) { /* TODO read the mode from the current display */ - } else { if (pd->def_mode) { dev_info(info->dev, "using supplied mode\n"); @@ -1737,12 +1765,34 @@ static int sm501fb_init_fb(struct fb_info *fb, fb->var.xres_virtual = fb->var.xres; fb->var.yres_virtual = fb->var.yres; } else { - ret = fb_find_mode(&fb->var, fb, + if (info->edid_data) + ret = fb_find_mode(&fb->var, fb, fb_mode, + fb->monspecs.modedb, + fb->monspecs.modedb_len, + &sm501_default_mode, default_bpp); + else + ret = fb_find_mode(&fb->var, fb, NULL, NULL, 0, NULL, 8); - if (ret == 0 || ret == 4) { - dev_err(info->dev, - "failed to get initial mode\n"); + switch (ret) { + case 1: + dev_info(info->dev, "using mode specified in " + "@mode\n"); + break; + case 2: + dev_info(info->dev, "using mode specified in " + "@mode with ignored refresh rate\n"); + break; + case 3: + dev_info(info->dev, "using mode default " + "mode\n"); + break; + case 4: + dev_info(info->dev, "using mode from list\n"); + break; + default: + dev_info(info->dev, "ret = %d\n", ret); + dev_info(info->dev, "failed to find mode\n"); return -EINVAL; } } @@ -2157,6 +2207,11 @@ static void __exit sm501fb_cleanup(void) module_init(sm501fb_init); module_exit(sm501fb_cleanup); +module_param_named(mode, fb_mode, charp, 0); +MODULE_PARM_DESC(mode, + "Specify resolution as \"x[-][@]\" "); +module_param_named(bpp, default_bpp, ulong, 0); +MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode"); MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); MODULE_DESCRIPTION("SM501 Framebuffer driver"); MODULE_LICENSE("GPL v2");