aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2011-01-07 06:57:55 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-10 22:07:49 -0500
commitc7321d6f88e1f962d605923a93f9c255e4d0b8c9 (patch)
tree41d541c751f976b1fecec8f2d7f59751d84bb7b6 /drivers/video
parente9ab3207310e8acfa3a5cd8cbb44860f69270bfd (diff)
fbdev: sh_mobile_hdmi: add command line option to use the preferred EDID mode
Currently, if no command-line option is specified, the sh_mobile_hdmi will use the default 720p video mode. If a command line option of the form "video=sh_mobile_lcdc:<width>x<height>@<refresh>" is provided, the driver will look for that mode among those, available in the monitor EDID. This patch adds the ability to request the driver to use monitor's preferred mode by specifying 0 as width and hight in the above string. If that mode is not supported by the system, the driver will continue scanning through EDID modes, until it finds a suitable one. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/sh_mobile_hdmi.c60
1 files changed, 41 insertions, 19 deletions
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 8c59cc8c5a9c..571bd9f74513 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -737,7 +737,7 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
737 struct fb_modelist *modelist = NULL; 737 struct fb_modelist *modelist = NULL;
738 unsigned int f_width = 0, f_height = 0, f_refresh = 0; 738 unsigned int f_width = 0, f_height = 0, f_refresh = 0;
739 unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */ 739 unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
740 bool exact_match = false; 740 bool scanning = false, preferred_bad = false;
741 u8 edid[128]; 741 u8 edid[128];
742 char *forced; 742 char *forced;
743 int i; 743 int i;
@@ -800,6 +800,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
800 if (i < 2) { 800 if (i < 2) {
801 f_width = 0; 801 f_width = 0;
802 f_height = 0; 802 f_height = 0;
803 } else {
804 /* The user wants us to use the EDID data */
805 scanning = true;
803 } 806 }
804 dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n", 807 dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n",
805 f_width, f_height, f_refresh); 808 f_width, f_height, f_refresh);
@@ -807,37 +810,56 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
807 810
808 /* Walk monitor modes to find the best or the exact match */ 811 /* Walk monitor modes to find the best or the exact match */
809 for (i = 0, mode = hdmi->monspec.modedb; 812 for (i = 0, mode = hdmi->monspec.modedb;
810 f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match; 813 i < hdmi->monspec.modedb_len && scanning;
811 i++, mode++) { 814 i++, mode++) {
812 unsigned long rate_error; 815 unsigned long rate_error;
813 816
814 /* No interest in unmatching modes */ 817 if (!f_width && !f_height) {
815 if (f_width != mode->xres || f_height != mode->yres) 818 /*
819 * A parameter string "video=sh_mobile_lcdc:0x0" means
820 * use the preferred EDID mode. If it is rejected by
821 * .fb_check_var(), keep looking, until an acceptable
822 * one is found.
823 */
824 if ((mode->flag & FB_MODE_IS_FIRST) || preferred_bad)
825 scanning = false;
826 else
827 continue;
828 } else if (f_width != mode->xres || f_height != mode->yres) {
829 /* No interest in unmatching modes */
816 continue; 830 continue;
831 }
817 832
818 rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate); 833 rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate);
819 834
820 if (f_refresh == mode->refresh || (!f_refresh && !rate_error)) 835 if (scanning) {
821 /* 836 if (f_refresh == mode->refresh || (!f_refresh && !rate_error))
822 * Exact match if either the refresh rate matches or it 837 /*
823 * hasn't been specified and we've found a mode, for 838 * Exact match if either the refresh rate
824 * which we can configure the clock precisely 839 * matches or it hasn't been specified and we've
825 */ 840 * found a mode, for which we can configure the
826 exact_match = true; 841 * clock precisely
827 else if (found && found_rate_error <= rate_error) 842 */
828 /* 843 scanning = false;
829 * We otherwise search for the closest matching clock 844 else if (found && found_rate_error <= rate_error)
830 * rate - either if no refresh rate has been specified 845 /*
831 * or we cannot find an exactly matching one 846 * We otherwise search for the closest matching
832 */ 847 * clock rate - either if no refresh rate has
833 continue; 848 * been specified or we cannot find an exactly
849 * matching one
850 */
851 continue;
852 }
834 853
835 /* Check if supported: sufficient fb memory, supported clock-rate */ 854 /* Check if supported: sufficient fb memory, supported clock-rate */
836 fb_videomode_to_var(var, mode); 855 fb_videomode_to_var(var, mode);
837 856
857 var->bits_per_pixel = info->var.bits_per_pixel;
858
838 if (info && info->fbops->fb_check_var && 859 if (info && info->fbops->fb_check_var &&
839 info->fbops->fb_check_var(var, info)) { 860 info->fbops->fb_check_var(var, info)) {
840 exact_match = false; 861 scanning = true;
862 preferred_bad = true;
841 continue; 863 continue;
842 } 864 }
843 865