summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-12-07 19:28:06 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-08 10:26:02 +0200
commit48167acb7f5b936b009eb824dfb3cfb7e1a42502 (patch)
tree30ed8870e228145d4d053a591eeca0732b7ce77c /drivers/gpu
parent97766c6a8e586308d89309591f73aa3bc5ce0643 (diff)
downloadlinux-stable-48167acb7f5b936b009eb824dfb3cfb7e1a42502.tar.gz
linux-stable-48167acb7f5b936b009eb824dfb3cfb7e1a42502.tar.bz2
linux-stable-48167acb7f5b936b009eb824dfb3cfb7e1a42502.zip
drm/i915: Fix the overlay frontbuffer tracking
[ Upstream commit 58d09ebdb4edf5d3ab3a2aee851ab0168bc83ec6 ] Do the overlay frontbuffer tracking properly so that it matches the state of the overlay on/off/continue requests. One slight problem is that intel_frontbuffer_flip_complete() may get delayed by an arbitrarily liong time due to the fact that the overlay code likes to bail out when a signal occurs. So the flip may not get completed until the ioctl is restarted. But fixing that would require bigger surgery, so I decided to ignore it for now. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1481131693-27993-5-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index a2655cd5a84e..8ab6f30dc23c 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -272,8 +272,30 @@ static int intel_overlay_on(struct intel_overlay *overlay)
return intel_overlay_do_wait_request(overlay, req, NULL);
}
+static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
+ struct i915_vma *vma)
+{
+ enum pipe pipe = overlay->crtc->pipe;
+
+ WARN_ON(overlay->old_vma);
+
+ i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL,
+ vma ? vma->obj : NULL,
+ INTEL_FRONTBUFFER_OVERLAY(pipe));
+
+ intel_frontbuffer_flip_prepare(overlay->i915,
+ INTEL_FRONTBUFFER_OVERLAY(pipe));
+
+ overlay->old_vma = overlay->vma;
+ if (vma)
+ overlay->vma = i915_vma_get(vma);
+ else
+ overlay->vma = NULL;
+}
+
/* overlay needs to be enabled in OCMD reg */
static int intel_overlay_continue(struct intel_overlay *overlay,
+ struct i915_vma *vma,
bool load_polyphase_filter)
{
struct drm_i915_private *dev_priv = overlay->i915;
@@ -308,43 +330,44 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
intel_ring_emit(ring, flip_addr);
intel_ring_advance(ring);
+ intel_overlay_flip_prepare(overlay, vma);
+
intel_overlay_submit_request(overlay, req, NULL);
return 0;
}
-static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
- struct drm_i915_gem_request *req)
+static void intel_overlay_release_old_vma(struct intel_overlay *overlay)
{
- struct intel_overlay *overlay =
- container_of(active, typeof(*overlay), last_flip);
struct i915_vma *vma;
vma = fetch_and_zero(&overlay->old_vma);
if (WARN_ON(!vma))
return;
- i915_gem_track_fb(vma->obj, NULL,
- INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
+ intel_frontbuffer_flip_complete(overlay->i915,
+ INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
i915_gem_object_unpin_from_display_plane(vma);
i915_vma_put(vma);
}
+static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
+ struct drm_i915_gem_request *req)
+{
+ struct intel_overlay *overlay =
+ container_of(active, typeof(*overlay), last_flip);
+
+ intel_overlay_release_old_vma(overlay);
+}
+
static void intel_overlay_off_tail(struct i915_gem_active *active,
struct drm_i915_gem_request *req)
{
struct intel_overlay *overlay =
container_of(active, typeof(*overlay), last_flip);
- struct i915_vma *vma;
-
- /* never have the overlay hw on without showing a frame */
- vma = fetch_and_zero(&overlay->vma);
- if (WARN_ON(!vma))
- return;
- i915_gem_object_unpin_from_display_plane(vma);
- i915_vma_put(vma);
+ intel_overlay_release_old_vma(overlay);
overlay->crtc->overlay = NULL;
overlay->crtc = NULL;
@@ -398,6 +421,8 @@ static int intel_overlay_off(struct intel_overlay *overlay)
}
intel_ring_advance(ring);
+ intel_overlay_flip_prepare(overlay, NULL);
+
return intel_overlay_do_wait_request(overlay, req,
intel_overlay_off_tail);
}
@@ -836,18 +861,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
intel_overlay_unmap_regs(overlay, regs);
- ret = intel_overlay_continue(overlay, scale_changed);
+ ret = intel_overlay_continue(overlay, vma, scale_changed);
if (ret)
goto out_unpin;
- i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL,
- vma->obj, INTEL_FRONTBUFFER_OVERLAY(pipe));
-
- overlay->old_vma = overlay->vma;
- overlay->vma = vma;
-
- intel_frontbuffer_flip(dev_priv, INTEL_FRONTBUFFER_OVERLAY(pipe));
-
return 0;
out_unpin:
@@ -1215,6 +1232,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
mutex_unlock(&dev->struct_mutex);
drm_modeset_unlock_all(dev);
+ i915_gem_object_put(new_bo);
kfree(params);