aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_crt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 8df574316063..17035b87ee46 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -30,6 +30,7 @@
30#include "drm.h" 30#include "drm.h"
31#include "drm_crtc.h" 31#include "drm_crtc.h"
32#include "drm_crtc_helper.h" 32#include "drm_crtc_helper.h"
33#include "drm_edid.h"
33#include "intel_drv.h" 34#include "intel_drv.h"
34#include "i915_drm.h" 35#include "i915_drm.h"
35#include "i915_drv.h" 36#include "i915_drv.h"
@@ -287,8 +288,9 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus)
287 return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; 288 return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1;
288} 289}
289 290
290static bool intel_crt_detect_ddc(struct intel_crt *crt) 291static bool intel_crt_detect_ddc(struct drm_connector *connector)
291{ 292{
293 struct intel_crt *crt = intel_attached_crt(connector);
292 struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; 294 struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
293 295
294 /* CRT should always be at 0, but check anyway */ 296 /* CRT should always be at 0, but check anyway */
@@ -301,8 +303,26 @@ static bool intel_crt_detect_ddc(struct intel_crt *crt)
301 } 303 }
302 304
303 if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { 305 if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
304 DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); 306 struct edid *edid;
305 return true; 307 bool is_digital = false;
308
309 edid = drm_get_edid(connector,
310 &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
311 /*
312 * This may be a DVI-I connector with a shared DDC
313 * link between analog and digital outputs, so we
314 * have to check the EDID input spec of the attached device.
315 */
316 if (edid != NULL) {
317 is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
318 connector->display_info.raw_edid = NULL;
319 kfree(edid);
320 }
321
322 if (!is_digital) {
323 DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
324 return true;
325 }
306 } 326 }
307 327
308 return false; 328 return false;
@@ -458,7 +478,7 @@ intel_crt_detect(struct drm_connector *connector, bool force)
458 } 478 }
459 } 479 }
460 480
461 if (intel_crt_detect_ddc(crt)) 481 if (intel_crt_detect_ddc(connector))
462 return connector_status_connected; 482 return connector_status_connected;
463 483
464 if (!force) 484 if (!force)
@@ -472,7 +492,7 @@ intel_crt_detect(struct drm_connector *connector, bool force)
472 crtc = intel_get_load_detect_pipe(&crt->base, connector, 492 crtc = intel_get_load_detect_pipe(&crt->base, connector,
473 NULL, &dpms_mode); 493 NULL, &dpms_mode);
474 if (crtc) { 494 if (crtc) {
475 if (intel_crt_detect_ddc(crt)) 495 if (intel_crt_detect_ddc(connector))
476 status = connector_status_connected; 496 status = connector_status_connected;
477 else 497 else
478 status = intel_crt_load_detect(crtc, crt); 498 status = intel_crt_load_detect(crtc, crt);