At Tue, 17 Apr 2012 17:26:26 +0200, Takashi Iwai wrote:
At Fri, 13 Apr 2012 16:56:26 -0400, Adam Jackson wrote:
On 4/13/12 4:33 PM, Adam Jackson wrote:
Incorporates some feedback from Rodrigo and Takashi. Major themes of the series:
- Fix the DMT list to include reduced-blanking modes
- Add modes from DMT for any range descriptor type
- Add an extra modes list for things not in DMT
- For ranges that specify a formula, generate timings from the extra modes
This still doesn't address the driver policy decision of "I know I have a scaler, add modes as if there were a range descriptor even if there's not one". But it should at least make clear what such a helper function should do.
One minor buglet in this series that's not obvious from inspection (and that I didn't realize until just now) is that putting 1366x768 in the minimode list won't do what you want, since the mode you get back will be 1368x768. Probably we should move the manual-underscan hack into the timing generators themselves.
Sounds like a good compromise. We have already hacks in drm_edid.c for HDMI TV, so one exception more isn't that bad ;)
FYI, I tried the hack below and it seems working.
Takashi
--- --- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
--- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1047,6 +1047,19 @@ drm_dmt_modes_for_range(struct drm_conne return modes; }
+/* fix up 1366x768 mode from 1368x768; + * GTF/CVT can't express 1366 width which isn't dividable by 8 + */ +static void fixup_mode_1366x768(struct drm_display_mode *mode) +{ + if (mode->hdisplay == 1368 && mode->vdisplay == 768) { + mode->hdisplay = 1366; + mode->hsync_start--; + mode->hsync_end--; + drm_mode_set_name(mode); + } +} + static int drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, struct detailed_timing *timing) @@ -1059,6 +1072,7 @@ drm_gtf_modes_for_range(struct drm_conne const struct minimode *m = &extra_modes[i]; newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0);
+ fixup_mode_1366x768(newmode); if (!mode_in_range(newmode, edid, timing)) { drm_mode_destroy(dev, newmode); continue; @@ -1084,6 +1098,7 @@ drm_cvt_modes_for_range(struct drm_conne const struct minimode *m = &extra_modes[i]; newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0);
+ fixup_mode_1366x768(newmode); if (!mode_in_range(newmode, edid, timing)) { drm_mode_destroy(dev, newmode); continue;