提交 7ca6adb3 编写于 作者: A Adam Jackson 提交者: Dave Airlie

drm/edid: Strengthen the algorithm for standard mode codes

If you have 1920x1200 in both detailed (probably RB) and standard
variants, you probably only want the RB version.  But we have no way of
guessing that from standard mode parse.  So, if a mode already exists
for a given w/h/r, skip adding it.
Signed-off-by: NAdam Jackson <ajax@redhat.com>
Signed-off-by: NDave Airlie <airlied@redhat.com>
上级 a0910c8e
...@@ -733,12 +733,12 @@ bad_std_timing(u8 a, u8 b) ...@@ -733,12 +733,12 @@ bad_std_timing(u8 a, u8 b)
* Take the standard timing params (in this case width, aspect, and refresh) * Take the standard timing params (in this case width, aspect, and refresh)
* and convert them into a real mode using CVT/GTF/DMT. * and convert them into a real mode using CVT/GTF/DMT.
*/ */
struct drm_display_mode *drm_mode_std(struct drm_device *dev, static struct drm_display_mode *
struct std_timing *t, drm_mode_std(struct drm_connector *connector, struct std_timing *t,
int revision, int revision, int timing_level)
int timing_level)
{ {
struct drm_display_mode *mode; struct drm_device *dev = connector->dev;
struct drm_display_mode *m, *mode = NULL;
int hsize, vsize; int hsize, vsize;
int vrefresh_rate; int vrefresh_rate;
unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK)
...@@ -774,6 +774,17 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, ...@@ -774,6 +774,17 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
vsize = 768; vsize = 768;
} }
/*
* If this connector already has a mode for this size and refresh
* rate (because it came from detailed or CVT info), use that
* instead. This way we don't have to guess at interlace or
* reduced blanking.
*/
list_for_each_entry(m, &connector->modes, head)
if (m->hdisplay == hsize && m->vdisplay == vsize &&
drm_mode_vrefresh(m) == vrefresh_rate)
return NULL;
/* HDTV hack, part 2 */ /* HDTV hack, part 2 */
if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) { if (hsize == 1366 && vsize == 768 && vrefresh_rate == 60) {
mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0, mode = drm_cvt_mode(dev, 1366, 768, vrefresh_rate, 0, 0,
...@@ -784,7 +795,6 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, ...@@ -784,7 +795,6 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
return mode; return mode;
} }
mode = NULL;
/* check whether it can be found in default mode table */ /* check whether it can be found in default mode table */
mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate); mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate);
if (mode) if (mode)
...@@ -1055,17 +1065,15 @@ static int standard_timing_level(struct edid *edid) ...@@ -1055,17 +1065,15 @@ static int standard_timing_level(struct edid *edid)
*/ */
static int add_standard_modes(struct drm_connector *connector, struct edid *edid) static int add_standard_modes(struct drm_connector *connector, struct edid *edid)
{ {
struct drm_device *dev = connector->dev;
int i, modes = 0; int i, modes = 0;
int timing_level; int timing_level;
timing_level = standard_timing_level(edid); timing_level = standard_timing_level(edid);
for (i = 0; i < EDID_STD_TIMINGS; i++) { for (i = 0; i < EDID_STD_TIMINGS; i++) {
struct std_timing *t = &edid->standard_timings[i];
struct drm_display_mode *newmode; struct drm_display_mode *newmode;
newmode = drm_mode_std(dev, &edid->standard_timings[i], newmode = drm_mode_std(connector, &edid->standard_timings[i],
edid->revision, timing_level); edid->revision, timing_level);
if (newmode) { if (newmode) {
drm_mode_probed_add(connector, newmode); drm_mode_probed_add(connector, newmode);
...@@ -1362,7 +1370,7 @@ static int add_detailed_modes(struct drm_connector *connector, ...@@ -1362,7 +1370,7 @@ static int add_detailed_modes(struct drm_connector *connector,
struct drm_display_mode *newmode; struct drm_display_mode *newmode;
std = &data->data.timings[i]; std = &data->data.timings[i];
newmode = drm_mode_std(dev, std, edid->revision, newmode = drm_mode_std(connector, std, edid->revision,
timing_level); timing_level);
if (newmode) { if (newmode) {
drm_mode_probed_add(connector, newmode); drm_mode_probed_add(connector, newmode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册