summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2019-03-19 18:03:11 +0200
committerVille Syrjälä <ville.syrjala@linux.intel.com>2019-03-20 17:16:08 +0200
commitdf331de3f8aac1a8080510d883fa40555809cddf (patch)
tree842bd02ebff0efdd6fc862c6ddc57d028b3ed01a /drivers/gpu
parentc92558aa41722f95160d96b8e1ac8dd36731a836 (diff)
downloadlinux-df331de3f8aac1a8080510d883fa40555809cddf.tar.gz
linux-df331de3f8aac1a8080510d883fa40555809cddf.tar.bz2
linux-df331de3f8aac1a8080510d883fa40555809cddf.zip
drm/i915: Allocate enough DDB for the cursor
Currently we just assume that 32 or 8 blocks of ddb is sufficient for the cursor. The 32 might be, but the 8 is certainly not. The minimum we need is at least what level 0 watermarks need, but that is a bit restrictive, so instead let's calculate what level 7 would need for a 256x256 cursor. We'll use that to determine the fixed ddb allocation for the cursor. This way the cursor will never be responsible for missing out on deeper power saving states. v2: Loop to make sure this works even if some wm levels are totally disabled (latency==0) Cc: Neel Desai <neel.desai@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> #v1 Link: https://patchwork.freedesktop.org/patch/msgid/20190319160311.23529-1-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9e7b4412f7a8..b35a55a59680 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3924,12 +3924,43 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
alloc->end = ddb_size * (width_before_pipe + pipe_width) / total_width;
}
-static unsigned int skl_cursor_allocation(int num_active)
+static int skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
+ int width, const struct drm_format_info *format,
+ u64 modifier, unsigned int rotation,
+ u32 plane_pixel_rate, struct skl_wm_params *wp,
+ int color_plane);
+static void skl_compute_plane_wm(const struct intel_crtc_state *cstate,
+ int level,
+ const struct skl_wm_params *wp,
+ const struct skl_wm_level *result_prev,
+ struct skl_wm_level *result /* out */);
+
+static unsigned int
+skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
+ int num_active)
{
- if (num_active == 1)
- return 32;
+ struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+ int level, max_level = ilk_wm_max_level(dev_priv);
+ struct skl_wm_level wm = {};
+ int ret, min_ddb_alloc = 0;
+ struct skl_wm_params wp;
+
+ ret = skl_compute_wm_params(crtc_state, 256,
+ drm_format_info(DRM_FORMAT_ARGB8888),
+ DRM_FORMAT_MOD_LINEAR,
+ DRM_MODE_ROTATE_0,
+ crtc_state->pixel_rate, &wp, 0);
+ WARN_ON(ret);
+
+ for (level = 0; level <= max_level; level++) {
+ skl_compute_plane_wm(crtc_state, 7, &wp, &wm, &wm);
+ if (wm.min_ddb_alloc == U16_MAX)
+ break;
+
+ min_ddb_alloc = wm.min_ddb_alloc;
+ }
- return 8;
+ return max(num_active == 1 ? 32 : 8, min_ddb_alloc);
}
static void skl_ddb_entry_init_from_hw(struct drm_i915_private *dev_priv,
@@ -4354,7 +4385,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
return 0;
/* Allocate fixed number of blocks for cursor. */
- total[PLANE_CURSOR] = skl_cursor_allocation(num_active);
+ total[PLANE_CURSOR] = skl_cursor_allocation(cstate, num_active);
alloc_size -= total[PLANE_CURSOR];
cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].start =
alloc->end - total[PLANE_CURSOR];