summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-11-28 19:37:12 +0200
committerVille Syrjälä <ville.syrjala@linux.intel.com>2016-12-05 16:23:27 +0200
commit11a85d6ab11440c87ff22bcdaa3b97dd5748ae14 (patch)
tree21c5aca2ec87d3adad4647f5098b04bb497c0e37 /drivers/gpu/drm/i915/intel_pm.c
parent3d90e649fa3da5c6e5cb72700584689eb6260082 (diff)
downloadop-kernel-dev-11a85d6ab11440c87ff22bcdaa3b97dd5748ae14.zip
op-kernel-dev-11a85d6ab11440c87ff22bcdaa3b97dd5748ae14.tar.gz
drm/i915: Skip vblank wait if cxsr was already off
Before we attempt to turn any planes on or off we must first exit csxr. That's due to cxsr effectively making the plane enable bits read-only. Currently we achieve that with a vblank wait right after toggling the cxsr enable bit. We do the vblank wait even if cxsr was already off, which seems wasteful, so let's try to only do it when absolutely necessary. We could start tracking the cxsr state fully somewhere, but for now it seems easiest to just have intel_set_memory_cxsr() return the previous cxsr state. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1480354637-14209-11-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 4a9e1f3..cb6b26b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -312,22 +312,30 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable)
#define FW_WM(value, plane) \
(((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK)
-static void _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable)
+static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable)
{
+ bool was_enabled;
u32 val;
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
+ was_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
I915_WRITE(FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0);
POSTING_READ(FW_BLC_SELF_VLV);
} else if (IS_G4X(dev_priv) || IS_CRESTLINE(dev_priv)) {
+ was_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN;
I915_WRITE(FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0);
POSTING_READ(FW_BLC_SELF);
} else if (IS_PINEVIEW(dev_priv)) {
- val = I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN;
- val |= enable ? PINEVIEW_SELF_REFRESH_EN : 0;
+ val = I915_READ(DSPFW3);
+ was_enabled = val & PINEVIEW_SELF_REFRESH_EN;
+ if (enable)
+ val |= PINEVIEW_SELF_REFRESH_EN;
+ else
+ val &= ~PINEVIEW_SELF_REFRESH_EN;
I915_WRITE(DSPFW3, val);
POSTING_READ(DSPFW3);
} else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) {
+ was_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN;
val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) :
_MASKED_BIT_DISABLE(FW_BLC_SELF_EN);
I915_WRITE(FW_BLC_SELF, val);
@@ -338,23 +346,32 @@ static void _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl
* and yet it does have the related watermark in
* FW_BLC_SELF. What's going on?
*/
+ was_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN;
val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) :
_MASKED_BIT_DISABLE(INSTPM_SELF_EN);
I915_WRITE(INSTPM, val);
POSTING_READ(INSTPM);
} else {
- return;
+ return false;
}
- DRM_DEBUG_KMS("memory self-refresh is %s\n", enableddisabled(enable));
+ DRM_DEBUG_KMS("memory self-refresh is %s (was %s)\n",
+ enableddisabled(enable),
+ enableddisabled(was_enabled));
+
+ return was_enabled;
}
-void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable)
+bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable)
{
+ bool ret;
+
mutex_lock(&dev_priv->wm.wm_mutex);
- _intel_set_memory_cxsr(dev_priv, enable);
+ ret = _intel_set_memory_cxsr(dev_priv, enable);
dev_priv->wm.vlv.cxsr = enable;
mutex_unlock(&dev_priv->wm.wm_mutex);
+
+ return ret;
}
/*
OpenPOWER on IntegriCloud