aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dp.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-07-29 09:51:16 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2016-08-04 08:57:52 -0400
commitc4e3170a0cdeec5ba9749a49a757b7ea722829d6 (patch)
treee19c7336d8bac8b95b27c4bb966173e8fc15dd9d /drivers/gpu/drm/i915/intel_dp.c
parentf64425a82bdb5c3d7e09ba765716da88a9b00eec (diff)
drm/i915: Allow MST sinks to work even if drm_probe_ddc() fails
With HSW + Dell UP2414Q (at least) drm_probe_ddc() occasionally fails, and then we'll assume that the entire display has been disconnected. We don't need the EDID from the main link, so we can simply check if the sink is MST capable, and if so treat is as connected. v2: Skip drm_probe_ddc() entirely for MST (Daniel) Cc: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> Cc: Jim Bride <jim.bride@linux.intel.com> Cc: Manasi D Navare <manasi.d.navare@intel.com> Cc: Durgadoss R <durgadoss.r@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1469800276-6979-1-git-send-email-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c45
1 files changed, 30 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 38f20339ad10..a0c99c06210e 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3545,7 +3545,7 @@ intel_dp_probe_oui(struct intel_dp *intel_dp)
3545} 3545}
3546 3546
3547static bool 3547static bool
3548intel_dp_probe_mst(struct intel_dp *intel_dp) 3548intel_dp_can_mst(struct intel_dp *intel_dp)
3549{ 3549{
3550 u8 buf[1]; 3550 u8 buf[1];
3551 3551
@@ -3558,18 +3558,30 @@ intel_dp_probe_mst(struct intel_dp *intel_dp)
3558 if (intel_dp->dpcd[DP_DPCD_REV] < 0x12) 3558 if (intel_dp->dpcd[DP_DPCD_REV] < 0x12)
3559 return false; 3559 return false;
3560 3560
3561 if (drm_dp_dpcd_read(&intel_dp->aux, DP_MSTM_CAP, buf, 1)) { 3561 if (drm_dp_dpcd_read(&intel_dp->aux, DP_MSTM_CAP, buf, 1) != 1)
3562 if (buf[0] & DP_MST_CAP) { 3562 return false;
3563 DRM_DEBUG_KMS("Sink is MST capable\n");
3564 intel_dp->is_mst = true;
3565 } else {
3566 DRM_DEBUG_KMS("Sink is not MST capable\n");
3567 intel_dp->is_mst = false;
3568 }
3569 }
3570 3563
3571 drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst); 3564 return buf[0] & DP_MST_CAP;
3572 return intel_dp->is_mst; 3565}
3566
3567static void
3568intel_dp_configure_mst(struct intel_dp *intel_dp)
3569{
3570 if (!i915.enable_dp_mst)
3571 return;
3572
3573 if (!intel_dp->can_mst)
3574 return;
3575
3576 intel_dp->is_mst = intel_dp_can_mst(intel_dp);
3577
3578 if (intel_dp->is_mst)
3579 DRM_DEBUG_KMS("Sink is MST capable\n");
3580 else
3581 DRM_DEBUG_KMS("Sink is not MST capable\n");
3582
3583 drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
3584 intel_dp->is_mst);
3573} 3585}
3574 3586
3575static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) 3587static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp)
@@ -3999,6 +4011,9 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
3999 connector_status_connected : connector_status_disconnected; 4011 connector_status_connected : connector_status_disconnected;
4000 } 4012 }
4001 4013
4014 if (intel_dp_can_mst(intel_dp))
4015 return connector_status_connected;
4016
4002 /* If no HPD, poke DDC gently */ 4017 /* If no HPD, poke DDC gently */
4003 if (drm_probe_ddc(&intel_dp->aux.ddc)) 4018 if (drm_probe_ddc(&intel_dp->aux.ddc))
4004 return connector_status_connected; 4019 return connector_status_connected;
@@ -4236,7 +4251,6 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
4236 struct drm_device *dev = connector->dev; 4251 struct drm_device *dev = connector->dev;
4237 enum drm_connector_status status; 4252 enum drm_connector_status status;
4238 enum intel_display_power_domain power_domain; 4253 enum intel_display_power_domain power_domain;
4239 bool ret;
4240 u8 sink_irq_vector; 4254 u8 sink_irq_vector;
4241 4255
4242 power_domain = intel_display_port_aux_power_domain(intel_encoder); 4256 power_domain = intel_display_port_aux_power_domain(intel_encoder);
@@ -4279,8 +4293,9 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
4279 4293
4280 intel_dp_probe_oui(intel_dp); 4294 intel_dp_probe_oui(intel_dp);
4281 4295
4282 ret = intel_dp_probe_mst(intel_dp); 4296 intel_dp_configure_mst(intel_dp);
4283 if (ret) { 4297
4298 if (intel_dp->is_mst) {
4284 /* 4299 /*
4285 * If we are in MST mode then this connector 4300 * If we are in MST mode then this connector
4286 * won't appear connected or have anything 4301 * won't appear connected or have anything