aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-05-18 04:34:38 -0400
committerDave Airlie <airlied@redhat.com>2016-08-02 17:06:41 -0400
commitdfd2e9ab6a7db56a5f5bb55f71485a92613c8e11 (patch)
tree968afed7882d42d34c35f96ae1d7fb25aefc2451
parent6608804b3d7f0552a38641b03a4e3aa1852df15b (diff)
drm/i915: Check PSR setup time vs. vblank length
Bspec says: "Restriction : SRD must not be enabled when the PSR Setup time from DPCD 00071h is greater than the time for vertical blank minus one line." Let's check for that and disallow PSR if we exceed the limit. Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c19
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c6
3 files changed, 23 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 3329fc6a95f4..cc937a19b1ba 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1730,6 +1730,8 @@ bool intel_sdvo_init(struct drm_device *dev,
1730 1730
1731 1731
1732/* intel_sprite.c */ 1732/* intel_sprite.c */
1733int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
1734 int usecs);
1733int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); 1735int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
1734int intel_sprite_set_colorkey(struct drm_device *dev, void *data, 1736int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
1735 struct drm_file *file_priv); 1737 struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 68bd0bb34817..2b0d1baf15b3 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -327,6 +327,9 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
327 struct drm_i915_private *dev_priv = to_i915(dev); 327 struct drm_i915_private *dev_priv = to_i915(dev);
328 struct drm_crtc *crtc = dig_port->base.base.crtc; 328 struct drm_crtc *crtc = dig_port->base.base.crtc;
329 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 329 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
330 const struct drm_display_mode *adjusted_mode =
331 &intel_crtc->config->base.adjusted_mode;
332 int psr_setup_time;
330 333
331 lockdep_assert_held(&dev_priv->psr.lock); 334 lockdep_assert_held(&dev_priv->psr.lock);
332 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); 335 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
@@ -365,11 +368,25 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
365 } 368 }
366 369
367 if (IS_HASWELL(dev) && 370 if (IS_HASWELL(dev) &&
368 intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { 371 adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
369 DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n"); 372 DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
370 return false; 373 return false;
371 } 374 }
372 375
376 psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd);
377 if (psr_setup_time < 0) {
378 DRM_DEBUG_KMS("PSR condition failed: Invalid PSR setup time (0x%02x)\n",
379 intel_dp->psr_dpcd[1]);
380 return false;
381 }
382
383 if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) >
384 adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay - 1) {
385 DRM_DEBUG_KMS("PSR condition failed: PSR setup time (%d us) too long\n",
386 psr_setup_time);
387 return false;
388 }
389
373 dev_priv->psr.source_ok = true; 390 dev_priv->psr.source_ok = true;
374 return true; 391 return true;
375} 392}
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0de935ad01c2..7c08e4f29032 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -53,8 +53,8 @@ format_is_yuv(uint32_t format)
53 } 53 }
54} 54}
55 55
56static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, 56int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
57 int usecs) 57 int usecs)
58{ 58{
59 /* paranoia */ 59 /* paranoia */
60 if (!adjusted_mode->crtc_htotal) 60 if (!adjusted_mode->crtc_htotal)
@@ -91,7 +91,7 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
91 vblank_start = DIV_ROUND_UP(vblank_start, 2); 91 vblank_start = DIV_ROUND_UP(vblank_start, 2);
92 92
93 /* FIXME needs to be calibrated sensibly */ 93 /* FIXME needs to be calibrated sensibly */
94 min = vblank_start - usecs_to_scanlines(adjusted_mode, 100); 94 min = vblank_start - intel_usecs_to_scanlines(adjusted_mode, 100);
95 max = vblank_start - 1; 95 max = vblank_start - 1;
96 96
97 local_irq_disable(); 97 local_irq_disable();