Signed-off-by: David Müller diff -dpurN a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c --- a/drivers/gpu/drm/i915/intel_crt.c 2010-12-08 15:09:28.777000052 +0100 +++ b/drivers/gpu/drm/i915/intel_crt.c 2011-01-06 17:59:08.071998088 +0100 @@ -30,6 +30,7 @@ #include "drm.h" #include "drm_crtc.h" #include "drm_crtc_helper.h" +#include "drm_edid.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" @@ -261,15 +262,40 @@ static bool intel_crt_detect_hotplug(str return ret; } -static bool intel_crt_detect_ddc(struct drm_encoder *encoder) +static bool intel_crt_detect_ddc(struct drm_connector *connector) { + struct drm_encoder *encoder = intel_attached_encoder(connector); struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); /* CRT should always be at 0, but check anyway */ if (intel_encoder->type != INTEL_OUTPUT_ANALOG) return false; - return intel_ddc_probe(intel_encoder); + if (intel_ddc_probe(intel_encoder)) { + struct edid *edid; + bool is_digital = false; + + intel_i2c_quirk_set(connector->dev, true); + edid = drm_get_edid(connector, intel_encoder->ddc_bus); + intel_i2c_quirk_set(connector->dev, false); + /* + * This may be a DVI-I connector with a shared DDC + * link between analog and digital outputs, so we + * have to check the EDID input spec of the attached device. + */ + if (edid != NULL) { + is_digital = edid->input & DRM_EDID_INPUT_DIGITAL; + connector->display_info.raw_edid = NULL; + kfree(edid); + } + + if (!is_digital) { + DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); + return true; + } + } + + return false; } static enum drm_connector_status @@ -417,7 +443,7 @@ intel_crt_detect(struct drm_connector *c return connector_status_disconnected; } - if (intel_crt_detect_ddc(encoder)) + if (intel_crt_detect_ddc(connector)) return connector_status_connected; if (!force)