[Intel-gfx] [PATCH V2] drm/i915: Detect SDVO digital output according to EDID

ling.ma at intel.com ling.ma at intel.com
Wed Jul 29 05:31:18 CEST 2009


We send sdvo attach command to check sdvo output status, it is good enough
for most cases. However we also should care about the similar case on 4X
platform, which also share DDC bus with other analog devices.

The patch fixed bug on MP965-D. When plugged VGA by DVI-I output,
it shows sdvo dvi is detected incorrectly.

Signed-off-by: Ma Ling <ling.ma at intel.com>
---
 drivers/gpu/drm/i915/intel_sdvo.c |   37 +++++++++++++++++++++++++++----------
 1 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 4f0c309..b2d02a9 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -31,6 +31,7 @@
 #include "drm.h"
 #include "drm_crtc.h"
 #include "intel_drv.h"
+#include "drm_edid.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
 #include "intel_sdvo_regs.h"
@@ -1435,40 +1436,56 @@ void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
 	intel_sdvo_read_response(intel_output, &response, 2);
 }
 
-static void
-intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
+enum drm_connector_status
+intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response)
 {
 	struct intel_output *intel_output = to_intel_output(connector);
 	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+	enum drm_connector_status status = connector_status_connected;
 	struct edid *edid = NULL;
 
 	edid = drm_get_edid(&intel_output->base,
 			    intel_output->ddc_bus);
 	if (edid != NULL) {
-		sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid);
+
+		/*
+		 * we try to avoid similar case(DVI-I) on 4X
+		 * platform.
+		 */
+		if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
+			if (edid->input & DRM_EDID_INPUT_DIGITAL)
+				sdvo_priv->is_hdmi =
+					drm_detect_hdmi_monitor(edid);
+			else
+				status = connector_status_disconnected;
+		}
+
 		kfree(edid);
 		intel_output->base.display_info.raw_edid = NULL;
-	}
+
+	} else if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
+		status = connector_status_disconnected;
+
+	return status;
 }
 
 static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
 {
-	u8 response[2];
+	u16 response;
 	u8 status;
 	struct intel_output *intel_output = to_intel_output(connector);
 
 	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
 	status = intel_sdvo_read_response(intel_output, &response, 2);
 
-	DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
+	DRM_DEBUG("SDVO response %d\n", response);
 
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return connector_status_unknown;
 
-	if ((response[0] != 0) || (response[1] != 0)) {
-		intel_sdvo_hdmi_sink_detect(connector);
-		return connector_status_connected;
-	} else
+	if (response != 0)
+		return intel_sdvo_hdmi_sink_detect(connector, response);
+	else
 		return connector_status_disconnected;
 }
 
-- 
1.5.4.4




More information about the Intel-gfx mailing list