diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_psr.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_psr.c | 77 |
1 files changed, 52 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c index 213581c215b3..bc5ea2a6cf4c 100644 --- a/drivers/gpu/drm/i915/intel_psr.c +++ b/drivers/gpu/drm/i915/intel_psr.c | |||
| @@ -80,7 +80,7 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp, | |||
| 80 | struct drm_i915_private *dev_priv = dev->dev_private; | 80 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 81 | struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); | 81 | struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); |
| 82 | enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; | 82 | enum transcoder cpu_transcoder = crtc->config->cpu_transcoder; |
| 83 | u32 ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder); | 83 | i915_reg_t ctl_reg = HSW_TVIDEO_DIP_CTL(cpu_transcoder); |
| 84 | uint32_t *data = (uint32_t *) vsc_psr; | 84 | uint32_t *data = (uint32_t *) vsc_psr; |
| 85 | unsigned int i; | 85 | unsigned int i; |
| 86 | 86 | ||
| @@ -151,13 +151,31 @@ static void vlv_psr_enable_sink(struct intel_dp *intel_dp) | |||
| 151 | DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE); | 151 | DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | static i915_reg_t psr_aux_ctl_reg(struct drm_i915_private *dev_priv, | ||
| 155 | enum port port) | ||
| 156 | { | ||
| 157 | if (INTEL_INFO(dev_priv)->gen >= 9) | ||
| 158 | return DP_AUX_CH_CTL(port); | ||
| 159 | else | ||
| 160 | return EDP_PSR_AUX_CTL; | ||
| 161 | } | ||
| 162 | |||
| 163 | static i915_reg_t psr_aux_data_reg(struct drm_i915_private *dev_priv, | ||
| 164 | enum port port, int index) | ||
| 165 | { | ||
| 166 | if (INTEL_INFO(dev_priv)->gen >= 9) | ||
| 167 | return DP_AUX_CH_DATA(port, index); | ||
| 168 | else | ||
| 169 | return EDP_PSR_AUX_DATA(index); | ||
| 170 | } | ||
| 171 | |||
| 154 | static void hsw_psr_enable_sink(struct intel_dp *intel_dp) | 172 | static void hsw_psr_enable_sink(struct intel_dp *intel_dp) |
| 155 | { | 173 | { |
| 156 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); | 174 | struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); |
| 157 | struct drm_device *dev = dig_port->base.base.dev; | 175 | struct drm_device *dev = dig_port->base.base.dev; |
| 158 | struct drm_i915_private *dev_priv = dev->dev_private; | 176 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 159 | uint32_t aux_clock_divider; | 177 | uint32_t aux_clock_divider; |
| 160 | uint32_t aux_data_reg, aux_ctl_reg; | 178 | i915_reg_t aux_ctl_reg; |
| 161 | int precharge = 0x3; | 179 | int precharge = 0x3; |
| 162 | static const uint8_t aux_msg[] = { | 180 | static const uint8_t aux_msg[] = { |
| 163 | [0] = DP_AUX_NATIVE_WRITE << 4, | 181 | [0] = DP_AUX_NATIVE_WRITE << 4, |
| @@ -166,6 +184,7 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) | |||
| 166 | [3] = 1 - 1, | 184 | [3] = 1 - 1, |
| 167 | [4] = DP_SET_POWER_D0, | 185 | [4] = DP_SET_POWER_D0, |
| 168 | }; | 186 | }; |
| 187 | enum port port = dig_port->port; | ||
| 169 | int i; | 188 | int i; |
| 170 | 189 | ||
| 171 | BUILD_BUG_ON(sizeof(aux_msg) > 20); | 190 | BUILD_BUG_ON(sizeof(aux_msg) > 20); |
| @@ -181,14 +200,11 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp) | |||
| 181 | DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF, | 200 | DP_SINK_DEVICE_AUX_FRAME_SYNC_CONF, |
| 182 | DP_AUX_FRAME_SYNC_ENABLE); | 201 | DP_AUX_FRAME_SYNC_ENABLE); |
| 183 | 202 | ||
| 184 | aux_data_reg = (INTEL_INFO(dev)->gen >= 9) ? | 203 | aux_ctl_reg = psr_aux_ctl_reg(dev_priv, port); |
| 185 | DPA_AUX_CH_DATA1 : EDP_PSR_AUX_DATA1(dev); | ||
| 186 | aux_ctl_reg = (INTEL_INFO(dev)->gen >= 9) ? | ||
| 187 | DPA_AUX_CH_CTL : EDP_PSR_AUX_CTL(dev); | ||
| 188 | 204 | ||
| 189 | /* Setup AUX registers */ | 205 | /* Setup AUX registers */ |
| 190 | for (i = 0; i < sizeof(aux_msg); i += 4) | 206 | for (i = 0; i < sizeof(aux_msg); i += 4) |
| 191 | I915_WRITE(aux_data_reg + i, | 207 | I915_WRITE(psr_aux_data_reg(dev_priv, port, i >> 2), |
| 192 | intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); | 208 | intel_dp_pack_aux(&aux_msg[i], sizeof(aux_msg) - i)); |
| 193 | 209 | ||
| 194 | if (INTEL_INFO(dev)->gen >= 9) { | 210 | if (INTEL_INFO(dev)->gen >= 9) { |
| @@ -267,16 +283,11 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) | |||
| 267 | const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; | 283 | const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; |
| 268 | 284 | ||
| 269 | if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) { | 285 | if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) { |
| 270 | /* It doesn't mean we shouldn't send TPS patters, so let's | ||
| 271 | send the minimal TP1 possible and skip TP2. */ | ||
| 272 | val |= EDP_PSR_TP1_TIME_100us; | ||
| 273 | val |= EDP_PSR_TP2_TP3_TIME_0us; | ||
| 274 | val |= EDP_PSR_SKIP_AUX_EXIT; | ||
| 275 | /* Sink should be able to train with the 5 or 6 idle patterns */ | 286 | /* Sink should be able to train with the 5 or 6 idle patterns */ |
| 276 | idle_frames += 4; | 287 | idle_frames += 4; |
| 277 | } | 288 | } |
| 278 | 289 | ||
| 279 | I915_WRITE(EDP_PSR_CTL(dev), val | | 290 | I915_WRITE(EDP_PSR_CTL, val | |
| 280 | (IS_BROADWELL(dev) ? 0 : link_entry_time) | | 291 | (IS_BROADWELL(dev) ? 0 : link_entry_time) | |
| 281 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | | 292 | max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | |
| 282 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | | 293 | idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | |
| @@ -340,7 +351,7 @@ static void intel_psr_activate(struct intel_dp *intel_dp) | |||
| 340 | struct drm_device *dev = intel_dig_port->base.base.dev; | 351 | struct drm_device *dev = intel_dig_port->base.base.dev; |
| 341 | struct drm_i915_private *dev_priv = dev->dev_private; | 352 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 342 | 353 | ||
| 343 | WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE); | 354 | WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE); |
| 344 | WARN_ON(dev_priv->psr.active); | 355 | WARN_ON(dev_priv->psr.active); |
| 345 | lockdep_assert_held(&dev_priv->psr.lock); | 356 | lockdep_assert_held(&dev_priv->psr.lock); |
| 346 | 357 | ||
| @@ -404,7 +415,7 @@ void intel_psr_enable(struct intel_dp *intel_dp) | |||
| 404 | } | 415 | } |
| 405 | 416 | ||
| 406 | /* Avoid continuous PSR exit by masking memup and hpd */ | 417 | /* Avoid continuous PSR exit by masking memup and hpd */ |
| 407 | I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | | 418 | I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP | |
| 408 | EDP_PSR_DEBUG_MASK_HPD); | 419 | EDP_PSR_DEBUG_MASK_HPD); |
| 409 | 420 | ||
| 410 | /* Enable PSR on the panel */ | 421 | /* Enable PSR on the panel */ |
| @@ -427,6 +438,19 @@ void intel_psr_enable(struct intel_dp *intel_dp) | |||
| 427 | vlv_psr_enable_source(intel_dp); | 438 | vlv_psr_enable_source(intel_dp); |
| 428 | } | 439 | } |
| 429 | 440 | ||
| 441 | /* | ||
| 442 | * FIXME: Activation should happen immediately since this function | ||
| 443 | * is just called after pipe is fully trained and enabled. | ||
| 444 | * However on every platform we face issues when first activation | ||
| 445 | * follows a modeset so quickly. | ||
| 446 | * - On VLV/CHV we get bank screen on first activation | ||
| 447 | * - On HSW/BDW we get a recoverable frozen screen until next | ||
| 448 | * exit-activate sequence. | ||
| 449 | */ | ||
| 450 | if (INTEL_INFO(dev)->gen < 9) | ||
| 451 | schedule_delayed_work(&dev_priv->psr.work, | ||
| 452 | msecs_to_jiffies(intel_dp->panel_power_cycle_delay * 5)); | ||
| 453 | |||
| 430 | dev_priv->psr.enabled = intel_dp; | 454 | dev_priv->psr.enabled = intel_dp; |
| 431 | unlock: | 455 | unlock: |
| 432 | mutex_unlock(&dev_priv->psr.lock); | 456 | mutex_unlock(&dev_priv->psr.lock); |
| @@ -466,17 +490,17 @@ static void hsw_psr_disable(struct intel_dp *intel_dp) | |||
| 466 | struct drm_i915_private *dev_priv = dev->dev_private; | 490 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 467 | 491 | ||
| 468 | if (dev_priv->psr.active) { | 492 | if (dev_priv->psr.active) { |
| 469 | I915_WRITE(EDP_PSR_CTL(dev), | 493 | I915_WRITE(EDP_PSR_CTL, |
| 470 | I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE); | 494 | I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE); |
| 471 | 495 | ||
| 472 | /* Wait till PSR is idle */ | 496 | /* Wait till PSR is idle */ |
| 473 | if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) & | 497 | if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) & |
| 474 | EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) | 498 | EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10)) |
| 475 | DRM_ERROR("Timed out waiting for PSR Idle State\n"); | 499 | DRM_ERROR("Timed out waiting for PSR Idle State\n"); |
| 476 | 500 | ||
| 477 | dev_priv->psr.active = false; | 501 | dev_priv->psr.active = false; |
| 478 | } else { | 502 | } else { |
| 479 | WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE); | 503 | WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE); |
| 480 | } | 504 | } |
| 481 | } | 505 | } |
| 482 | 506 | ||
| @@ -523,7 +547,7 @@ static void intel_psr_work(struct work_struct *work) | |||
| 523 | * and be ready for re-enable. | 547 | * and be ready for re-enable. |
| 524 | */ | 548 | */ |
| 525 | if (HAS_DDI(dev_priv->dev)) { | 549 | if (HAS_DDI(dev_priv->dev)) { |
| 526 | if (wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev_priv->dev)) & | 550 | if (wait_for((I915_READ(EDP_PSR_STATUS_CTL) & |
| 527 | EDP_PSR_STATUS_STATE_MASK) == 0, 50)) { | 551 | EDP_PSR_STATUS_STATE_MASK) == 0, 50)) { |
| 528 | DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n"); | 552 | DRM_ERROR("Timed out waiting for PSR Idle for re-enable\n"); |
| 529 | return; | 553 | return; |
| @@ -566,11 +590,11 @@ static void intel_psr_exit(struct drm_device *dev) | |||
| 566 | return; | 590 | return; |
| 567 | 591 | ||
| 568 | if (HAS_DDI(dev)) { | 592 | if (HAS_DDI(dev)) { |
| 569 | val = I915_READ(EDP_PSR_CTL(dev)); | 593 | val = I915_READ(EDP_PSR_CTL); |
| 570 | 594 | ||
| 571 | WARN_ON(!(val & EDP_PSR_ENABLE)); | 595 | WARN_ON(!(val & EDP_PSR_ENABLE)); |
| 572 | 596 | ||
| 573 | I915_WRITE(EDP_PSR_CTL(dev), val & ~EDP_PSR_ENABLE); | 597 | I915_WRITE(EDP_PSR_CTL, val & ~EDP_PSR_ENABLE); |
| 574 | } else { | 598 | } else { |
| 575 | val = I915_READ(VLV_PSRCTL(pipe)); | 599 | val = I915_READ(VLV_PSRCTL(pipe)); |
| 576 | 600 | ||
| @@ -700,7 +724,6 @@ void intel_psr_flush(struct drm_device *dev, | |||
| 700 | struct drm_i915_private *dev_priv = dev->dev_private; | 724 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 701 | struct drm_crtc *crtc; | 725 | struct drm_crtc *crtc; |
| 702 | enum pipe pipe; | 726 | enum pipe pipe; |
| 703 | int delay_ms = HAS_DDI(dev) ? 100 : 500; | ||
| 704 | 727 | ||
| 705 | mutex_lock(&dev_priv->psr.lock); | 728 | mutex_lock(&dev_priv->psr.lock); |
| 706 | if (!dev_priv->psr.enabled) { | 729 | if (!dev_priv->psr.enabled) { |
| @@ -735,8 +758,9 @@ void intel_psr_flush(struct drm_device *dev, | |||
| 735 | } | 758 | } |
| 736 | 759 | ||
| 737 | if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) | 760 | if (!dev_priv->psr.active && !dev_priv->psr.busy_frontbuffer_bits) |
| 738 | schedule_delayed_work(&dev_priv->psr.work, | 761 | if (!work_busy(&dev_priv->psr.work.work)) |
| 739 | msecs_to_jiffies(delay_ms)); | 762 | schedule_delayed_work(&dev_priv->psr.work, |
| 763 | msecs_to_jiffies(100)); | ||
| 740 | mutex_unlock(&dev_priv->psr.lock); | 764 | mutex_unlock(&dev_priv->psr.lock); |
| 741 | } | 765 | } |
| 742 | 766 | ||
| @@ -751,6 +775,9 @@ void intel_psr_init(struct drm_device *dev) | |||
| 751 | { | 775 | { |
| 752 | struct drm_i915_private *dev_priv = dev->dev_private; | 776 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 753 | 777 | ||
| 778 | dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ? | ||
| 779 | HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE; | ||
| 780 | |||
| 754 | INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work); | 781 | INIT_DELAYED_WORK(&dev_priv->psr.work, intel_psr_work); |
| 755 | mutex_init(&dev_priv->psr.lock); | 782 | mutex_init(&dev_priv->psr.lock); |
| 756 | } | 783 | } |
