[PATCH 2/2] drm/edid: Be much more cautious about walking extra_modes

Adam Jackson ajax at redhat.com
Mon Jun 25 08:25:19 PDT 2012


Essentially, only do this on digital displays.  It's almost certainly
not wise to add them on CRTs, but we can't tell CRT from LCD before EDID
1.4, so just use digital as a proxy for that.

Bugzilla: https://bugs.freedesktop.org/51146
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 drivers/gpu/drm/drm_edid.c |   66 ++++++++-----------------------------------
 1 files changed, 13 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 4a3e61a..e198325 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1081,44 +1081,16 @@ static void fixup_mode_1366x768(struct drm_display_mode *mode)
 }
 
 static int
-drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid,
-			struct detailed_timing *timing)
-{
-	int i, modes = 0;
-	struct drm_display_mode *newmode;
-	struct drm_device *dev = connector->dev;
-
-	for (i = 0; i < num_extra_modes; i++) {
-		const struct minimode *m = &extra_modes[i];
-		newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0);
-		if (!newmode)
-			return modes;
-
-		fixup_mode_1366x768(newmode);
-		if (!mode_in_range(newmode, edid, timing)) {
-			drm_mode_destroy(dev, newmode);
-			continue;
-		}
-
-		drm_mode_probed_add(connector, newmode);
-		modes++;
-	}
-
-	return modes;
-}
-
-static int
-drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid,
-			struct detailed_timing *timing)
+drm_extra_modes_for_range(struct drm_connector *connector, struct edid *edid,
+			  struct detailed_timing *timing)
 {
 	int i, modes = 0;
 	struct drm_display_mode *newmode;
 	struct drm_device *dev = connector->dev;
-	bool rb = drm_monitor_supports_rb(edid);
 
 	for (i = 0; i < num_extra_modes; i++) {
 		const struct minimode *m = &extra_modes[i];
-		newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0);
+		newmode = drm_cvt_mode(dev, m->w, m->h, m->r, true, 0, 0);
 		if (!newmode)
 			return modes;
 
@@ -1140,7 +1112,6 @@ do_inferred_modes(struct detailed_timing *timing, void *c)
 {
 	struct detailed_mode_closure *closure = c;
 	struct detailed_non_pixel *data = &timing->data.other_data;
-	struct detailed_data_monitor_range *range = &data->data.range;
 
 	if (data->type != EDID_DETAIL_MONITOR_RANGE)
 		return;
@@ -1149,28 +1120,17 @@ do_inferred_modes(struct detailed_timing *timing, void *c)
 						  closure->edid,
 						  timing);
 	
-	if (!version_greater(closure->edid, 1, 1))
-		return; /* GTF not defined yet */
-
-	switch (range->flags) {
-	case 0x02: /* secondary gtf, XXX could do more */
-	case 0x00: /* default gtf */
-		closure->modes += drm_gtf_modes_for_range(closure->connector,
-							  closure->edid,
-							  timing);
-		break;
-	case 0x04: /* cvt, only in 1.4+ */
-		if (!version_greater(closure->edid, 1, 3))
-			break;
+	/* Don't look at extra_modes for pre-CVT-era displays */
+	if (!version_greater(closure->edid, 1, 2))
+		return; /* CVT not defined yet */
 
-		closure->modes += drm_cvt_modes_for_range(closure->connector,
-							  closure->edid,
-							  timing);
-		break;
-	case 0x01: /* just the ranges, no formula */
-	default:
-		break;
-	}
+	/* Don't look at extra_modes for non-rb displays */
+	if (!drm_monitor_supports_rb(closure->edid))
+		return;
+
+	closure->modes += drm_extra_modes_for_range(closure->connector,
+						    closure->edid,
+						    timing);
 }
 
 static int
-- 
1.7.7.6



More information about the dri-devel mailing list