summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_psr.c
diff options
context:
space:
mode:
authorJosé Roberto de Souza <jose.souza@intel.com>2018-11-06 22:08:41 +0300
committerJosé Roberto de Souza <jose.souza@intel.com>2018-11-09 21:49:38 +0300
commitb2fc2252ce41d004a23be7dd90ab3b88394df4d6 (patch)
tree0b719c7bca96ee27b2f63bc1818171cba547e140 /drivers/gpu/drm/i915/intel_psr.c
parent26f9ec9a9a4a2d97a86f6bd0084dcda4d88b89ef (diff)
downloadlinux-b2fc2252ce41d004a23be7dd90ab3b88394df4d6.tar.xz
drm/i915/psr: Always wait for idle state when disabling PSR
It should always wait for idle state when disabling PSR because PSR could be inactive due a call to intel_psr_exit() and while PSR is still being disabled asynchronously userspace could change the modeset causing a call to psr_disable() that will not wait for PSR idle and then PSR will be enabled again while PSR is still not idle. v2: rebased on top of the patch reusing psr_exit() Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181106190843.18009-2-jose.souza@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_psr.c')
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c41
1 files changed, 18 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 2ecc2db67395..81ec31784766 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -661,8 +661,12 @@ static void intel_psr_exit(struct drm_i915_private *dev_priv)
{
u32 val;
- if (!dev_priv->psr.active)
+ if (!dev_priv->psr.active) {
+ if (INTEL_GEN(dev_priv) >= 9)
+ WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE);
+ WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
return;
+ }
if (dev_priv->psr.psr2_enabled) {
val = I915_READ(EDP_PSR2_CTL);
@@ -680,32 +684,23 @@ static void
intel_psr_disable_source(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ i915_reg_t psr_status;
+ u32 psr_status_mask;
- if (dev_priv->psr.active) {
- i915_reg_t psr_status;
- u32 psr_status_mask;
-
- intel_psr_exit(dev_priv);
+ intel_psr_exit(dev_priv);
- if (dev_priv->psr.psr2_enabled) {
- psr_status = EDP_PSR2_STATUS;
- psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
- } else {
- psr_status = EDP_PSR_STATUS;
- psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
- }
-
- /* Wait till PSR is idle */
- if (intel_wait_for_register(dev_priv,
- psr_status, psr_status_mask, 0,
- 2000))
- DRM_ERROR("Timed out waiting for PSR Idle State\n");
+ if (dev_priv->psr.psr2_enabled) {
+ psr_status = EDP_PSR2_STATUS;
+ psr_status_mask = EDP_PSR2_STATUS_STATE_MASK;
} else {
- if (dev_priv->psr.psr2_enabled)
- WARN_ON(I915_READ(EDP_PSR2_CTL) & EDP_PSR2_ENABLE);
- else
- WARN_ON(I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE);
+ psr_status = EDP_PSR_STATUS;
+ psr_status_mask = EDP_PSR_STATUS_STATE_MASK;
}
+
+ /* Wait till PSR is idle */
+ if (intel_wait_for_register(dev_priv, psr_status, psr_status_mask, 0,
+ 2000))
+ DRM_ERROR("Timed out waiting PSR idle state\n");
}
static void intel_psr_disable_locked(struct intel_dp *intel_dp)