From: Stéphane Marchesin <marcheu@xxxxxxxxxxxx> During suspend/resume all fences are reset, including their pin count which is reset to 0. However a framebuffer can be bound across suspend/resume, which means that after the buffer is unbound on resume, the pin count for the buffer will be negative. Since the fence pin count is now negative when available and zero when in use, the buffer's fence will get recycled when the fence is in use which is the opposite of what we want. The adverse effect is that since the fence is recycled the tiling mode goes away while the buffer is being displayed and we get lines/screens of garbage. To fix this, we reallocate and repin the fences for all bound fbs on resume, which ensures the pin count is right. v2: Only repin the fence pin count, not the gem buffer pin count BUG=chromium:219172,chromium:225056 TEST=by hand, suspend/resume on alex, the artifacts are gone Change-Id: I5f623a583fe475561cc6643bdf52e7744740b4f1 Signed-off-by: Stéphane Marchesin <marcheu@xxxxxxxxxxxx> Reviewed-on: https://gerrit.chromium.org/gerrit/47933 Reviewed-on: https://gerrit.chromium.org/gerrit/57379 Reviewed-by: Sean Paul <seanpaul@xxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index cc97082..873a66c1 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -452,6 +452,32 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return 1; } +/* Repin all fbs which are currently bound to a crtc on resume */ +static void i915_repin_bound_fbs(struct drm_device *dev) +{ + struct drm_crtc *crtc; + struct drm_i915_gem_object *obj; + int ret; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (!crtc || !crtc->fb) + continue; + obj = to_intel_framebuffer(crtc->fb)->obj; + if (!obj) + continue; + + /* Install a fence for tiled scan-out. */ + if (obj->tiling_mode != I915_TILING_NONE) { + ret = i915_gem_object_get_fence(obj); + if (ret) + DRM_ERROR("Couldn't get a fence\n"); + else + i915_gem_object_pin_fence(obj); + } + + } +} + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -550,6 +576,7 @@ static int __i915_drm_thaw(struct drm_device *dev) error = i915_gem_init_hw(dev); mutex_unlock(&dev->struct_mutex); + i915_repin_bound_fbs(dev); intel_modeset_init_hw(dev); intel_modeset_setup_hw_state(dev, true); -- 1.8.3.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx