Commit c7321d6f authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Paul Mundt

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: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent e9ab3207
...@@ -737,7 +737,7 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate, ...@@ -737,7 +737,7 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
struct fb_modelist *modelist = NULL; struct fb_modelist *modelist = NULL;
unsigned int f_width = 0, f_height = 0, f_refresh = 0; unsigned int f_width = 0, f_height = 0, f_refresh = 0;
unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */ unsigned long found_rate_error = ULONG_MAX; /* silly compiler... */
bool exact_match = false; bool scanning = false, preferred_bad = false;
u8 edid[128]; u8 edid[128];
char *forced; char *forced;
int i; int i;
...@@ -800,6 +800,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate, ...@@ -800,6 +800,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
if (i < 2) { if (i < 2) {
f_width = 0; f_width = 0;
f_height = 0; f_height = 0;
} else {
/* The user wants us to use the EDID data */
scanning = true;
} }
dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n", dev_dbg(hdmi->dev, "Forced mode %ux%u@%uHz\n",
f_width, f_height, f_refresh); 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,37 +810,56 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi, unsigned long *hdmi_rate,
/* Walk monitor modes to find the best or the exact match */ /* Walk monitor modes to find the best or the exact match */
for (i = 0, mode = hdmi->monspec.modedb; for (i = 0, mode = hdmi->monspec.modedb;
f_width && f_height && i < hdmi->monspec.modedb_len && !exact_match; i < hdmi->monspec.modedb_len && scanning;
i++, mode++) { i++, mode++) {
unsigned long rate_error; unsigned long rate_error;
/* No interest in unmatching modes */ if (!f_width && !f_height) {
if (f_width != mode->xres || f_height != mode->yres) /*
* A parameter string "video=sh_mobile_lcdc:0x0" means
* use the preferred EDID mode. If it is rejected by
* .fb_check_var(), keep looking, until an acceptable
* one is found.
*/
if ((mode->flag & FB_MODE_IS_FIRST) || preferred_bad)
scanning = false;
else
continue;
} else if (f_width != mode->xres || f_height != mode->yres) {
/* No interest in unmatching modes */
continue; continue;
}
rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate); rate_error = sh_hdmi_rate_error(hdmi, mode, hdmi_rate, parent_rate);
if (f_refresh == mode->refresh || (!f_refresh && !rate_error)) if (scanning) {
/* if (f_refresh == mode->refresh || (!f_refresh && !rate_error))
* Exact match if either the refresh rate matches or it /*
* hasn't been specified and we've found a mode, for * Exact match if either the refresh rate
* which we can configure the clock precisely * matches or it hasn't been specified and we've
*/ * found a mode, for which we can configure the
exact_match = true; * clock precisely
else if (found && found_rate_error <= rate_error) */
/* scanning = false;
* We otherwise search for the closest matching clock else if (found && found_rate_error <= rate_error)
* rate - either if no refresh rate has been specified /*
* or we cannot find an exactly matching one * We otherwise search for the closest matching
*/ * clock rate - either if no refresh rate has
continue; * been specified or we cannot find an exactly
* matching one
*/
continue;
}
/* Check if supported: sufficient fb memory, supported clock-rate */ /* Check if supported: sufficient fb memory, supported clock-rate */
fb_videomode_to_var(var, mode); fb_videomode_to_var(var, mode);
var->bits_per_pixel = info->var.bits_per_pixel;
if (info && info->fbops->fb_check_var && if (info && info->fbops->fb_check_var &&
info->fbops->fb_check_var(var, info)) { info->fbops->fb_check_var(var, info)) {
exact_match = false; scanning = true;
preferred_bad = true;
continue; continue;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment