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

ling.ma at intel.com ling.ma at intel.com
Fri Jul 3 17:29:01 CEST 2009


We detect HDMI output status by setting interrupt enable bit,
then read live status, which is effective for most cases.
However some G4x platform will indicate incorrect detection result,
because according to the HW team live status detection need special board
design and won't work on all boards, 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..26b473d 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 */
+			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