Skip to content

Commit dfd2e9a

Browse files
vsyrjalaairlied
authored andcommitted
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 <[email protected]> Reviewed-by: Daniel Vetter <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
1 parent 6608804 commit dfd2e9a

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

drivers/gpu/drm/i915/intel_drv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,8 @@ bool intel_sdvo_init(struct drm_device *dev,
17301730

17311731

17321732
/* intel_sprite.c */
1733+
int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
1734+
int usecs);
17331735
int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
17341736
int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
17351737
struct drm_file *file_priv);

drivers/gpu/drm/i915/intel_psr.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,9 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
327327
struct drm_i915_private *dev_priv = to_i915(dev);
328328
struct drm_crtc *crtc = dig_port->base.base.crtc;
329329
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;
330333

331334
lockdep_assert_held(&dev_priv->psr.lock);
332335
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)
365368
}
366369

367370
if (IS_HASWELL(dev) &&
368-
intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
371+
adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
369372
DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
370373
return false;
371374
}
372375

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+
373390
dev_priv->psr.source_ok = true;
374391
return true;
375392
}

drivers/gpu/drm/i915/intel_sprite.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ format_is_yuv(uint32_t format)
5353
}
5454
}
5555

56-
static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
57-
int usecs)
56+
int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
57+
int usecs)
5858
{
5959
/* paranoia */
6060
if (!adjusted_mode->crtc_htotal)
@@ -91,7 +91,7 @@ void intel_pipe_update_start(struct intel_crtc *crtc)
9191
vblank_start = DIV_ROUND_UP(vblank_start, 2);
9292

9393
/* 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);
9595
max = vblank_start - 1;
9696

9797
local_irq_disable();

0 commit comments

Comments
 (0)