aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_runtime_pm.c
diff options
context:
space:
mode:
authorMahesh Kumar <mahesh1.kumar@intel.com>2018-04-26 10:25:16 -0400
committerRodrigo Vivi <rodrigo.vivi@intel.com>2018-04-27 20:11:51 -0400
commitaa9664ffe863f470efdbe40ea20ce96f2887ebcd (patch)
treee903e51518892208579adadee50c0008aacfa34f /drivers/gpu/drm/i915/intel_runtime_pm.c
parent74bd8004e475d67eb41f6795cda5efac03d010b8 (diff)
drm/i915/icl: Enable 2nd DBuf slice only when needed
ICL has two slices of DBuf, each slice of size 1024 blocks. We should not always enable slice-2. It should be enabled only if display total required BW is > 12GBps OR more than 1 pipes are enabled. Changes since V1: - typecast total_data_rate to u64 before multiplication to solve any possible overflow (Rodrigo) - fix where skl_wm_get_hw_state was memsetting ddb, resulting enabled_slices to become zero - Fix the logic of calculating ddb_size Changes since V2: - If no-crtc is part of commit required_slices will have value "0", don't try to disable DBuf slice. Changes since V3: - Create a generic helper to enable/disable slice - don't return early if total_data_rate is 0, it may be cursor only commit, or atomic modeset without any plane. Changes since V4: - Solve checkpatch warnings - use kernel types u8/u64 instead of uint8_t/uint64_t Changes since V5: - Rebase Signed-off-by: Mahesh Kumar <mahesh1.kumar@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180426142517.16643-3-mahesh1.kumar@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/intel_runtime_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_runtime_pm.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index afc6ef81ca0c..3fffbfe4521d 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -2619,32 +2619,69 @@ static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv)
2619 mutex_unlock(&power_domains->lock); 2619 mutex_unlock(&power_domains->lock);
2620} 2620}
2621 2621
2622static void gen9_dbuf_enable(struct drm_i915_private *dev_priv) 2622static inline
2623bool intel_dbuf_slice_set(struct drm_i915_private *dev_priv,
2624 i915_reg_t reg, bool enable)
2623{ 2625{
2624 I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) | DBUF_POWER_REQUEST); 2626 u32 val, status;
2625 POSTING_READ(DBUF_CTL);
2626 2627
2628 val = I915_READ(reg);
2629 val = enable ? (val | DBUF_POWER_REQUEST) : (val & ~DBUF_POWER_REQUEST);
2630 I915_WRITE(reg, val);
2631 POSTING_READ(reg);
2627 udelay(10); 2632 udelay(10);
2628 2633
2629 if (!(I915_READ(DBUF_CTL) & DBUF_POWER_STATE)) 2634 status = I915_READ(reg) & DBUF_POWER_STATE;
2630 DRM_ERROR("DBuf power enable timeout\n"); 2635 if ((enable && !status) || (!enable && status)) {
2636 DRM_ERROR("DBus power %s timeout!\n",
2637 enable ? "enable" : "disable");
2638 return false;
2639 }
2640 return true;
2641}
2642
2643static void gen9_dbuf_enable(struct drm_i915_private *dev_priv)
2644{
2645 intel_dbuf_slice_set(dev_priv, DBUF_CTL, true);
2631} 2646}
2632 2647
2633static void gen9_dbuf_disable(struct drm_i915_private *dev_priv) 2648static void gen9_dbuf_disable(struct drm_i915_private *dev_priv)
2634{ 2649{
2635 I915_WRITE(DBUF_CTL, I915_READ(DBUF_CTL) & ~DBUF_POWER_REQUEST); 2650 intel_dbuf_slice_set(dev_priv, DBUF_CTL, false);
2636 POSTING_READ(DBUF_CTL); 2651}
2637 2652
2638 udelay(10); 2653static u8 intel_dbuf_max_slices(struct drm_i915_private *dev_priv)
2654{
2655 if (INTEL_GEN(dev_priv) < 11)
2656 return 1;
2657 return 2;
2658}
2639 2659
2640 if (I915_READ(DBUF_CTL) & DBUF_POWER_STATE) 2660void icl_dbuf_slices_update(struct drm_i915_private *dev_priv,
2641 DRM_ERROR("DBuf power disable timeout!\n"); 2661 u8 req_slices)
2662{
2663 u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
2664 u32 val;
2665 bool ret;
2666
2667 if (req_slices > intel_dbuf_max_slices(dev_priv)) {
2668 DRM_ERROR("Invalid number of dbuf slices requested\n");
2669 return;
2670 }
2671
2672 if (req_slices == hw_enabled_slices || req_slices == 0)
2673 return;
2674
2675 val = I915_READ(DBUF_CTL_S2);
2676 if (req_slices > hw_enabled_slices)
2677 ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, true);
2678 else
2679 ret = intel_dbuf_slice_set(dev_priv, DBUF_CTL_S2, false);
2680
2681 if (ret)
2682 dev_priv->wm.skl_hw.ddb.enabled_slices = req_slices;
2642} 2683}
2643 2684
2644/*
2645 * TODO: we shouldn't always enable DBUF_CTL_S2, we should only enable it when
2646 * needed and keep it disabled as much as possible.
2647 */
2648static void icl_dbuf_enable(struct drm_i915_private *dev_priv) 2685static void icl_dbuf_enable(struct drm_i915_private *dev_priv)
2649{ 2686{
2650 I915_WRITE(DBUF_CTL_S1, I915_READ(DBUF_CTL_S1) | DBUF_POWER_REQUEST); 2687 I915_WRITE(DBUF_CTL_S1, I915_READ(DBUF_CTL_S1) | DBUF_POWER_REQUEST);