drm/i915: Call intel_fbc_pre_update() after pinning the new pageflip

intel_fbc_pre_update() depends upon the new state being already pinned
in place in the Global GTT (primarily for both fencing which wants both
an offset and a fence register, if assigned). This requires the call to
intel_fbc_pre_update() be after intel_pin_and_fence_fb() - but commit
e8216e502a ("drm/i915/fbc: call intel_fbc_pre_update earlier during
page flips") moved the code way too much up in its attempt to call it
before the page flip.

v2 (from Paulo):
 - Point the original bad commit.
 - Add a comment to maybe prevent further regressions.

Fixes: e8216e502a ("drm/i915/fbc: call intel_fbc_pre_update earlier...")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Patrik Jakobsson <patrik.jakobsson@linux.intel.com>
Cc: drm-intel-fixes@lists.freedesktop.org
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1471462904-842-1-git-send-email-paulo.r.zanoni@intel.com
Cc: stable@vger.kernel.org
This commit is contained in:
Paulo Zanoni 2016-08-17 16:41:44 -03:00 committed by Chris Wilson
parent c75870d86f
commit 1f061316cf

View File

@ -12094,9 +12094,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
crtc->primary->fb = fb;
update_state_fb(crtc->primary);
intel_fbc_pre_update(intel_crtc, intel_crtc->config,
to_intel_plane_state(primary->state));
work->pending_flip_obj = i915_gem_object_get(obj);
ret = i915_mutex_lock_interruptible(dev);
@ -12142,6 +12139,17 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
work->gtt_offset += intel_crtc->dspaddr_offset;
work->rotation = crtc->primary->state->rotation;
/*
* There's the potential that the next frame will not be compatible with
* FBC, so we want to call pre_update() before the actual page flip.
* The problem is that pre_update() caches some information about the fb
* object, so we want to do this only after the object is pinned. Let's
* be on the safe side and do this immediately before scheduling the
* flip.
*/
intel_fbc_pre_update(intel_crtc, intel_crtc->config,
to_intel_plane_state(primary->state));
if (mmio_flip) {
INIT_WORK(&work->mmio_work, intel_mmio_flip_work_func);