diff mbox

[2/4] DRM: try to find the std mode in DMT table

Message ID 1251941629-6694-2-git-send-email-yakui.zhao@intel.com (mailing list archive)
State Not Applicable
Headers show

Commit Message

Zhao, Yakui Sept. 3, 2009, 1:33 a.m. UTC
From: Zhao Yakui <yakui.zhao@intel.com>

When we need to add the standard timing mode, we will firstly check whether it
can be found in DMT table by comparing the hdisplay/vdisplay/vfresh_rate.
If it can't be found, then we will use the cvt/gtf to add the required mode.
If it can be found, it will be returned.

At the same time the function of drm_mode_vrefresh is also fixed. It will 
return the result of actual refresh_rate plus 0.5.
For example: 
When the calculated value is 84.9, then the fresh_rate is 85.
When the calculated value is 70.02, then the fresh_rate is 70.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
---
 drivers/gpu/drm/drm_edid.c  |   40 +++++++++++++++++++++++++++++++++-------
 drivers/gpu/drm/drm_modes.c |   11 ++++++-----
 2 files changed, 39 insertions(+), 12 deletions(-)
diff mbox

Patch

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)