[Intel-gfx] [PATCH] drm/i915: Delete the strict EDID check for SDVO DVI-D monitor

yakui.zhao at intel.com yakui.zhao at intel.com
Thu Oct 22 07:25:33 CEST 2009


From: Zhao Yakui <yakui.zhao at intel.com>

In theory we can use EDID obtained from the DVI-D monitor to detect whether
the device is connected or not. But on some boxes we can't get the EDID for
the SDVO DVI-D although it is really connected. In such case it will be
detected as disconnected, which causes that there is no connected output.

So delete the strict check for the DVI-D monitor. When there is no EDID
for the SDVO DVI-D monitor, we still detect them as connected.

At the same time we will also add several default modes for it. For example:
1680x1050 at 60, 1280x960 at 60Hz, 1024x768 at 60Hz, 800x600 at 60Hz. Otherwise it will
have no display mode or very low resolution display mode(800x600).

https://bugs.freedesktop.org/show_bug.cgi?id=24282
https://bugs.freedesktop.org/show_bug.cgi?id=24458
https://bugs.freedesktop.org/show_bug.cgi?id=23842

Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
cc: stable at kernel.org
---
 drivers/gpu/drm/i915/intel_sdvo.c |   65 ++++++++++++++++++++++++++++++++++--
 1 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 55b8beb..fe22112 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1602,8 +1602,10 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
 		kfree(edid);
 		intel_output->base.display_info.raw_edid = NULL;
 
-	} else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
-		status = connector_status_disconnected;
+	} else {
+		status = connector_status_connected;
+		DRM_DEBUG_KMS("No EDID is obtained. But still connected.\n");
+	}
 
 	return status;
 }
@@ -1634,7 +1636,55 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
 			return connector_status_unknown;
 		sdvo_priv->attached_output = response;
 	}
-	return intel_sdvo_hdmi_sink_detect(connector, response);
+	/*
+	 * When the response doesn't belong to TMDS,it is unnecessary to check
+	 * the EDID. In such case it will be detected as connected.
+	 */
+	if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
+		return intel_sdvo_hdmi_sink_detect(connector, response);
+	else
+		return connector_status_connected;
+}
+
+/* the default mode list for the DVI-D device when
+ * there is no EDID
+ */
+static struct drm_display_mode sdvo_default_modes[] = {
+	/* 640x480 at 60Hz */
+	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
+		   752, 800, 0, 480, 489, 492, 525, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 800x600 at 60Hz */
+	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
+		   968, 1056, 0, 600, 601, 605, 628, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1024x768 at 60Hz */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
+		   1184, 1344, 0, 768, 771, 777, 806, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
+	/* 1280x960 at 60Hz */
+	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
+		   1488, 1800, 0, 960, 961, 964, 1000, 0,
+		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
+	/* 1680x1050 at 60Hz */
+	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
+		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
+		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
+};
+
+static void intel_sdvo_add_default_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_display_mode *mode, *ptr;
+	int i;
+
+	for (i = 0; i < sizeof(sdvo_default_modes) /
+			sizeof(struct drm_display_mode); i++) {
+		mode = &sdvo_default_modes[i];
+		ptr = drm_mode_duplicate(dev, mode);
+		if (ptr)
+			drm_mode_probed_add(connector, ptr);
+	}
 }
 
 static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
@@ -1662,10 +1712,17 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
 		digital_ddc_bus = intel_output->ddc_bus;
 		intel_output->ddc_bus = sdvo_priv->analog_ddc_bus;
 
-		(void) intel_ddc_get_modes(intel_output);
+		num_modes = intel_ddc_get_modes(intel_output);
 
 		intel_output->ddc_bus = digital_ddc_bus;
 	}
+	/*
+	 * If we can't get the EDID for DVI-D monitor, we will add some default
+	 * modes for it.
+	 * For example: 1680x1050 at 60, 1280x960 at 60Hz, 1024x768 at 60, 800x600 at 60Hz.
+	 */
+	if (num_modes == 0)
+		intel_sdvo_add_default_modes(connector);
 }
 
 /*
-- 
1.5.4.5




More information about the Intel-gfx mailing list