diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 8e484c9ac1f5..389fcd2aea1f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -261,6 +261,21 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
261 | return ret; | 261 | return ret; |
262 | } | 262 | } |
263 | 263 | ||
264 | static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus) | ||
265 | { | ||
266 | u8 buf; | ||
267 | struct i2c_msg msgs[] = { | ||
268 | { | ||
269 | .addr = 0xA0, | ||
270 | .flags = 0, | ||
271 | .len = 1, | ||
272 | .buf = &buf, | ||
273 | }, | ||
274 | }; | ||
275 | /* DDC monitor detect: Does it ACK a write to 0xA0? */ | ||
276 | return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; | ||
277 | } | ||
278 | |||
264 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) | 279 | static bool intel_crt_detect_ddc(struct drm_encoder *encoder) |
265 | { | 280 | { |
266 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); | 281 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
@@ -270,7 +285,17 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder) | |||
270 | if (intel_encoder->type != INTEL_OUTPUT_ANALOG) | 285 | if (intel_encoder->type != INTEL_OUTPUT_ANALOG) |
271 | return false; | 286 | return false; |
272 | 287 | ||
273 | return intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin); | 288 | if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) { |
289 | DRM_DEBUG_KMS("CRT detected via DDC:0xa0\n"); | ||
290 | return true; | ||
291 | } | ||
292 | |||
293 | if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) { | ||
294 | DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); | ||
295 | return true; | ||
296 | } | ||
297 | |||
298 | return false; | ||
274 | } | 299 | } |
275 | 300 | ||
276 | static enum drm_connector_status | 301 | static enum drm_connector_status |
@@ -296,6 +321,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
296 | uint8_t st00; | 321 | uint8_t st00; |
297 | enum drm_connector_status status; | 322 | enum drm_connector_status status; |
298 | 323 | ||
324 | DRM_DEBUG_KMS("starting load-detect on CRT\n"); | ||
325 | |||
299 | if (pipe == 0) { | 326 | if (pipe == 0) { |
300 | bclrpat_reg = BCLRPAT_A; | 327 | bclrpat_reg = BCLRPAT_A; |
301 | vtotal_reg = VTOTAL_A; | 328 | vtotal_reg = VTOTAL_A; |
@@ -412,9 +439,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
412 | enum drm_connector_status status; | 439 | enum drm_connector_status status; |
413 | 440 | ||
414 | if (I915_HAS_HOTPLUG(dev)) { | 441 | if (I915_HAS_HOTPLUG(dev)) { |
415 | if (intel_crt_detect_hotplug(connector)) | 442 | if (intel_crt_detect_hotplug(connector)) { |
443 | DRM_DEBUG_KMS("CRT detected via hotplug\n"); | ||
416 | return connector_status_connected; | 444 | return connector_status_connected; |
417 | else | 445 | } else |
418 | return connector_status_disconnected; | 446 | return connector_status_disconnected; |
419 | } | 447 | } |
420 | 448 | ||
@@ -431,7 +459,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) | |||
431 | crtc = intel_get_load_detect_pipe(encoder, connector, | 459 | crtc = intel_get_load_detect_pipe(encoder, connector, |
432 | NULL, &dpms_mode); | 460 | NULL, &dpms_mode); |
433 | if (crtc) { | 461 | if (crtc) { |
434 | status = intel_crt_load_detect(crtc, encoder); | 462 | if (intel_crt_detect_ddc(&encoder->base)) |
463 | status = connector_status_connected; | ||
464 | else | ||
465 | status = intel_crt_load_detect(crtc, encoder); | ||
435 | intel_release_load_detect_pipe(encoder, | 466 | intel_release_load_detect_pipe(encoder, |
436 | connector, dpms_mode); | 467 | connector, dpms_mode); |
437 | } else | 468 | } else |