diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index f6a3fdd5589e..4bcd91757321 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -2806,6 +2806,13 @@ intel_dp_dpcd_read_wake(struct drm_dp_aux *aux, unsigned int offset, | |||
2806 | ssize_t ret; | 2806 | ssize_t ret; |
2807 | int i; | 2807 | int i; |
2808 | 2808 | ||
2809 | /* | ||
2810 | * Sometime we just get the same incorrect byte repeated | ||
2811 | * over the entire buffer. Doing just one throw away read | ||
2812 | * initially seems to "solve" it. | ||
2813 | */ | ||
2814 | drm_dp_dpcd_read(aux, DP_DPCD_REV, buffer, 1); | ||
2815 | |||
2809 | for (i = 0; i < 3; i++) { | 2816 | for (i = 0; i < 3; i++) { |
2810 | ret = drm_dp_dpcd_read(aux, offset, buffer, size); | 2817 | ret = drm_dp_dpcd_read(aux, offset, buffer, size); |
2811 | if (ret == size) | 2818 | if (ret == size) |
@@ -3724,9 +3731,10 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) | |||
3724 | } | 3731 | } |
3725 | } | 3732 | } |
3726 | 3733 | ||
3727 | /* Training Pattern 3 support */ | 3734 | /* Training Pattern 3 support, both source and sink */ |
3728 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && | 3735 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && |
3729 | intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) { | 3736 | intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED && |
3737 | (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)) { | ||
3730 | intel_dp->use_tps3 = true; | 3738 | intel_dp->use_tps3 = true; |
3731 | DRM_DEBUG_KMS("Displayport TPS3 supported\n"); | 3739 | DRM_DEBUG_KMS("Displayport TPS3 supported\n"); |
3732 | } else | 3740 | } else |
@@ -4442,6 +4450,7 @@ static void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder) | |||
4442 | * vdd might still be enabled do to the delayed vdd off. | 4450 | * vdd might still be enabled do to the delayed vdd off. |
4443 | * Make sure vdd is actually turned off here. | 4451 | * Make sure vdd is actually turned off here. |
4444 | */ | 4452 | */ |
4453 | cancel_delayed_work_sync(&intel_dp->panel_vdd_work); | ||
4445 | pps_lock(intel_dp); | 4454 | pps_lock(intel_dp); |
4446 | edp_panel_vdd_off_sync(intel_dp); | 4455 | edp_panel_vdd_off_sync(intel_dp); |
4447 | pps_unlock(intel_dp); | 4456 | pps_unlock(intel_dp); |
@@ -4491,6 +4500,18 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) | |||
4491 | if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) | 4500 | if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) |
4492 | intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; | 4501 | intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; |
4493 | 4502 | ||
4503 | if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { | ||
4504 | /* | ||
4505 | * vdd off can generate a long pulse on eDP which | ||
4506 | * would require vdd on to handle it, and thus we | ||
4507 | * would end up in an endless cycle of | ||
4508 | * "vdd off -> long hpd -> vdd on -> detect -> vdd off -> ..." | ||
4509 | */ | ||
4510 | DRM_DEBUG_KMS("ignoring long hpd on eDP port %c\n", | ||
4511 | port_name(intel_dig_port->port)); | ||
4512 | return false; | ||
4513 | } | ||
4514 | |||
4494 | DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", | 4515 | DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", |
4495 | port_name(intel_dig_port->port), | 4516 | port_name(intel_dig_port->port), |
4496 | long_hpd ? "long" : "short"); | 4517 | long_hpd ? "long" : "short"); |