From f6e252bac45cab5edc30c2ede971def51e272c9b Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 13 Apr 2012 16:33:31 -0400 Subject: drm/edid: Allow drm_mode_find_dmt to hunt for reduced-blanking modes It won't find any, yet. Fix up callers to match: standard mode codes will look prefer r-b modes for a given size if present, EST3 mode codes will look for exactly the r-b-ness mentioned in the mode code. This might mean fewer modes matched for EST3 mode codes between now and when the DMT mode list regrows the r-b modes, but practically speaking EST3 codes don't exist in the wild. Signed-off-by: Adam Jackson Tested-by: Takashi Iwai Reviewed-by: Rodrigo Vivi Signed-off-by: Dave Airlie diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 9c8fa88..ec0464c 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -486,18 +486,29 @@ static void edid_fixup_preferred(struct drm_connector *connector, preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; } +static bool +mode_is_rb(const struct drm_display_mode *mode) +{ + return (mode->htotal - mode->hdisplay == 160) && + (mode->hsync_end - mode->hdisplay == 80) && + (mode->hsync_end - mode->hsync_start == 32) && + (mode->vsync_start - mode->vdisplay == 3); +} + /* * drm_mode_find_dmt - Create a copy of a mode if present in DMT * @dev: Device to duplicate against * @hsize: Mode width * @vsize: Mode height * @fresh: Mode refresh rate + * @rb: Mode reduced-blanking-ness * * Walk the DMT mode list looking for a match for the given parameters. * Return a newly allocated copy of the mode, or NULL if not found. */ struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, - int hsize, int vsize, int fresh) + int hsize, int vsize, int fresh, + bool rb) { int i; @@ -509,6 +520,8 @@ struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, continue; if (fresh != drm_mode_vrefresh(ptr)) continue; + if (rb != mode_is_rb(ptr)) + continue; return drm_mode_duplicate(dev, ptr); } @@ -742,10 +755,17 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, } /* check whether it can be found in default mode table */ - mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate); + if (drm_monitor_supports_rb(edid)) { + mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, + true); + if (mode) + return mode; + } + mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, false); if (mode) return mode; + /* okay, generate it */ switch (timing_level) { case LEVEL_DMT: break; @@ -920,15 +940,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, } static bool -mode_is_rb(const struct drm_display_mode *mode) -{ - return (mode->htotal - mode->hdisplay == 160) && - (mode->hsync_end - mode->hdisplay == 80) && - (mode->hsync_end - mode->hsync_start == 32) && - (mode->vsync_start - mode->vdisplay == 3); -} - -static bool mode_in_hsync_range(const struct drm_display_mode *mode, struct edid *edid, u8 *t) { @@ -1073,8 +1084,8 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) mode = drm_mode_find_dmt(connector->dev, est3_modes[m].w, est3_modes[m].h, - est3_modes[m].r - /*, est3_modes[m].rb */); + est3_modes[m].r, + est3_modes[m].rb); if (mode) { drm_mode_probed_add(connector, mode); modes++; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a0d6e89..6e19dd1 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1083,7 +1083,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, /* try and find a 1024x768 mode on each connector */ can_clone = true; - dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60); + dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false); for (i = 0; i < fb_helper->connector_count; i++) { diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 2d63a02..6f5faf6 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1015,7 +1015,8 @@ extern int drm_edid_header_is_valid(const u8 *raw_edid); extern bool drm_edid_block_valid(u8 *raw_edid); extern bool drm_edid_is_valid(struct edid *edid); struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, - int hsize, int vsize, int fresh); + int hsize, int vsize, int fresh, + bool rb); extern int drm_mode_create_dumb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -- cgit v0.10.2