From 9c65f9d9ef788f7b6fe47f7dd264592fd16bbd70 Mon Sep 17 00:00:00 2001 From: Mahesh Kumar Date: Thu, 15 Jun 2017 20:37:00 +0530 Subject: [PATCH] [RFC] drm/i915/skl+: Don't fix cursor WM in multipipe scenario We allocate fixed 8 blocks to cursor plane. Soe times these blocks are not sufficient to enable cursor level-0 WM, So we can't enable cursor plane. If we enable plane, it results in fifo underrun and screen corruption. This patch increases the cursor DDB in multipipe scenario according to the requirement. It keep track of maximum requirement by pipe & allocate it. This way we avoids reallocating cursor WM very frequently. Signed-off-by: Mahesh Kumar --- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 83dd40905821..c30aaf0abf03 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -568,6 +568,7 @@ struct intel_crtc_wm_state { struct { /* gen9+ only needs 1-step wm programming */ struct skl_pipe_wm optimal; + uint16_t cursor_ddb; struct skl_ddb_entry ddb; } skl; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 55ec8514c74a..349befc72f63 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3712,7 +3712,7 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state) static void skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, - const struct intel_crtc_state *cstate, + struct intel_crtc_state *cstate, struct skl_ddb_entry *alloc, /* out */ int *num_active /* out */) { @@ -3754,9 +3754,13 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, * copy from old state to be sure */ *alloc = to_intel_crtc_state(for_crtc->state)->wm.skl.ddb; + cstate->wm.skl.cursor_ddb = + to_intel_crtc_state(for_crtc->state)->wm.skl.cursor_ddb; return; } + /* Reset Cursor stored max ddb to 0 on active pipe change */ + cstate->wm.skl.cursor_ddb = 0; nth_active_pipe = hweight32(intel_state->active_crtcs & (drm_crtc_mask(for_crtc) - 1)); pipe_size = ddb_size / hweight32(intel_state->active_crtcs); @@ -3764,12 +3768,36 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev, alloc->end = alloc->start + pipe_size; } -static unsigned int skl_cursor_allocation(int num_active) +static unsigned int skl_cursor_allocation(struct intel_crtc_state *cstate, + struct skl_pipe_wm *pipe_wm, + int num_active) { + uint16_t stored_ddb = cstate->wm.skl.cursor_ddb; + uint16_t req_ddb = pipe_wm->planes[PLANE_CURSOR].wm[0].plane_res_b; + uint16_t new_ddb = stored_ddb; + bool ddb_modified = false; + if (num_active == 1) return 32; - return 8; + if (stored_ddb < req_ddb) + ddb_modified = true; + + if (!ddb_modified) + goto exit; + + if (req_ddb < 8) + new_ddb = 8; + else if (req_ddb < 16) + new_ddb = 16; + else if (req_ddb < 24) + new_ddb = 24; + else + new_ddb = 32; + + cstate->wm.skl.cursor_ddb = new_ddb; +exit: + return cstate->wm.skl.cursor_ddb; } static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg) @@ -4136,8 +4164,6 @@ skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active, minimum[plane_id] = skl_ddb_min_alloc(pstate, 0); y_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1); } - - minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active); } static void @@ -4208,6 +4234,8 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, skl_ddb_calc_min(cstate, num_active, minimum, y_minimum); + minimum[PLANE_CURSOR] = skl_cursor_allocation(cstate, pipe_wm, num_active); + /* * 1. Allocate the mininum required blocks for each active plane * and allocate the cursor, it doesn't require extra allocation -- 2.13.0