From f1068e8973ee6d91fbce12fe673a04372078ca93 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 28 Sep 2016 21:18:28 -0300 Subject: [PATCH] drm/i915/gen9: only add the planes actually affected by ddb changes We were previously adding all the CRTC's planes even when the ddb partitioning didn't change. This was causing flickering on the primary plane when moving the cursor. With this patch, just moving the mouse won't add the primary plane to the commit. Fixes: 05a76d3d6ad1 ("drm/i915/skl: Ensure pipes with changed wms get added to the state") TODO: - investigate why exactly adding the primary plane causes flickers - improve this commit message - thank and give credit to those who helped the bug - possible bugs: #97888, #97596, #97450, find more Cc: drm-intel-fixes@lists.freedesktop.org Cc: Lyude Reported-and-bisected-by: Mike Lothian Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97888 Signed-off-by: Paulo Zanoni --- drivers/gpu/drm/i915/intel_pm.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 5d39ad2..1cf34a3 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3966,6 +3966,45 @@ pipes_modified(struct drm_atomic_state *state) return ret; } +int +skl_ddb_add_affected_planes(struct intel_crtc_state *cstate) +{ + struct drm_atomic_state *state = cstate->base.state; + struct drm_device *dev = state->dev; + struct drm_crtc *crtc = cstate->base.crtc; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_atomic_state *intel_state = to_intel_atomic_state(state); + struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb; + struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb; + struct drm_plane_state *plane_state; + struct drm_plane *plane; + enum pipe pipe = intel_crtc->pipe; + int id; + + WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc)); + + drm_for_each_plane_mask(plane, dev, crtc->state->plane_mask) { + id = skl_wm_plane_id(to_intel_plane(plane)); + + if (cur_ddb->plane[pipe][id].start == + new_ddb->plane[pipe][id].start && + cur_ddb->plane[pipe][id].end == + new_ddb->plane[pipe][id].end && + cur_ddb->y_plane[pipe][id].start == + new_ddb->y_plane[pipe][id].start && + cur_ddb->y_plane[pipe][id].end == + new_ddb->y_plane[pipe][id].end) + continue; + + plane_state = drm_atomic_get_plane_state(state, plane); + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + } + + return 0; +} + static int skl_compute_ddb(struct drm_atomic_state *state) { @@ -4030,7 +4069,7 @@ skl_compute_ddb(struct drm_atomic_state *state) if (ret) return ret; - ret = drm_atomic_add_affected_planes(state, &intel_crtc->base); + ret = skl_ddb_add_affected_planes(cstate); if (ret) return ret; } -- 2.7.4