[Intel-gfx] [PATCH 2/4 V2] drm/i915: hdmi detection according to edid header

ling.ma at intel.com ling.ma at intel.com
Mon Jul 13 11:57:55 CEST 2009


According to investigations from windows team ,hw team,
and our test results on all 4x platofrms available
(gm45, g45b, q45, g45a, g45c, g41a, and g41), we find
currently Hot plug live status and Hot plug interrupt
detection are not reliable, sometime the results from
the two approaches are contradicts. So we chose edid
detection for hdmi output, and only read edid header
to save detection time.

It fixed freedescktop.org bug #21322

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

diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 9e30daa..7c29d2d 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -163,50 +163,28 @@ igdng_hdmi_detect(struct drm_connector *connector)
 	return intel_hdmi_edid_detect(connector);
 }
 
+/* Valid EDID header has these bytes */
+static u8 EDID_HEADER[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
+
 static enum drm_connector_status
 intel_hdmi_detect(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
-	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;
-	u32 temp, bit;
+	u8 edid_header[sizeof(EDID_HEADER)];
+	int ret;
 
 	if (IS_IGDNG(dev))
 		return igdng_hdmi_detect(connector);
 
-	temp = I915_READ(PORT_HOTPLUG_EN);
-
-	switch (hdmi_priv->sdvox_reg) {
-	case SDVOB:
-		temp |= HDMIB_HOTPLUG_INT_EN;
-		break;
-	case SDVOC:
-		temp |= HDMIC_HOTPLUG_INT_EN;
-		break;
-	default:
-		return connector_status_unknown;
-	}
-
-	I915_WRITE(PORT_HOTPLUG_EN, temp);
-
-	POSTING_READ(PORT_HOTPLUG_EN);
-
-	switch (hdmi_priv->sdvox_reg) {
-	case SDVOB:
-		bit = HDMIB_HOTPLUG_INT_STATUS;
-		break;
-	case SDVOC:
-		bit = HDMIC_HOTPLUG_INT_STATUS;
-		break;
-	default:
-		return connector_status_unknown;
-	}
+	ret = drm_do_probe_ddc_edid(intel_output->ddc_bus,
+				    edid_header, sizeof(EDID_HEADER));
 
-	if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0)
-		return intel_hdmi_edid_detect(connector);
-	else
+	/*Fail to get edid, return disconnect status*/
+	if (ret || memcmp(edid_header, EDID_HEADER, sizeof(EDID_HEADER)))
 		return connector_status_disconnected;
+
+	return intel_hdmi_edid_detect(connector);
 }
 
 static int intel_hdmi_get_modes(struct drm_connector *connector)
@@ -266,7 +244,6 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
 
 void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 {
-	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_connector *connector;
 	struct intel_output *intel_output;
 	struct intel_hdmi_priv *hdmi_priv;
@@ -316,15 +293,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
 					  &intel_output->enc);
 	drm_sysfs_connector_add(connector);
 
-	/* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
-	 * 0xd.  Failure to do so will result in spurious interrupts being
-	 * generated on the port when a cable is not attached.
-	 */
-	if (IS_G4X(dev) && !IS_GM45(dev)) {
-		u32 temp = I915_READ(PEG_BAND_GAP_DATA);
-		I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd);
-	}
-
 	return;
 
 err_connector:
-- 
1.5.4.4




More information about the Intel-gfx mailing list