Commit a2bd1f54 authored by Daniel Vetter's avatar Daniel Vetter

drm/i915: check whether we actually received an edid in detect_ddc

Somehow detect_ddc manages to fall through all checks when we think
that something responds on the ddc i2c address, but the edid read
failed. Fix this up by explicitly checking for this case.

This fixes a regression on newer chips because since

commit aaa37730
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date:   Sat Jun 16 15:30:32 2012 +0200

    drm/i915/crt: Do not rely upon the HPD presence pin

we use ddc detection also on hotplug capable platforms. And one of
these reads all 0s for any i2c transaction if nothing is connected to
the vga port.

v2: Implement Chris Wilson's review:
- simplify logic, default to "nothing detected"
- kill stale comment
- BUG_ON(!crt->type != ANALOG)

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=51900Tested-by: default avatarYang Guang <guang.a.yang@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-Off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 4b4147c3
...@@ -330,39 +330,34 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) ...@@ -330,39 +330,34 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
{ {
struct intel_crt *crt = intel_attached_crt(connector); struct intel_crt *crt = intel_attached_crt(connector);
struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
/* CRT should always be at 0, but check anyway */
if (crt->base.type != INTEL_OUTPUT_ANALOG)
return false;
if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
struct edid *edid; struct edid *edid;
bool is_digital = false;
struct i2c_adapter *i2c; struct i2c_adapter *i2c;
BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin); i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->crt_ddc_pin);
edid = drm_get_edid(connector, i2c); edid = drm_get_edid(connector, i2c);
if (edid) {
bool is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
/* /*
* This may be a DVI-I connector with a shared DDC * This may be a DVI-I connector with a shared DDC
* link between analog and digital outputs, so we * link between analog and digital outputs, so we
* have to check the EDID input spec of the attached device. * have to check the EDID input spec of the attached device.
*
* On the other hand, what should we do if it is a broken EDID?
*/ */
if (edid != NULL) {
is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
connector->display_info.raw_edid = NULL;
kfree(edid);
}
if (!is_digital) { if (!is_digital) {
DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
return true; return true;
} else {
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
} }
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
} else {
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n");
} }
kfree(edid);
return false; return false;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment