diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 30 |
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 | ||
290 | static bool intel_crt_detect_ddc(struct intel_crt *crt) | 291 | static 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); |