diff options
author | Heiko Schocher <hs@denx.de> | 2011-01-26 02:21:22 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-03-22 04:17:00 -0400 |
commit | e6a049807105decf5aa7f0c510f5e5ec96c3548e (patch) | |
tree | 0cbc2078c332cb4df53859b13f8e1f346f2f958c | |
parent | bf5f0019046d596d613caf74722ba4994e153899 (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.txt | 10 | ||||
-rw-r--r-- | drivers/video/sm501fb.c | 65 |
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 @@ | |||
1 | Configuration: | ||
2 | |||
3 | You 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 | |||
46 | static char *fb_mode = "640x480-16@60"; | ||
47 | static unsigned long default_bpp = 16; | ||
48 | |||
49 | static 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 | ||
46 | enum sm501_controller { | 66 | enum 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) | |||
2157 | module_init(sm501fb_init); | 2207 | module_init(sm501fb_init); |
2158 | module_exit(sm501fb_cleanup); | 2208 | module_exit(sm501fb_cleanup); |
2159 | 2209 | ||
2210 | module_param_named(mode, fb_mode, charp, 0); | ||
2211 | MODULE_PARM_DESC(mode, | ||
2212 | "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); | ||
2213 | module_param_named(bpp, default_bpp, ulong, 0); | ||
2214 | MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode"); | ||
2160 | MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); | 2215 | MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); |
2161 | MODULE_DESCRIPTION("SM501 Framebuffer driver"); | 2216 | MODULE_DESCRIPTION("SM501 Framebuffer driver"); |
2162 | MODULE_LICENSE("GPL v2"); | 2217 | MODULE_LICENSE("GPL v2"); |