aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Schocher <hs@denx.de>2011-01-26 02:21:22 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-03-22 04:17:00 -0400
commite6a049807105decf5aa7f0c510f5e5ec96c3548e (patch)
tree0cbc2078c332cb4df53859b13f8e1f346f2f958c
parentbf5f0019046d596d613caf74722ba4994e153899 (diff)
video, sm501: add edid and commandline support
- add commandline options: sm501fb.mode: Specify resolution as "<xres>x<yres>[-<bpp>][@<refresh>]" sm501fb.bpp: Specify bit-per-pixel if not specified mode - Add support for encoding display mode information in the device tree using verbatim EDID block. If the "edid" entry in the "smi,sm501" node is present, the driver will build mode database using EDID data and allow setting the display modes from this database. Signed-off-by: Heiko Schocher <hs@denx.de> cc: linux-fbdev@vger.kernel.org cc: devicetree-discuss@ozlabs.org cc: Ben Dooks <ben@simtec.co.uk> cc: Vincent Sanders <vince@simtec.co.uk> cc: Samuel Ortiz <sameo@linux.intel.com> cc: linux-kernel@vger.kernel.org cc: Randy Dunlap <rdunlap@xenotime.net> cc: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--Documentation/fb/sm501.txt10
-rw-r--r--drivers/video/sm501fb.c65
2 files changed, 70 insertions, 5 deletions
diff --git a/Documentation/fb/sm501.txt b/Documentation/fb/sm501.txt
new file mode 100644
index 000000000000..8d17aebd2648
--- /dev/null
+++ b/Documentation/fb/sm501.txt
@@ -0,0 +1,10 @@
1Configuration:
2
3You can pass the following kernel command line options to sm501 videoframebuffer:
4
5 sm501fb.bpp= SM501 Display driver:
6 Specifiy bits-per-pixel if not specified by 'mode'
7
8 sm501fb.mode= SM501 Display driver:
9 Specify resolution as
10 "<xres>x<yres>[-<bpp>][@<refresh>]"
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 5df406c87c50..f31252ce8892 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -41,6 +41,26 @@
41#include <linux/sm501.h> 41#include <linux/sm501.h>
42#include <linux/sm501-regs.h> 42#include <linux/sm501-regs.h>
43 43
44#include "edid.h"
45
46static char *fb_mode = "640x480-16@60";
47static unsigned long default_bpp = 16;
48
49static struct fb_videomode __devinitdata sm501_default_mode = {
50 .refresh = 60,
51 .xres = 640,
52 .yres = 480,
53 .pixclock = 20833,
54 .left_margin = 142,
55 .right_margin = 13,
56 .upper_margin = 21,
57 .lower_margin = 1,
58 .hsync_len = 69,
59 .vsync_len = 3,
60 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
61 .vmode = FB_VMODE_NONINTERLACED
62};
63
44#define NR_PALETTE 256 64#define NR_PALETTE 256
45 65
46enum sm501_controller { 66enum sm501_controller {
@@ -77,6 +97,7 @@ struct sm501fb_info {
77 void __iomem *regs2d; /* 2d remapped registers */ 97 void __iomem *regs2d; /* 2d remapped registers */
78 void __iomem *fbmem; /* remapped framebuffer */ 98 void __iomem *fbmem; /* remapped framebuffer */
79 size_t fbmem_len; /* length of remapped region */ 99 size_t fbmem_len; /* length of remapped region */
100 u8 *edid_data;
80}; 101};
81 102
82/* per-framebuffer private data */ 103/* per-framebuffer private data */
@@ -1725,9 +1746,16 @@ static int sm501fb_init_fb(struct fb_info *fb,
1725 fb->var.vmode = FB_VMODE_NONINTERLACED; 1746 fb->var.vmode = FB_VMODE_NONINTERLACED;
1726 fb->var.bits_per_pixel = 16; 1747 fb->var.bits_per_pixel = 16;
1727 1748
1749 if (info->edid_data) {
1750 /* Now build modedb from EDID */
1751 fb_edid_to_monspecs(info->edid_data, &fb->monspecs);
1752 fb_videomode_to_modelist(fb->monspecs.modedb,
1753 fb->monspecs.modedb_len,
1754 &fb->modelist);
1755 }
1756
1728 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) { 1757 if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) {
1729 /* TODO read the mode from the current display */ 1758 /* TODO read the mode from the current display */
1730
1731 } else { 1759 } else {
1732 if (pd->def_mode) { 1760 if (pd->def_mode) {
1733 dev_info(info->dev, "using supplied mode\n"); 1761 dev_info(info->dev, "using supplied mode\n");
@@ -1737,12 +1765,34 @@ static int sm501fb_init_fb(struct fb_info *fb,
1737 fb->var.xres_virtual = fb->var.xres; 1765 fb->var.xres_virtual = fb->var.xres;
1738 fb->var.yres_virtual = fb->var.yres; 1766 fb->var.yres_virtual = fb->var.yres;
1739 } else { 1767 } else {
1740 ret = fb_find_mode(&fb->var, fb, 1768 if (info->edid_data)
1769 ret = fb_find_mode(&fb->var, fb, fb_mode,
1770 fb->monspecs.modedb,
1771 fb->monspecs.modedb_len,
1772 &sm501_default_mode, default_bpp);
1773 else
1774 ret = fb_find_mode(&fb->var, fb,
1741 NULL, NULL, 0, NULL, 8); 1775 NULL, NULL, 0, NULL, 8);
1742 1776
1743 if (ret == 0 || ret == 4) { 1777 switch (ret) {
1744 dev_err(info->dev, 1778 case 1:
1745 "failed to get initial mode\n"); 1779 dev_info(info->dev, "using mode specified in "
1780 "@mode\n");
1781 break;
1782 case 2:
1783 dev_info(info->dev, "using mode specified in "
1784 "@mode with ignored refresh rate\n");
1785 break;
1786 case 3:
1787 dev_info(info->dev, "using mode default "
1788 "mode\n");
1789 break;
1790 case 4:
1791 dev_info(info->dev, "using mode from list\n");
1792 break;
1793 default:
1794 dev_info(info->dev, "ret = %d\n", ret);
1795 dev_info(info->dev, "failed to find mode\n");
1746 return -EINVAL; 1796 return -EINVAL;
1747 } 1797 }
1748 } 1798 }
@@ -2157,6 +2207,11 @@ static void __exit sm501fb_cleanup(void)
2157module_init(sm501fb_init); 2207module_init(sm501fb_init);
2158module_exit(sm501fb_cleanup); 2208module_exit(sm501fb_cleanup);
2159 2209
2210module_param_named(mode, fb_mode, charp, 0);
2211MODULE_PARM_DESC(mode,
2212 "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
2213module_param_named(bpp, default_bpp, ulong, 0);
2214MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode");
2160MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); 2215MODULE_AUTHOR("Ben Dooks, Vincent Sanders");
2161MODULE_DESCRIPTION("SM501 Framebuffer driver"); 2216MODULE_DESCRIPTION("SM501 Framebuffer driver");
2162MODULE_LICENSE("GPL v2"); 2217MODULE_LICENSE("GPL v2");