diff options
author | Adam Jackson <ajax@redhat.com> | 2012-09-18 14:58:50 (GMT) |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-09-26 12:22:29 (GMT) |
commit | 07d3dc18396790d9d394f4f0717a91b3a845c758 (patch) | |
tree | bbeef79ea8ea2d0523e1d6cb09f367b32e18c666 /drivers/gpu/drm/i915/intel_dp.c | |
parent | b091cd928dfa81e8c28b9707899201358b4e50b5 (diff) | |
download | linux-fsl-qoriq-07d3dc18396790d9d394f4f0717a91b3a845c758.tar.xz |
drm/i915/dp: Be smarter about connection sense for branch devices
If there's no downstream device, DPCD success is good enough. If
there's a hotplug-capable downstream device, count the number of
connected sinks in DP_SINK_STATUS and return success if it's non-zero.
Otherwise, probe DDC and report appropriately.
v2: Check DP_SINK_STATUS instead of something unrelated to sink status.
Tested-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 42bdca4..4f2a381 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2083,11 +2083,44 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) } } +/* XXX this is probably wrong for multiple downstream ports */ static enum drm_connector_status intel_dp_detect_dpcd(struct intel_dp *intel_dp) { - if (intel_dp_get_dpcd(intel_dp)) + uint8_t *dpcd = intel_dp->dpcd; + bool hpd; + uint8_t type; + + if (!intel_dp_get_dpcd(intel_dp)) + return connector_status_disconnected; + + /* if there's no downstream port, we're done */ + if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) + return connector_status_connected; + + /* If we're HPD-aware, SINK_COUNT changes dynamically */ + hpd = !!(intel_dp->downstream_ports[0] & DP_DS_PORT_HPD); + if (hpd) { + uint8_t sink_count; + if (!intel_dp_aux_native_read_retry(intel_dp, DP_SINK_COUNT, + &sink_count, 1)) + return connector_status_unknown; + sink_count &= DP_SINK_COUNT_MASK; + return sink_count ? connector_status_connected + : connector_status_disconnected; + } + + /* If no HPD, poke DDC gently */ + if (drm_probe_ddc(&intel_dp->adapter)) return connector_status_connected; + + /* Well we tried, say unknown for unreliable port types */ + type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK; + if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_NON_EDID) + return connector_status_unknown; + + /* Anything else is out of spec, warn and ignore */ + DRM_DEBUG_KMS("Broken DP branch device, ignoring\n"); return connector_status_disconnected; } |