drm/i915: Fix ILK-IVB sprite enable delays

Sprite enable on ILK-IVB may take two frames to complete
when the hardware is in big FIFO mode (LP1+). That is
not entirely great as it means the sprite enable may
actually happen one frame after we've already signalled
flip completion. At the very least crc checks may fail
due to the sprite not yet being visible when we expect it.

We already have code to deal with big FIFO mode when it
comes to the sprite scaling on IVB
(WaCxSRDisabledForSpriteScaling:ivb). Let's extend that
workaround to kick in whenever the sprite is in the process
of being enabled. Also ILK/SNB bspec has some notes to
indicate that we should most likely also do the sprite
scaling w/a on all three platforms, so let's do that as well.

Pretty easy to reproduce on SNB/IVB. ILK has proved more
elusive, but let's trust the spec and include it as well.

v2: Make sure the pipe is active before the vblank wait

Cc: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Testcase: igt/kms_plane/pixel-format-pipe-*-planes
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107749
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com> #v1
Link: https://patchwork.freedesktop.org/patch/msgid/20181004121527.30249-1-ville.syrjala@linux.intel.com
This commit is contained in:
Ville Syrjälä 2018-10-04 15:15:27 +03:00
Родитель 6f405638c2
Коммит 8e7a4424b9
1 изменённых файлов: 34 добавлений и 7 удалений

Просмотреть файл

@ -5403,7 +5403,8 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
*
* WaCxSRDisabledForSpriteScaling:ivb
*/
if (pipe_config->disable_lp_wm && ilk_disable_lp_wm(dev))
if (pipe_config->disable_lp_wm && ilk_disable_lp_wm(dev) &&
old_crtc_state->base.active)
intel_wait_for_vblank(dev_priv, crtc->pipe);
/*
@ -10717,14 +10718,40 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
pipe_config->fb_bits |= plane->frontbuffer_bit;
/*
* WaCxSRDisabledForSpriteScaling:ivb
* ILK/SNB DVSACNTR/Sprite Enable
* IVB SPR_CTL/Sprite Enable
* "When in Self Refresh Big FIFO mode, a write to enable the
* plane will be internally buffered and delayed while Big FIFO
* mode is exiting."
*
* cstate->update_wm was already set above, so this flag will
* take effect when we commit and program watermarks.
* Which means that enabling the sprite can take an extra frame
* when we start in big FIFO mode (LP1+). Thus we need to drop
* down to LP0 and wait for vblank in order to make sure the
* sprite gets enabled on the next vblank after the register write.
* Doing otherwise would risk enabling the sprite one frame after
* we've already signalled flip completion. We can resume LP1+
* once the sprite has been enabled.
*
*
* WaCxSRDisabledForSpriteScaling:ivb
* IVB SPR_SCALE/Scaling Enable
* "Low Power watermarks must be disabled for at least one
* frame before enabling sprite scaling, and kept disabled
* until sprite scaling is disabled."
*
* ILK/SNB DVSASCALE/Scaling Enable
* "When in Self Refresh Big FIFO mode, scaling enable will be
* masked off while Big FIFO mode is exiting."
*
* Despite the w/a only being listed for IVB we assume that
* the ILK/SNB note has similar ramifications, hence we apply
* the w/a on all three platforms.
*/
if (plane->id == PLANE_SPRITE0 && IS_IVYBRIDGE(dev_priv) &&
needs_scaling(to_intel_plane_state(plane_state)) &&
!needs_scaling(old_plane_state))
if (plane->id == PLANE_SPRITE0 &&
(IS_GEN5(dev_priv) || IS_GEN6(dev_priv) ||
IS_IVYBRIDGE(dev_priv)) &&
(turn_on || (!needs_scaling(old_plane_state) &&
needs_scaling(to_intel_plane_state(plane_state)))))
pipe_config->disable_lp_wm = true;
return 0;