Commit 601a9ee0 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Streamline skl_commit_modeset_enables()

skl_commit_modeset_enables() is a bit of mess. Let's streamline
it by simply tracking which pipes still need to be updated.
As a bonus we get rid of the state->wm_results.dirty_pipes usage.

v2: Rebase due to port sync

Cc: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> #v1
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191210144105.3239-2-ville.syrjala@linux.intel.com
parent 8717c6b7
......@@ -14553,17 +14553,19 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
struct intel_crtc *crtc;
struct intel_crtc_state *old_crtc_state, *new_crtc_state;
unsigned int updated = 0;
bool progress;
int i;
u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
u8 required_slices = state->wm_results.ddb.enabled_slices;
struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
u8 dirty_pipes = 0;
int i;
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i)
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
/* ignore allocations for crtc's that have been turned off. */
if (!needs_modeset(new_crtc_state) && new_crtc_state->hw.active)
entries[i] = old_crtc_state->wm.skl.ddb;
if (new_crtc_state->hw.active)
dirty_pipes |= BIT(crtc->pipe);
}
/* If 2nd DBuf slice required, enable it here */
if (INTEL_GEN(dev_priv) >= 11 && required_slices > hw_enabled_slices)
......@@ -14575,15 +14577,13 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
* never overlap with eachother inbetween CRTC updates. Otherwise we'll
* cause pipe underruns and other bad stuff.
*/
do {
progress = false;
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
while (dirty_pipes) {
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
enum pipe pipe = crtc->pipe;
bool vbl_wait = false;
bool modeset = needs_modeset(new_crtc_state);
if (updated & BIT(crtc->pipe) || !new_crtc_state->hw.active)
if ((dirty_pipes & BIT(pipe)) == 0)
continue;
if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
......@@ -14591,20 +14591,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
INTEL_NUM_PIPES(dev_priv), i))
continue;
updated |= BIT(pipe);
entries[i] = new_crtc_state->wm.skl.ddb;
/*
* If this is an already active pipe, it's DDB changed,
* and this isn't the last pipe that needs updating
* then we need to wait for a vblank to pass for the
* new ddb allocation to take effect.
*/
if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,
&old_crtc_state->wm.skl.ddb) &&
!modeset &&
state->wm_results.dirty_pipes != updated)
vbl_wait = true;
dirty_pipes &= ~BIT(pipe);
if (modeset && is_trans_port_sync_mode(new_crtc_state)) {
if (is_trans_port_sync_master(new_crtc_state))
......@@ -14619,12 +14607,18 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
new_crtc_state);
}
if (vbl_wait)
/*
* If this is an already active pipe, it's DDB changed,
* and this isn't the last pipe that needs updating
* then we need to wait for a vblank to pass for the
* new ddb allocation to take effect.
*/
if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,
&old_crtc_state->wm.skl.ddb) &&
!modeset && dirty_pipes)
intel_wait_for_vblank(dev_priv, pipe);
progress = true;
}
} while (progress);
}
/* If 2nd DBuf slice is no more required disable it */
if (INTEL_GEN(dev_priv) >= 11 && required_slices < hw_enabled_slices)
......
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