diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5ede4e8e290d..2688f6d64bb9 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -404,7 +404,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
404 | int i, ret, recv_bytes; | 404 | int i, ret, recv_bytes; |
405 | uint32_t status; | 405 | uint32_t status; |
406 | int try, precharge, clock = 0; | 406 | int try, precharge, clock = 0; |
407 | bool has_aux_irq = true; | 407 | bool has_aux_irq = HAS_AUX_IRQ(dev); |
408 | uint32_t timeout; | 408 | uint32_t timeout; |
409 | 409 | ||
410 | /* dp aux is extremely sensitive to irq latency, hence request the | 410 | /* dp aux is extremely sensitive to irq latency, hence request the |
@@ -537,6 +537,7 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp, | |||
537 | uint8_t msg[20]; | 537 | uint8_t msg[20]; |
538 | int msg_bytes; | 538 | int msg_bytes; |
539 | uint8_t ack; | 539 | uint8_t ack; |
540 | int retry; | ||
540 | 541 | ||
541 | if (WARN_ON(send_bytes > 16)) | 542 | if (WARN_ON(send_bytes > 16)) |
542 | return -E2BIG; | 543 | return -E2BIG; |
@@ -548,19 +549,21 @@ intel_dp_aux_native_write(struct intel_dp *intel_dp, | |||
548 | msg[3] = send_bytes - 1; | 549 | msg[3] = send_bytes - 1; |
549 | memcpy(&msg[4], send, send_bytes); | 550 | memcpy(&msg[4], send, send_bytes); |
550 | msg_bytes = send_bytes + 4; | 551 | msg_bytes = send_bytes + 4; |
551 | for (;;) { | 552 | for (retry = 0; retry < 7; retry++) { |
552 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); | 553 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); |
553 | if (ret < 0) | 554 | if (ret < 0) |
554 | return ret; | 555 | return ret; |
555 | ack >>= 4; | 556 | ack >>= 4; |
556 | if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_ACK) | 557 | if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_ACK) |
557 | break; | 558 | return send_bytes; |
558 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) | 559 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) |
559 | udelay(100); | 560 | usleep_range(400, 500); |
560 | else | 561 | else |
561 | return -EIO; | 562 | return -EIO; |
562 | } | 563 | } |
563 | return send_bytes; | 564 | |
565 | DRM_ERROR("too many retries, giving up\n"); | ||
566 | return -EIO; | ||
564 | } | 567 | } |
565 | 568 | ||
566 | /* Write a single byte to the aux channel in native mode */ | 569 | /* Write a single byte to the aux channel in native mode */ |
@@ -582,6 +585,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
582 | int reply_bytes; | 585 | int reply_bytes; |
583 | uint8_t ack; | 586 | uint8_t ack; |
584 | int ret; | 587 | int ret; |
588 | int retry; | ||
585 | 589 | ||
586 | if (WARN_ON(recv_bytes > 19)) | 590 | if (WARN_ON(recv_bytes > 19)) |
587 | return -E2BIG; | 591 | return -E2BIG; |
@@ -595,7 +599,7 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
595 | msg_bytes = 4; | 599 | msg_bytes = 4; |
596 | reply_bytes = recv_bytes + 1; | 600 | reply_bytes = recv_bytes + 1; |
597 | 601 | ||
598 | for (;;) { | 602 | for (retry = 0; retry < 7; retry++) { |
599 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, | 603 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, |
600 | reply, reply_bytes); | 604 | reply, reply_bytes); |
601 | if (ret == 0) | 605 | if (ret == 0) |
@@ -608,10 +612,13 @@ intel_dp_aux_native_read(struct intel_dp *intel_dp, | |||
608 | return ret - 1; | 612 | return ret - 1; |
609 | } | 613 | } |
610 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) | 614 | else if ((ack & DP_AUX_NATIVE_REPLY_MASK) == DP_AUX_NATIVE_REPLY_DEFER) |
611 | udelay(100); | 615 | usleep_range(400, 500); |
612 | else | 616 | else |
613 | return -EIO; | 617 | return -EIO; |
614 | } | 618 | } |
619 | |||
620 | DRM_ERROR("too many retries, giving up\n"); | ||
621 | return -EIO; | ||
615 | } | 622 | } |
616 | 623 | ||
617 | static int | 624 | static int |
@@ -1242,17 +1249,24 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
1242 | 1249 | ||
1243 | DRM_DEBUG_KMS("Turn eDP power off\n"); | 1250 | DRM_DEBUG_KMS("Turn eDP power off\n"); |
1244 | 1251 | ||
1252 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); | ||
1253 | |||
1245 | pp = ironlake_get_pp_control(intel_dp); | 1254 | pp = ironlake_get_pp_control(intel_dp); |
1246 | /* We need to switch off panel power _and_ force vdd, for otherwise some | 1255 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
1247 | * panels get very unhappy and cease to work. */ | 1256 | * panels get very unhappy and cease to work. */ |
1248 | pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1257 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); |
1249 | 1258 | ||
1250 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); | 1259 | pp_ctrl_reg = _pp_ctrl_reg(intel_dp); |
1251 | 1260 | ||
1252 | I915_WRITE(pp_ctrl_reg, pp); | 1261 | I915_WRITE(pp_ctrl_reg, pp); |
1253 | POSTING_READ(pp_ctrl_reg); | 1262 | POSTING_READ(pp_ctrl_reg); |
1254 | 1263 | ||
1264 | intel_dp->want_panel_vdd = false; | ||
1265 | |||
1255 | ironlake_wait_panel_off(intel_dp); | 1266 | ironlake_wait_panel_off(intel_dp); |
1267 | |||
1268 | /* We got a reference when we enabled the VDD. */ | ||
1269 | intel_runtime_pm_put(dev_priv); | ||
1256 | } | 1270 | } |
1257 | 1271 | ||
1258 | void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | 1272 | void ironlake_edp_backlight_on(struct intel_dp *intel_dp) |
@@ -1632,7 +1646,7 @@ static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) | |||
1632 | val |= EDP_PSR_LINK_DISABLE; | 1646 | val |= EDP_PSR_LINK_DISABLE; |
1633 | 1647 | ||
1634 | I915_WRITE(EDP_PSR_CTL(dev), val | | 1648 | I915_WRITE(EDP_PSR_CTL(dev), val | |
1635 | IS_BROADWELL(dev) ? 0 : link_entry_time | | 1649 | (IS_BROADWELL(dev) ? 0 : link_entry_time) | |
1636 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | | 1650 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | |
1637 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | | 1651 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | |
1638 | EDP_PSR_ENABLE); | 1652 | EDP_PSR_ENABLE); |
@@ -1777,6 +1791,7 @@ static void intel_disable_dp(struct intel_encoder *encoder) | |||
1777 | 1791 | ||
1778 | /* Make sure the panel is off before trying to change the mode. But also | 1792 | /* Make sure the panel is off before trying to change the mode. But also |
1779 | * ensure that we have vdd while we switch off the panel. */ | 1793 | * ensure that we have vdd while we switch off the panel. */ |
1794 | ironlake_edp_panel_vdd_on(intel_dp); | ||
1780 | ironlake_edp_backlight_off(intel_dp); | 1795 | ironlake_edp_backlight_off(intel_dp); |
1781 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); | 1796 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); |
1782 | ironlake_edp_panel_off(intel_dp); | 1797 | ironlake_edp_panel_off(intel_dp); |
@@ -1869,10 +1884,12 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder) | |||
1869 | 1884 | ||
1870 | mutex_unlock(&dev_priv->dpio_lock); | 1885 | mutex_unlock(&dev_priv->dpio_lock); |
1871 | 1886 | ||
1872 | /* init power sequencer on this pipe and port */ | 1887 | if (is_edp(intel_dp)) { |
1873 | intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); | 1888 | /* init power sequencer on this pipe and port */ |
1874 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, | 1889 | intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); |
1875 | &power_seq); | 1890 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, |
1891 | &power_seq); | ||
1892 | } | ||
1876 | 1893 | ||
1877 | intel_enable_dp(encoder); | 1894 | intel_enable_dp(encoder); |
1878 | 1895 | ||