--- drivers/gpu/drm/drm_edid.c | 40 +++++++++++++++++++++++++++++++++------- drivers/gpu/drm/drm_modes.c | 11 ++++++----- 2 files changed, 39 insertions(+), 12 deletions(-) Index: linux-2.6/drivers/gpu/drm/drm_edid.c =================================================================== --- linux-2.6.orig/drivers/gpu/drm/drm_edid.c 2009-09-02 14:59:38.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/drm_edid.c 2009-09-02 17:12:25.000000000 +0800 @@ -480,6 +480,26 @@ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, }; +static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, + int hsize, int vsize, int fresh) +{ + int i, count; + struct drm_display_mode *ptr, *mode; + + count = sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); + mode = NULL; + for (i = 0; i < count; i++) { + ptr = &drm_dmt_modes[i]; + if (hsize == ptr->hdisplay && + vsize == ptr->vdisplay && + fresh == drm_mode_vrefresh(ptr)) { + /* get the expected default mode */ + mode = drm_mode_duplicate(dev, ptr); + break; + } + } + return mode; +} /** * drm_mode_std - convert standard mode info (width, height, refresh) into mode * @t: standard timing params @@ -516,16 +536,22 @@ vsize = (hsize * 4) / 5; else vsize = (hsize * 9) / 16; - + /* HDTV hack */ + if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { + mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); + mode->hdisplay = 1366; + mode->vsync_start = mode->vsync_start - 1; + mode->vsync_end = mode->vsync_end - 1; + return mode; + } mode = NULL; + /* check whether it can be found in default mode table */ + mode = drm_find_dmt(dev, hsize, vsize, vrefresh_rate); + if (mode) + return mode; + switch (timing_level) { case LEVEL_DMT: - mode = drm_mode_create(dev); - if (mode) { - mode->hdisplay = hsize; - mode->vdisplay = vsize; - drm_mode_set_name(mode); - } break; case LEVEL_GTF: mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); Index: linux-2.6/drivers/gpu/drm/drm_modes.c =================================================================== --- linux-2.6.orig/drivers/gpu/drm/drm_modes.c 2009-09-02 08:41:36.000000000 +0800 +++ linux-2.6/drivers/gpu/drm/drm_modes.c 2009-09-02 15:34:11.000000000 +0800 @@ -566,7 +566,9 @@ * FIXME: why is this needed? shouldn't vrefresh be set already? * * RETURNS: - * Vertical refresh rate of @mode x 1000. For precision reasons. + * Vertical refresh rate. It will be the result of actual value plus 0.5. + * If it is 70.288, it will return 70Hz. + * If it is 59.6, it will return 60Hz. */ int drm_mode_vrefresh(struct drm_display_mode *mode) { @@ -576,14 +578,13 @@ if (mode->vrefresh > 0) refresh = mode->vrefresh; else if (mode->htotal > 0 && mode->vtotal > 0) { + int vtotal; + vtotal = mode->vtotal; /* work out vrefresh the value will be x1000 */ calc_val = (mode->clock * 1000); - calc_val /= mode->htotal; - calc_val *= 1000; - calc_val /= mode->vtotal; + refresh = (calc_val + vtotal / 2) / vtotal; - refresh = calc_val; if (mode->flags & DRM_MODE_FLAG_INTERLACE) refresh *= 2; if (mode->flags & DRM_MODE_FLAG_DBLSCAN)