[Intel-gfx] [PATCH] drm/i915: detect hdmi monitor by reading edid

ling.ma at intel.com ling.ma at intel.com
Thu Jun 25 03:15:14 CEST 2009


We detect HDMI output status by setting interrupt enable bit,
then read interrupt status, which is effective for most cases.
However G4x platform will indicate incorrect detection result 
even if current output is HDMI monitor. The patch intends
to read edid, then determin connect status by EDID type.

It fixed freedesktop.org bug #21322.

Signed-off-by: Ma Ling <ling.ma at intel.com>
---
 drivers/gpu/drm/i915/intel_hdmi.c |   41 +++++++++++++++++++++---------------
 1 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 9e30daa..abcb146 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -130,37 +130,29 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
 }
 
 static enum drm_connector_status
-intel_hdmi_edid_detect(struct drm_connector *connector)
+intel_hdmi_edid_detect(struct drm_connector *connector, struct edid *edid)
 {
 	struct intel_output *intel_output = to_intel_output(connector);
 	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
-	struct edid *edid = NULL;
-	enum drm_connector_status status = connector_status_disconnected;
 
-	edid = drm_get_edid(&intel_output->base,
-			    intel_output->ddc_bus);
 	hdmi_priv->has_hdmi_sink = false;
-	if (edid) {
-		if (edid->input & DRM_EDID_INPUT_DIGITAL) {
-			status = connector_status_connected;
-			hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
-		}
+	if (edid != NULL) {
+		hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
 		intel_output->base.display_info.raw_edid = NULL;
 		kfree(edid);
 	}
-	return status;
+	return connector_status_connected;
 }
 
 static enum drm_connector_status
-igdng_hdmi_detect(struct drm_connector *connector)
+igdng_hdmi_detect(struct drm_connector *connector, struct edid *edid)
 {
 	struct intel_output *intel_output = to_intel_output(connector);
-	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+
 
 	/* FIXME hotplug detect */
 
-	hdmi_priv->has_hdmi_sink = false;
-	return intel_hdmi_edid_detect(connector);
+	return intel_hdmi_edid_detect(connector, edid);
 }
 
 static enum drm_connector_status
@@ -170,10 +162,25 @@ intel_hdmi_detect(struct drm_connector *connector)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_output *intel_output = to_intel_output(connector);
 	struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
+	struct edid *edid = NULL;
 	u32 temp, bit;
 
+	/* probe connect status by EDID */
+	edid = drm_get_edid(&intel_output->base,
+			    intel_output->ddc_bus);
+
+	if (edid != NULL) {
+		if ((edid->input & DRM_EDID_INPUT_DIGITAL) == 0) {
+			/* This is analog monitor disconnected with hdmi output */
+			kfree(edid);
+			intel_output->base.display_info.raw_edid = NULL;
+			return connector_status_disconnected;
+		}
+		return intel_hdmi_edid_detect(connector, edid);
+	}
+
 	if (IS_IGDNG(dev))
-		return igdng_hdmi_detect(connector);
+		return igdng_hdmi_detect(connector, edid);
 
 	temp = I915_READ(PORT_HOTPLUG_EN);
 
@@ -204,7 +211,7 @@ intel_hdmi_detect(struct drm_connector *connector)
 	}
 
 	if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0)
-		return intel_hdmi_edid_detect(connector);
+		return intel_hdmi_edid_detect(connector, edid);
 	else
 		return connector_status_disconnected;
 }
-- 
1.5.4.4




More information about the Intel-gfx mailing list