mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-14 17:46:54 +07:00
drm/i915: Fix the overlay frontbuffer tracking
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>
This commit is contained in:
parent
4a15cdbbc5
commit
58d09ebdb4
@ -272,8 +272,30 @@ static int intel_overlay_on(struct intel_overlay *overlay)
|
|||||||
return intel_overlay_do_wait_request(overlay, req, NULL);
|
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 */
|
/* overlay needs to be enabled in OCMD reg */
|
||||||
static int intel_overlay_continue(struct intel_overlay *overlay,
|
static int intel_overlay_continue(struct intel_overlay *overlay,
|
||||||
|
struct i915_vma *vma,
|
||||||
bool load_polyphase_filter)
|
bool load_polyphase_filter)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = overlay->i915;
|
struct drm_i915_private *dev_priv = overlay->i915;
|
||||||
@ -308,27 +330,35 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
|
|||||||
intel_ring_emit(ring, flip_addr);
|
intel_ring_emit(ring, flip_addr);
|
||||||
intel_ring_advance(ring);
|
intel_ring_advance(ring);
|
||||||
|
|
||||||
|
intel_overlay_flip_prepare(overlay, vma);
|
||||||
|
|
||||||
intel_overlay_submit_request(overlay, req, NULL);
|
intel_overlay_submit_request(overlay, req, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void intel_overlay_release_old_vma(struct intel_overlay *overlay)
|
||||||
|
{
|
||||||
|
struct i915_vma *vma;
|
||||||
|
|
||||||
|
vma = fetch_and_zero(&overlay->old_vma);
|
||||||
|
if (WARN_ON(!vma))
|
||||||
|
return;
|
||||||
|
|
||||||
|
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,
|
static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
|
||||||
struct drm_i915_gem_request *req)
|
struct drm_i915_gem_request *req)
|
||||||
{
|
{
|
||||||
struct intel_overlay *overlay =
|
struct intel_overlay *overlay =
|
||||||
container_of(active, typeof(*overlay), last_flip);
|
container_of(active, typeof(*overlay), last_flip);
|
||||||
struct i915_vma *vma;
|
|
||||||
|
|
||||||
vma = fetch_and_zero(&overlay->old_vma);
|
intel_overlay_release_old_vma(overlay);
|
||||||
if (WARN_ON(!vma))
|
|
||||||
return;
|
|
||||||
|
|
||||||
i915_gem_track_fb(vma->obj, NULL,
|
|
||||||
INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
|
|
||||||
|
|
||||||
i915_gem_object_unpin_from_display_plane(vma);
|
|
||||||
i915_vma_put(vma);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_overlay_off_tail(struct i915_gem_active *active,
|
static void intel_overlay_off_tail(struct i915_gem_active *active,
|
||||||
@ -336,15 +366,8 @@ static void intel_overlay_off_tail(struct i915_gem_active *active,
|
|||||||
{
|
{
|
||||||
struct intel_overlay *overlay =
|
struct intel_overlay *overlay =
|
||||||
container_of(active, typeof(*overlay), last_flip);
|
container_of(active, typeof(*overlay), last_flip);
|
||||||
struct i915_vma *vma;
|
|
||||||
|
|
||||||
/* never have the overlay hw on without showing a frame */
|
intel_overlay_release_old_vma(overlay);
|
||||||
vma = fetch_and_zero(&overlay->vma);
|
|
||||||
if (WARN_ON(!vma))
|
|
||||||
return;
|
|
||||||
|
|
||||||
i915_gem_object_unpin_from_display_plane(vma);
|
|
||||||
i915_vma_put(vma);
|
|
||||||
|
|
||||||
overlay->crtc->overlay = NULL;
|
overlay->crtc->overlay = NULL;
|
||||||
overlay->crtc = NULL;
|
overlay->crtc = NULL;
|
||||||
@ -398,6 +421,8 @@ static int intel_overlay_off(struct intel_overlay *overlay)
|
|||||||
}
|
}
|
||||||
intel_ring_advance(ring);
|
intel_ring_advance(ring);
|
||||||
|
|
||||||
|
intel_overlay_flip_prepare(overlay, NULL);
|
||||||
|
|
||||||
return intel_overlay_do_wait_request(overlay, req,
|
return intel_overlay_do_wait_request(overlay, req,
|
||||||
intel_overlay_off_tail);
|
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);
|
intel_overlay_unmap_regs(overlay, regs);
|
||||||
|
|
||||||
ret = intel_overlay_continue(overlay, scale_changed);
|
ret = intel_overlay_continue(overlay, vma, scale_changed);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unpin;
|
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;
|
return 0;
|
||||||
|
|
||||||
out_unpin:
|
out_unpin:
|
||||||
@ -1215,6 +1232,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
|
|||||||
|
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
drm_modeset_unlock_all(dev);
|
drm_modeset_unlock_all(dev);
|
||||||
|
i915_gem_object_put(new_bo);
|
||||||
|
|
||||||
kfree(params);
|
kfree(params);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user