Commit 0d9bdd88 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Convert intel_overlay to request tracking

intel_overlay already tracks its last flip request, along with action to
take after its completion. Refactor intel_overlay to reuse the common
i915_gem_active tracker.

v2: Now using i915_gem_retire_fn typedef

References: https://bugs.freedesktop.org/show_bug.cgi?id=93730
References: https://bugs.freedesktop.org/show_bug.cgi?id=96851Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470293567-10811-18-git-send-email-chris@chris-wilson.co.uk
parent 675d9ad7
...@@ -183,8 +183,7 @@ struct intel_overlay { ...@@ -183,8 +183,7 @@ struct intel_overlay {
u32 flip_addr; u32 flip_addr;
struct drm_i915_gem_object *reg_bo; struct drm_i915_gem_object *reg_bo;
/* flip handling */ /* flip handling */
struct drm_i915_gem_request *last_flip_req; struct i915_gem_active last_flip;
void (*flip_tail)(struct intel_overlay *);
}; };
static struct overlay_registers __iomem * static struct overlay_registers __iomem *
...@@ -210,23 +209,24 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay, ...@@ -210,23 +209,24 @@ static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
io_mapping_unmap(regs); io_mapping_unmap(regs);
} }
static int intel_overlay_do_wait_request(struct intel_overlay *overlay, static void intel_overlay_submit_request(struct intel_overlay *overlay,
struct drm_i915_gem_request *req, struct drm_i915_gem_request *req,
void (*tail)(struct intel_overlay *)) i915_gem_retire_fn retire)
{ {
int ret; GEM_BUG_ON(i915_gem_active_peek(&overlay->last_flip,
&overlay->i915->drm.struct_mutex));
WARN_ON(overlay->last_flip_req); overlay->last_flip.retire = retire;
i915_gem_request_assign(&overlay->last_flip_req, req); i915_gem_active_set(&overlay->last_flip, req);
i915_add_request(req); i915_add_request(req);
}
overlay->flip_tail = tail; static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
ret = i915_wait_request(overlay->last_flip_req); struct drm_i915_gem_request *req,
if (ret) i915_gem_retire_fn retire)
return ret; {
intel_overlay_submit_request(overlay, req, retire);
i915_gem_request_assign(&overlay->last_flip_req, NULL); return i915_gem_active_retire(&overlay->last_flip,
return 0; &overlay->i915->drm.struct_mutex);
} }
static struct drm_i915_gem_request *alloc_request(struct intel_overlay *overlay) static struct drm_i915_gem_request *alloc_request(struct intel_overlay *overlay)
...@@ -306,25 +306,32 @@ static int intel_overlay_continue(struct intel_overlay *overlay, ...@@ -306,25 +306,32 @@ 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);
WARN_ON(overlay->last_flip_req); intel_overlay_submit_request(overlay, req, NULL);
i915_gem_request_assign(&overlay->last_flip_req, req);
i915_add_request(req);
return 0; return 0;
} }
static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) 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);
struct drm_i915_gem_object *obj = overlay->old_vid_bo; struct drm_i915_gem_object *obj = overlay->old_vid_bo;
i915_gem_track_fb(obj, NULL,
INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
i915_gem_object_ggtt_unpin(obj); i915_gem_object_ggtt_unpin(obj);
i915_gem_object_put(obj); i915_gem_object_put(obj);
overlay->old_vid_bo = NULL; overlay->old_vid_bo = NULL;
} }
static void intel_overlay_off_tail(struct intel_overlay *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 drm_i915_gem_object *obj = overlay->vid_bo; struct drm_i915_gem_object *obj = overlay->vid_bo;
/* never have the overlay hw on without showing a frame */ /* never have the overlay hw on without showing a frame */
...@@ -387,27 +394,16 @@ static int intel_overlay_off(struct intel_overlay *overlay) ...@@ -387,27 +394,16 @@ static int intel_overlay_off(struct intel_overlay *overlay)
} }
intel_ring_advance(ring); intel_ring_advance(ring);
return intel_overlay_do_wait_request(overlay, req, intel_overlay_off_tail); return intel_overlay_do_wait_request(overlay, req,
intel_overlay_off_tail);
} }
/* recover from an interruption due to a signal /* recover from an interruption due to a signal
* We have to be careful not to repeat work forever an make forward progess. */ * We have to be careful not to repeat work forever an make forward progess. */
static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay)
{ {
int ret; return i915_gem_active_retire(&overlay->last_flip,
&overlay->i915->drm.struct_mutex);
if (overlay->last_flip_req == NULL)
return 0;
ret = i915_wait_request(overlay->last_flip_req);
if (ret)
return ret;
if (overlay->flip_tail)
overlay->flip_tail(overlay);
i915_gem_request_assign(&overlay->last_flip_req, NULL);
return 0;
} }
/* Wait for pending overlay flip and release old frame. /* Wait for pending overlay flip and release old frame.
...@@ -452,13 +448,9 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) ...@@ -452,13 +448,9 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
intel_overlay_release_old_vid_tail); intel_overlay_release_old_vid_tail);
if (ret) if (ret)
return ret; return ret;
} } else
intel_overlay_release_old_vid_tail(&overlay->last_flip, NULL);
intel_overlay_release_old_vid_tail(overlay);
i915_gem_track_fb(overlay->old_vid_bo, NULL,
INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
return 0; return 0;
} }
...@@ -471,7 +463,6 @@ void intel_overlay_reset(struct drm_i915_private *dev_priv) ...@@ -471,7 +463,6 @@ void intel_overlay_reset(struct drm_i915_private *dev_priv)
intel_overlay_release_old_vid(overlay); intel_overlay_release_old_vid(overlay);
overlay->last_flip_req = NULL;
overlay->old_xscale = 0; overlay->old_xscale = 0;
overlay->old_yscale = 0; overlay->old_yscale = 0;
overlay->crtc = NULL; overlay->crtc = NULL;
...@@ -882,12 +873,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay) ...@@ -882,12 +873,7 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
iowrite32(0, &regs->OCMD); iowrite32(0, &regs->OCMD);
intel_overlay_unmap_regs(overlay, regs); intel_overlay_unmap_regs(overlay, regs);
ret = intel_overlay_off(overlay); return intel_overlay_off(overlay);
if (ret != 0)
return ret;
intel_overlay_off_tail(overlay);
return 0;
} }
static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment