Bogus video resolution in Linux 3.5-rc4
Subsystems (2)
After upgrading to Linux 3.5-rc4 from 3.4.4, I noticed that my monitor switched to a resolution of 1280x960 rather than the native 1280x1024, and nouveau has set up a framebuffer of 1680x945. It goes without saying that the result looks terrible.
Bisecting shows that the problem started with commit cb21aafe1:
--8<---------------cut here---------------start------------->8--- commit cb21aafe121b1c3ad4c77cc5c22320163f16ba42
Author: Adam Jackson <[email protected]> Date: Fri Apr 13 16:33:36 2012 -0400
drm/edid: Do drm_dmt_modes_for_range() for all range descriptor types
EDID 1.4 retcons the meaning of the "GTF feature" bit to mean "is continuous frequency", and moves the set of supported timing formulas into the range descriptor itself. In any event, the range descriptor can act as a filter on the DMT list without regard to a specific timing formula.
drivers/gpu/drm/drm_edid.c +6 -5
@@ -1042,12 +1042,13 @@ do_inferred_modes(struct detailed_timing *timing, void *c) {struct detailed_mode_closure *closure = c;struct detailed_non_pixel *data = &timing->data.other_data; -int gtf = (closure->edid->features &DRM_EDID_FEATURE_DEFAULT_GTF ); -if (gtf && data->type ==EDID_DETAIL_MONITOR_RANGE ) - closure->modes +=drm_dmt_modes_for_range (closure->connector, - closure->edid, - timing); +if (data->type !=EDID_DETAIL_MONITOR_RANGE ) +return ; + + closure->modes +=drm_dmt_modes_for_range (closure->connector, + closure->edid, + timing); } static int
--8<---------------cut here---------------end--------------->8---
With a kernel from this commit nouveau sets up a resolution of 1400x1050; kernels built from commits cffd754 and fc48f16 complain about an invalid EDID and use the 1024x768 fallback.
Attached is the /sys/class/drm/card0-DVI-I-1/edid file from a working kernel; in 3.5-rc4 it is identical.
Cheers,
Sven
At Mon, 25 Jun 2012 16:03:36 +0200,
Quoted 51 lines · Sven Joachim
After upgrading to Linux 3.5-rc4 from 3.4.4, I noticed that my monitor switched to a resolution of 1280x960 rather than the native 1280x1024, and nouveau has set up a framebuffer of 1680x945. It goes without saying that the result looks terrible.
Bisecting shows that the problem started with commit
cb21aafe1:--8<---------------cut here---------------start------------->8--- commit
cb21aafe121b1c3ad4c77cc5c22320163f16ba42Author: Adam Jackson <[email protected]> Date: Fri Apr 13 16:33:36 2012 -0400drm/edid: Do
drm_dmt_modes_for_range()for all range descriptor typesEDID 1.4 retcons the meaning of the "GTF feature" bit to mean "is continuous frequency", and moves the set of supported timing formulas into the range descriptor itself. In any event, the range descriptor can act as a filter on the DMT list without regard to a specific timing formula.
Signed-off-by Adam Jackson <[email protected]>Tested-by Takashi Iwai <[email protected]>Reviewed-by Rodrigo Vivi <[email protected]>Signed-off-by Dave Airlie <[email protected]>drivers/gpu/drm/drm_edid.c +6
-6@@ -1042,12 +1042,13 @@ do_inferred_modes(struct detailed_timing *timing, void *c) {struct detailed_mode_closure *closure = c;struct detailed_non_pixel *data = &timing->data.other_data; -int gtf = (closure->edid->features &DRM_EDID_FEATURE_DEFAULT_GTF ); -if (gtf && data->type ==EDID_DETAIL_MONITOR_RANGE ) - closure->modes +=drm_dmt_modes_for_range (closure->connector, - closure->edid, - timing); +if (data->type !=EDID_DETAIL_MONITOR_RANGE ) +return ; + + closure->modes +=drm_dmt_modes_for_range (closure->connector, + closure->edid, + timing); } static int --8<---------------cut here---------------end--------------->8---
Quoted 6 lines
With a kernel from this commit nouveau sets up a resolution of 1400x1050; kernels built from commits cffd754 and fc48f16 complain about an invalid EDID and use the 1024x768 fallback.
Attached is the
/sys/class/drm/card0-DVI-I-1/edidfile from a working kernel; in 3.5-rc4 it is identical.
Looking at the EDID data, the problem is likely that your monitor doesn't give the proper preferred mode.
What does xrandr output show?
And, does the patch below help?
Takashi
---
drivers/gpu/drm/drm_edid.c +4 -1
@@ -116,6 +116,7 @@ static struct edid_quirk {/* Proview AY765C */ { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, + { "PTS", 793, EDID_QUIRK_FIRST_DETAILED_PREFERRED },/* Samsung SyncMaster 205BW. Note: irony */ { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },
@@ -1404,7 +1405,9 @@ do_detailed_mode(struct detailed_timing *timing, void *c)if (!newmode)return ; -if (closure->preferred) +if (closure->preferred || + ((closure->quirks &EDID_QUIRK_FIRST_DETAILED_PREFERRED ) && + !closure->modes)) newmode->type |=DRM_MODE_TYPE_PREFERRED ;drm_mode_probed_add (closure->connector, newmode);
At Mon, 25 Jun 2012 17:53:12 +0200,
Quoted 2 lines · Takashi Iwai
And, does the patch below help?
BTW, the patch below contains the possible generic fix.
It seems that EDID_QUIRK_FIRST_DETAILED_PREFERRED handling is missing from the beginning. So I wrote it just from what I can imagine from the comment:
/* Monitor forgot to set the first detailed is preferred bit. */
#define EDID_QUIRK_FIRST_DETAILED_PREFERRED (1 << 5)
Adam, is my interpretation correct?
Takashi
Quoted 28 lines
Takashi
---
drivers/gpu/drm/drm_edid.c +4
-1@@ -116,6 +116,7 @@ static struct edid_quirk {/* Proview AY765C */ { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, + { "PTS", 793, EDID_QUIRK_FIRST_DETAILED_PREFERRED },/* Samsung SyncMaster 205BW. Note: irony */ { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },@@ -1404,7 +1405,9 @@ do_detailed_mode(struct detailed_timing *timing, void *c)if (!newmode)return ; -if (closure->preferred) +if (closure->preferred || + ((closure->quirks &EDID_QUIRK_FIRST_DETAILED_PREFERRED ) && + !closure->modes)) newmode->type |=DRM_MODE_TYPE_PREFERRED ;drm_mode_probed_add (closure->connector, newmode);
Am 25.06.2012 um 17:53 schrieb Takashi Iwai:
Quoted 3 lines
Looking at the EDID data, the problem is likely that your monitor doesn't give the proper preferred mode.
What does xrandr output show?
,----
| Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 8192 x 8192 | DVI-I-1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 376mm x 301mm | 1280x1024 75.0* 60.0 | 1024x768 75.1 75.0 70.1 60.0 | 832x624 74.6 | 800x600 72.2 75.0 60.3 56.2 | 640x480 72.8 75.0 66.7 60.0 59.9 | VGA-1 disconnected (normal left inverted right x axis y axis)
`----
I should note that the monitor is actually connected via VGA, not DVI. This seems to be similar to https://bugs.freedesktop.org/50830, but since it never caused any real problems for me, I didn't bother.
Quoted 1 line
And, does the patch below help?
Somewhat: at least I get 1280x1024 again, but at 60 rather than 75 Hz. The xrandr command shows various bogus modes.
,----
| Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 8192 x 8192 | DVI-I-1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 376mm x 301mm | 1280x1024 60.0*+ 75.0 | 1680x945 60.0 | 1400x1050 60.0 | 1600x900 60.0 | 1440x900 75.0 59.9 | 1280x960 60.0 | 1366x768 60.0 | 1360x768 60.0 | 1280x800 74.9 59.8 | 1152x864 75.0 | 1280x768 74.9 59.9 | 1024x768 75.1 75.0 70.1 60.0 | 1024x576 60.0 | 832x624 74.6 | 800x600 72.2 75.0 60.3 56.2 | 848x480 60.0 | 640x480 75.0 72.8 72.8 66.7 60.0 59.9 | VGA-1 disconnected (normal left inverted right x axis y axis)
`----
Cheers,
Sven
Quoted 24 lines
---
drivers/gpu/drm/drm_edid.c +4
-1@@ -116,6 +116,7 @@ static struct edid_quirk {/* Proview AY765C */ { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, + { "PTS", 793, EDID_QUIRK_FIRST_DETAILED_PREFERRED },/* Samsung SyncMaster 205BW. Note: irony */ { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },@@ -1404,7 +1405,9 @@ do_detailed_mode(struct detailed_timing *timing, void *c)if (!newmode)return ; -if (closure->preferred) +if (closure->preferred || + ((closure->quirks &EDID_QUIRK_FIRST_DETAILED_PREFERRED ) && + !closure->modes)) newmode->type |=DRM_MODE_TYPE_PREFERRED ;drm_mode_probed_add (closure->connector, newmode);
Quoted 3 lines · Sven Joachim
Quoted 1 line
And, does the patch below help?
Somewhat: at least I get 1280x1024 again, but at 60 rather than 75 Hz.
That is, in fact, what your monitor claims to prefer.
Quoted 1 line
The xrandr command shows various bogus modes.
Most of which my patch series would eliminate.
- ajax
At Mon, 25 Jun 2012 19:40:48 +0200,
Quoted 18 lines · Sven Joachim
Am 25.06.2012 um 17:53 schrieb Takashi Iwai:
Quoted 3 lines
Looking at the EDID data, the problem is likely that your monitor doesn't give the proper preferred mode.
What does xrandr output show?,----
| Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 8192 x 8192 | DVI-I-1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 376mm x 301mm | 1280x1024 75.0* 60.0 | 1024x768 75.1 75.0 70.1 60.0 | 832x624 74.6 | 800x600 72.2 75.0 60.3 56.2 | 640x480 72.8 75.0 66.7 60.0 59.9 | VGA-1 disconnected (normal left inverted right x axis y axis)`----
Quoted 7 lines
I should note that the monitor is actually connected via VGA, not DVI. This seems to be similar to https://bugs.freedesktop.org/50830, but since it never caused any real problems for me, I didn't bother.
Quoted 1 line
And, does the patch below help?
Somewhat: at least I get 1280x1024 again, but at 60 rather than 75 Hz.
I guess it worked casually because 1280x1024@75 was the highest resolution / rate, so it was picked up as the preferred mode...
Quoted 1 line
The xrandr command shows various bogus modes.
Can't these values be displayed on your monitor at all? If they can be displayed, they are valid modes, not really bogus. After all, they are values that EDID of your montor advertises as available ranges.
Takashi
Quoted 52 lines
,----
| Screen 0: minimum 320 x 200, current 1280 x 1024, maximum 8192 x 8192 | DVI-I-1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 376mm x 301mm | 1280x1024 60.0*+ 75.0 | 1680x945 60.0 | 1400x1050 60.0 | 1600x900 60.0 | 1440x900 75.0 59.9 | 1280x960 60.0 | 1366x768 60.0 | 1360x768 60.0 | 1280x800 74.9 59.8 | 1152x864 75.0 | 1280x768 74.9 59.9 | 1024x768 75.1 75.0 70.1 60.0 | 1024x576 60.0 | 832x624 74.6 | 800x600 72.2 75.0 60.3 56.2 | 848x480 60.0 | 640x480 75.0 72.8 72.8 66.7 60.0 59.9 | VGA-1 disconnected (normal left inverted right x axis y axis)`----
Cheers,
SvenQuoted 24 lines
---
drivers/gpu/drm/drm_edid.c +4
-1@@ -116,6 +116,7 @@ static struct edid_quirk {/* Proview AY765C */ { "PTS", 765, EDID_QUIRK_FIRST_DETAILED_PREFERRED }, + { "PTS", 793, EDID_QUIRK_FIRST_DETAILED_PREFERRED },/* Samsung SyncMaster 205BW. Note: irony */ { "SAM", 541, EDID_QUIRK_DETAILED_SYNC_PP },@@ -1404,7 +1405,9 @@ do_detailed_mode(struct detailed_timing *timing, void *c)if (!newmode)return ; -if (closure->preferred) +if (closure->preferred || + ((closure->quirks &EDID_QUIRK_FIRST_DETAILED_PREFERRED ) && + !closure->modes)) newmode->type |=DRM_MODE_TYPE_PREFERRED ;drm_mode_probed_add (closure->connector, newmode);
Am 25.06.2012 um 21:24 schrieb Takashi Iwai:
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
And, does the patch below help?
Somewhat: at least I get 1280x1024 again, but at 60 rather than 75 Hz.
I guess it worked casually because 1280x1024@75 was the highest resolution / rate, so it was picked up as the preferred mode...
Quite possible. Problem is that 1280x1024@60 looks worse, so I'd like to get the 75 Hz back.
Quoted 3 lines
Quoted 1 line
The xrandr command shows various bogus modes.
Can't these values be displayed on your monitor at all?
It's a TFT LCD with 1280x1024 pixels.
Cheers,
Sven
At Mon, 25 Jun 2012 21:38:56 +0200,
Quoted 10 lines · Sven Joachim
Am 25.06.2012 um 21:24 schrieb Takashi Iwai:
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
And, does the patch below help?
Somewhat: at least I get 1280x1024 again, but at 60 rather than 75 Hz.
I guess it worked casually because 1280x1024@75 was the highest resolution / rate, so it was picked up as the preferred mode...
Quoted 8 lines
Quite possible. Problem is that 1280x1024@60 looks worse, so I'd like to get the 75 Hz back.
Quoted 3 lines
Quoted 1 line
The xrandr command shows various bogus modes.
Can't these values be displayed on your monitor at all?
It's a TFT LCD with 1280x1024 pixels.
Yes, but displaying higher resolutions wasn't too uncommon in the earlier VGA days. So, this doesn't mean the higher modes are "bogus" as long they are in the range the monitor itself advertises.
On the second thought, if there are many such broken monitors, it might be safer to exclude the inferred modes with higher resolutions.
The original problem was that the resolution like 1366x768 or 1600x900 doesn't appear in the mode list. These are supposed to be lower than the native. Restricting the higher resolutions won't regress for these problems.
The patch below is a quick fix.
Takashi
---
From: Takashi Iwai <[email protected]>
Subject: [PATCH] drm: edid: Don't add inferred modes with higher resolution
When a monitor EDID doesn't give the preferred bit, driver assumes that the mode with the higest resolution and rate is the preferred mode. Meanwhile the recent changes for allowing more modes in the GFT/CVT ranges give actually more modes, and some modes may be over the native size. Thus such a mode would be picked up as the preferred mode although it's no native resolution.
For avoiding such a problem, this patch limits the addition of inferred modes by checking not to be greater than other modes. Also, it checks the duplicated mode entry at the same time.
--- drivers/gpu/drm/drm_edid.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
drivers/gpu/drm/drm_edid.c +24 -3
@@ -1039,6 +1039,24 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid,return true; } +static bool valid_inferred_mode (const struct drm_connector *connector, +const struct drm_display_mode *mode) +{ +struct drm_display_mode *m; +bool ok = false; + +list_for_each_entry (m, &connector->probed_modes, head) { +if (mode->hdisplay == m->hdisplay && + mode->vdisplay == m->vdisplay && +drm_mode_vrefresh (mode) ==drm_mode_vrefresh (m)) +return false;/* duplicated */ +if (mode->hdisplay <= m->hdisplay && + mode->vdisplay <= m->vdisplay) + ok = true; + } +return ok; +} +static int drm_dmt_modes_for_range (struct drm_connector *connector,struct edid *edid,struct detailed_timing *timing)
@@ -1048,7 +1066,8 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,struct drm_device *dev = connector->dev;for (i =0 ; i < drm_num_dmt_modes; i++) { -if (mode_in_range (drm_dmt_modes + i, edid, timing)) { +if (mode_in_range (drm_dmt_modes + i, edid, timing) && +valid_inferred_mode (connector, drm_dmt_modes + i)) { newmode =drm_mode_duplicate (dev, &drm_dmt_modes[i]);if (newmode) {drm_mode_probed_add (connector, newmode);
@@ -1088,7 +1107,8 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,return modes;fixup_mode_1366x768 (newmode); -if (!mode_in_range (newmode, edid, timing)) { +if (!mode_in_range (newmode, edid, timing) || + !valid_inferred_mode (connector, newmode)) {drm_mode_destroy (dev, newmode);continue ; }
@@ -1116,7 +1136,8 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,return modes;fixup_mode_1366x768 (newmode); -if (!mode_in_range (newmode, edid, timing)) { +if (!mode_in_range (newmode, edid, timing) || + !valid_inferred_mode (connector, newmode)) {drm_mode_destroy (dev, newmode);continue ; }
Signature · 1 line
1.7.10.4
Quoted 108 lines · Takashi Iwai
At Mon, 25 Jun 2012 21:38:56 +0200,
Quoted 10 lines · Sven Joachim
Am 25.06.2012 um 21:24 schrieb Takashi Iwai:
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
And, does the patch below help?
Somewhat: at least I get 1280x1024 again, but at 60 rather than 75 Hz.
I guess it worked casually because 1280x1024@75 was the highest resolution / rate, so it was picked up as the preferred mode...
Quoted 8 lines
Quite possible. Problem is that 1280x1024@60 looks worse, so I'd like to get the 75 Hz back.
Quoted 3 lines
Quoted 1 line
The xrandr command shows various bogus modes.
Can't these values be displayed on your monitor at all?
It's a TFT LCD with 1280x1024 pixels.
Yes, but displaying higher resolutions wasn't too uncommon in the earlier VGA days. So, this doesn't mean the higher modes are "bogus" as long they are in the range the monitor itself advertises.
On the second thought, if there are many such broken monitors, it might be safer to exclude the inferred modes with higher resolutions.
The original problem was that the resolution like 1366x768 or 1600x900 doesn't appear in the mode list. These are supposed to be lower than the native. Restricting the higher resolutions won't regress for these problems.
The patch below is a quick fix.
Takashi
---
From: Takashi Iwai <[email protected]>
Subject: [PATCH] drm: edid: Don't add inferred modes with higher resolutionWhen a monitor EDID doesn't give the preferred bit, driver assumes that the mode with the higest resolution and rate is the preferred mode. Meanwhile the recent changes for allowing more modes in the GFT/CVT ranges give actually more modes, and some modes may be over the native size. Thus such a mode would be picked up as the preferred mode although it's no native resolution.
For avoiding such a problem, this patch limits the addition of inferred modes by checking not to be greater than other modes. Also, it checks the duplicated mode entry at the same time.
Signed-off-by Takashi Iwai <[email protected]>--- drivers/gpu/drm/drm_edid.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)drivers/gpu/drm/drm_edid.c +22
-2@@ -1039,6 +1039,24 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid,return true; } +static bool valid_inferred_mode (const struct drm_connector *connector, +const struct drm_display_mode *mode) +{ +struct drm_display_mode *m; +bool ok = false; + +list_for_each_entry (m, &connector->probed_modes, head) { +if (mode->hdisplay == m->hdisplay && + mode->vdisplay == m->vdisplay && +drm_mode_vrefresh (mode) ==drm_mode_vrefresh (m)) +return false;/* duplicated */ +if (mode->hdisplay <= m->hdisplay && + mode->vdisplay <= m->vdisplay) + ok = true; + } +return ok; +} +static int drm_dmt_modes_for_range (struct drm_connector *connector,struct edid *edid,struct detailed_timing *timing)@@ -1048,7 +1066,8 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,struct drm_device *dev = connector->dev;for (i =0 ; i < drm_num_dmt_modes; i++) { -if (mode_in_range (drm_dmt_modes + i, edid, timing)) { +if (mode_in_range (drm_dmt_modes + i, edid, timing) && +valid_inferred_mode (connector, drm_dmt_modes + i)) { newmode =drm_mode_duplicate (dev, &drm_dmt_modes[i]);if (newmode) {drm_mode_probed_add (connector, newmode);@@ -1088,7 +1107,8 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,return modes;fixup_mode_1366x768 (newmode); -if (!mode_in_range (newmode, edid, timing)) { +if (!mode_in_range (newmode, edid, timing) || + !valid_inferred_mode (connector, newmode)) {drm_mode_destroy (dev, newmode);continue ; }
drivers/gpu/drm/drm_edid.c drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid, · line 1143
Quoted 9 lines
drivers/gpu/drm/drm_edid.c +2
-1@@ -1116,7 +1136,8 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,return modes;fixup_mode_1366x768 (newmode); -if (!mode_in_range (newmode, edid, timing)) { +if (!mode_in_range (newmode, edid, timing) || + !valid_inferred_mode (connector, newmode)) {drm_mode_destroy (dev, newmode);continue ; }
Hello all,
I had the exact same problem as Sven, bisected to cb21aafe121b1c3ad4c77cc5c22320163f16ba42. Takashi's patch (supra) fixes the issue for me.
Regards,
Calvin Owens
At Sat, 30 Jun 2012 13:46:54 -0500,
Quoted 122 lines · Calvin Owens
Quoted 108 lines · Takashi Iwai
At Mon, 25 Jun 2012 21:38:56 +0200,
Quoted 10 lines · Sven Joachim
Am 25.06.2012 um 21:24 schrieb Takashi Iwai:
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
And, does the patch below help?
Somewhat: at least I get 1280x1024 again, but at 60 rather than 75 Hz.
I guess it worked casually because 1280x1024@75 was the highest resolution / rate, so it was picked up as the preferred mode...
Quoted 8 lines
Quite possible. Problem is that 1280x1024@60 looks worse, so I'd like to get the 75 Hz back.
Quoted 3 lines
Quoted 1 line
The xrandr command shows various bogus modes.
Can't these values be displayed on your monitor at all?
It's a TFT LCD with 1280x1024 pixels.
Yes, but displaying higher resolutions wasn't too uncommon in the earlier VGA days. So, this doesn't mean the higher modes are "bogus" as long they are in the range the monitor itself advertises.
On the second thought, if there are many such broken monitors, it might be safer to exclude the inferred modes with higher resolutions.
The original problem was that the resolution like 1366x768 or 1600x900 doesn't appear in the mode list. These are supposed to be lower than the native. Restricting the higher resolutions won't regress for these problems.
The patch below is a quick fix.
Takashi
---
From: Takashi Iwai <[email protected]>
Subject: [PATCH] drm: edid: Don't add inferred modes with higher resolutionWhen a monitor EDID doesn't give the preferred bit, driver assumes that the mode with the higest resolution and rate is the preferred mode. Meanwhile the recent changes for allowing more modes in the GFT/CVT ranges give actually more modes, and some modes may be over the native size. Thus such a mode would be picked up as the preferred mode although it's no native resolution.
For avoiding such a problem, this patch limits the addition of inferred modes by checking not to be greater than other modes. Also, it checks the duplicated mode entry at the same time.
Signed-off-by Takashi Iwai <[email protected]>--- drivers/gpu/drm/drm_edid.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)drivers/gpu/drm/drm_edid.c +22
-2@@ -1039,6 +1039,24 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid,return true; } +static bool valid_inferred_mode (const struct drm_connector *connector, +const struct drm_display_mode *mode) +{ +struct drm_display_mode *m; +bool ok = false; + +list_for_each_entry (m, &connector->probed_modes, head) { +if (mode->hdisplay == m->hdisplay && + mode->vdisplay == m->vdisplay && +drm_mode_vrefresh (mode) ==drm_mode_vrefresh (m)) +return false;/* duplicated */ +if (mode->hdisplay <= m->hdisplay && + mode->vdisplay <= m->vdisplay) + ok = true; + } +return ok; +} +static int drm_dmt_modes_for_range (struct drm_connector *connector,struct edid *edid,struct detailed_timing *timing)@@ -1048,7 +1066,8 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid,struct drm_device *dev = connector->dev;for (i =0 ; i < drm_num_dmt_modes; i++) { -if (mode_in_range (drm_dmt_modes + i, edid, timing)) { +if (mode_in_range (drm_dmt_modes + i, edid, timing) && +valid_inferred_mode (connector, drm_dmt_modes + i)) { newmode =drm_mode_duplicate (dev, &drm_dmt_modes[i]);if (newmode) {drm_mode_probed_add (connector, newmode);@@ -1088,7 +1107,8 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,return modes;fixup_mode_1366x768 (newmode); -if (!mode_in_range (newmode, edid, timing)) { +if (!mode_in_range (newmode, edid, timing) || + !valid_inferred_mode (connector, newmode)) {drm_mode_destroy (dev, newmode);continue ; }drivers/gpu/drm/drm_edid.c drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid, · line 1143
Quoted 9 lines
drivers/gpu/drm/drm_edid.c +2
-1@@ -1116,7 +1136,8 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,return modes;fixup_mode_1366x768 (newmode); -if (!mode_in_range (newmode, edid, timing)) { +if (!mode_in_range (newmode, edid, timing) || + !valid_inferred_mode (connector, newmode)) {drm_mode_destroy (dev, newmode);continue ; }Hello all,
Quoted 2 lines
I had the exact same problem as Sven, bisected to
cb21aafe121b1c3ad4c77cc5c22320163f16ba42. Takashi's patch (supra) fixes the issue for me.
OK, so there can be more people hit by this issue.
Adam, what do you think? My patch is acceptable?
thanks,
Takashi
Quoted 2 lines · Calvin Owens
I had the exact same problem as Sven, bisected to
cb21aafe121b1c3ad4c77cc5c22320163f16ba42. Takashi's patch (supra) fixes the issue for me.
For me as well. Sorry for the slightly belated reply, was busy with other things in the last few days.
Thanks,
Sven
Adam Jackson
Reviewed-byQuoted 10 lines · Takashi Iwai
From: Takashi Iwai <[email protected]>
Subject: [PATCH] drm: edid: Don't add inferred modes with higher resolutionWhen a monitor EDID doesn't give the preferred bit, driver assumes that the mode with the higest resolution and rate is the preferred mode. Meanwhile the recent changes for allowing more modes in the GFT/CVT ranges give actually more modes, and some modes may be over the native size. Thus such a mode would be picked up as the preferred mode although it's no native resolution.
Quoted 3 lines
For avoiding such a problem, this patch limits the addition of inferred modes by checking not to be greater than other modes. Also, it checks the duplicated mode entry at the same time.
This is a little aggressive on CRTs, but whatever, better than what's there.
- ajax
At Mon, 02 Jul 2012 15:46:29 -0400,
Quoted 13 lines · Adam Jackson
Quoted 10 lines · Takashi Iwai
From: Takashi Iwai <[email protected]>
Subject: [PATCH] drm: edid: Don't add inferred modes with higher resolutionWhen a monitor EDID doesn't give the preferred bit, driver assumes that the mode with the higest resolution and rate is the preferred mode. Meanwhile the recent changes for allowing more modes in the GFT/CVT ranges give actually more modes, and some modes may be over the native size. Thus such a mode would be picked up as the preferred mode although it's no native resolution.
Quoted 7 lines
Quoted 3 lines
For avoiding such a problem, this patch limits the addition of inferred modes by checking not to be greater than other modes. Also, it checks the duplicated mode entry at the same time.
This is a little aggressive on CRTs, but whatever, better than what's there.
Reviewed-by Adam Jackson <[email protected]>
Thanks. I'm going to resend the patch with your tag.
Takashi
Quoted 6 lines · Takashi Iwai
Quoted 1 line
The xrandr command shows various bogus modes.
Can't these values be displayed on your monitor at all? If they can be displayed, they are valid modes, not really bogus. After all, they are values that EDID of your montor advertises as available ranges.
I have already commented on bogus modes when the patch first went into dcn, but to repeat -
HDMI TV - lots of new modes but it already advertised all the CVT that it supports and all the new are bogus.
DVI 120Hz 1920x1080 monitor many bogus modes as it won't display > it's res and won't scale up some of the new modes.
Even some of the new ones that are not "out of range" will actually end up setting something different and show some distortion.
Maybe gained a couple.
Quoted 2 lines · Andy Furniss
HDMI TV - lots of new modes but it already advertised all the CVT that it supports and all the new are bogus.
Oops CEA not CVT.