Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-2.6
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_crt.c
index 8df5743..17035b8 100644 (file)
@@ -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"
@@ -287,8 +288,9 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus)
        return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1;
 }
 
-static bool intel_crt_detect_ddc(struct intel_crt *crt)
+static bool intel_crt_detect_ddc(struct drm_connector *connector)
 {
+       struct intel_crt *crt = intel_attached_crt(connector);
        struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
 
        /* CRT should always be at 0, but check anyway */
@@ -301,8 +303,26 @@ static bool intel_crt_detect_ddc(struct intel_crt *crt)
        }
 
        if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
-               DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
-               return true;
+               struct edid *edid;
+               bool is_digital = false;
+
+               edid = drm_get_edid(connector,
+                       &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
+               /*
+                * 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;
@@ -458,7 +478,7 @@ intel_crt_detect(struct drm_connector *connector, bool force)
                }
        }
 
-       if (intel_crt_detect_ddc(crt))
+       if (intel_crt_detect_ddc(connector))
                return connector_status_connected;
 
        if (!force)
@@ -472,7 +492,7 @@ intel_crt_detect(struct drm_connector *connector, bool force)
                crtc = intel_get_load_detect_pipe(&crt->base, connector,
                                                  NULL, &dpms_mode);
                if (crtc) {
-                       if (intel_crt_detect_ddc(crt))
+                       if (intel_crt_detect_ddc(connector))
                                status = connector_status_connected;
                        else
                                status = intel_crt_load_detect(crtc, crt);