Merge tag 'drm-intel-next-2016-08-08' of git://anongit.freedesktop.org/drm-intel...
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_psr.c
index adf2ce0..59a21c9 100644 (file)
@@ -327,6 +327,9 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
        struct drm_i915_private *dev_priv = to_i915(dev);
        struct drm_crtc *crtc = dig_port->base.base.crtc;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       const struct drm_display_mode *adjusted_mode =
+               &intel_crtc->config->base.adjusted_mode;
+       int psr_setup_time;
 
        lockdep_assert_held(&dev_priv->psr.lock);
        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)
        }
 
        if (IS_HASWELL(dev) &&
-           intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+           adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
                DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
                return false;
        }
 
+       psr_setup_time = drm_dp_psr_setup_time(intel_dp->psr_dpcd);
+       if (psr_setup_time < 0) {
+               DRM_DEBUG_KMS("PSR condition failed: Invalid PSR setup time (0x%02x)\n",
+                             intel_dp->psr_dpcd[1]);
+               return false;
+       }
+
+       if (intel_usecs_to_scanlines(adjusted_mode, psr_setup_time) >
+           adjusted_mode->crtc_vtotal - adjusted_mode->crtc_vdisplay - 1) {
+               DRM_DEBUG_KMS("PSR condition failed: PSR setup time (%d us) too long\n",
+                             psr_setup_time);
+               return false;
+       }
+
        dev_priv->psr.source_ok = true;
        return true;
 }