Commit 5a920b85 authored by Paulo Zanoni's avatar Paulo Zanoni

drm/i915/gen9: fix DDB partitioning for multi-screen cases

With the previous code we were only recomputing the DDB partitioning
for the CRTCs included in the atomic commit, so any other active CRTCs
would end up having their DDB registers zeroed. In this patch we make
sure that the computed state starts as a copy of the current
partitioning, and then we only zero the DDBs that we're actually
going to recompute.

How to reproduce the bug:
  1 - Enable the primary plane on pipe A
  2 - Enable the primary plane on pipe B
  3 - Enable the cursor or sprite plane on pipe A

Step 3 will zero the DDB partitioning for pipe B since it's not
included in the commit that enabled the cursor or sprite for pipe A.

I expect this to fix many FIFO underrun problems on gen9+.

v2:
  - Mention the cursor on the steps to reproduce the problem (Paulo).
  - Add Testcase tag provided by Maarten (Maarten).

Testcase: kms_cursor_legacy.cursorA-vs-flipB-atomic-transitions
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96226
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96828
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97450
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97596
Bugzilla: https://www.phoronix.com/scan.php?page=news_item&px=Intel-Skylake-Multi-Screen-Woes
Cc: stable@vger.kernel.org
Signed-off-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: default avatarLyude <cpaul@redhat.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1475602652-17326-1-git-send-email-paulo.r.zanoni@intel.com
parent 9eeb7304
...@@ -3362,13 +3362,15 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, ...@@ -3362,13 +3362,15 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
int num_active; int num_active;
int id, i; int id, i;
/* Clear the partitioning for disabled planes. */
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
if (WARN_ON(!state)) if (WARN_ON(!state))
return 0; return 0;
if (!cstate->base.active) { if (!cstate->base.active) {
ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0; ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0;
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
return 0; return 0;
} }
...@@ -4054,6 +4056,12 @@ skl_compute_ddb(struct drm_atomic_state *state) ...@@ -4054,6 +4056,12 @@ skl_compute_ddb(struct drm_atomic_state *state)
intel_state->wm_results.dirty_pipes = ~0; intel_state->wm_results.dirty_pipes = ~0;
} }
/*
* We're not recomputing for the pipes not included in the commit, so
* make sure we start with the current state.
*/
memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb));
for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) { for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
struct intel_crtc_state *cstate; struct intel_crtc_state *cstate;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment