diff options
author | Mahesh Kumar <mahesh1.kumar@intel.com> | 2018-04-26 10:25:16 -0400 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2018-04-27 20:11:51 -0400 |
commit | aa9664ffe863f470efdbe40ea20ce96f2887ebcd (patch) | |
tree | e903e51518892208579adadee50c0008aacfa34f /drivers/gpu/drm/i915/intel_runtime_pm.c | |
parent | 74bd8004e475d67eb41f6795cda5efac03d010b8 (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.c | 65 |
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 | ||
2622 | static void gen9_dbuf_enable(struct drm_i915_private *dev_priv) | 2622 | static inline |
2623 | bool 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 | |||
2643 | static 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 | ||
2633 | static void gen9_dbuf_disable(struct drm_i915_private *dev_priv) | 2648 | static 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); | 2653 | static 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) | 2660 | void 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 | */ | ||
2648 | static void icl_dbuf_enable(struct drm_i915_private *dev_priv) | 2685 | static 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); |