Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 345490
b: refs/heads/master
c: b4a98e5
h: refs/heads/master
v: v3
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Nov 21, 2012
1 parent 2bbdc08 commit bdba754
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a726915cef1daab57aad4c5b5e4773822f0a4bf8
refs/heads/master: b4a98e57fc27854b5938fc8b08b68e5e68b91e1f
22 changes: 16 additions & 6 deletions trunk/drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -6896,14 +6896,19 @@ static void intel_unpin_work_fn(struct work_struct *__work)
{
struct intel_unpin_work *work =
container_of(__work, struct intel_unpin_work, work);
struct drm_device *dev = work->crtc->dev;

mutex_lock(&work->dev->struct_mutex);
mutex_lock(&dev->struct_mutex);
intel_unpin_fb_obj(work->old_fb_obj);
drm_gem_object_unreference(&work->pending_flip_obj->base);
drm_gem_object_unreference(&work->old_fb_obj->base);

intel_update_fbc(work->dev);
mutex_unlock(&work->dev->struct_mutex);
intel_update_fbc(dev);
mutex_unlock(&dev->struct_mutex);

BUG_ON(atomic_read(&to_intel_crtc(work->crtc)->unpin_work_count) == 0);
atomic_dec(&to_intel_crtc(work->crtc)->unpin_work_count);

kfree(work);
}

Expand Down Expand Up @@ -6951,9 +6956,9 @@ static void do_intel_finish_page_flip(struct drm_device *dev,

atomic_clear_mask(1 << intel_crtc->plane,
&obj->pending_flip.counter);

wake_up(&dev_priv->pending_flip_queue);
schedule_work(&work->work);

queue_work(dev_priv->wq, &work->work);

trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
}
Expand Down Expand Up @@ -7254,7 +7259,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
return -ENOMEM;

work->event = event;
work->dev = crtc->dev;
work->crtc = crtc;
intel_fb = to_intel_framebuffer(crtc->fb);
work->old_fb_obj = intel_fb->obj;
INIT_WORK(&work->work, intel_unpin_work_fn);
Expand All @@ -7279,6 +7284,9 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
intel_fb = to_intel_framebuffer(fb);
obj = intel_fb->obj;

if (atomic_read(&intel_crtc->unpin_work_count) >= 2)
flush_workqueue(dev_priv->wq);

ret = i915_mutex_lock_interruptible(dev);
if (ret)
goto cleanup;
Expand All @@ -7297,6 +7305,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
* the flip occurs and the object is no longer visible.
*/
atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
atomic_inc(&intel_crtc->unpin_work_count);

ret = dev_priv->display.queue_flip(dev, crtc, fb, obj);
if (ret)
Expand All @@ -7311,6 +7320,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
return 0;

cleanup_pending:
atomic_dec(&intel_crtc->unpin_work_count);
atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
drm_gem_object_unreference(&work->old_fb_obj->base);
drm_gem_object_unreference(&obj->base);
Expand Down
4 changes: 3 additions & 1 deletion trunk/drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ struct intel_crtc {
struct intel_unpin_work *unpin_work;
int fdi_lanes;

atomic_t unpin_work_count;

/* Display surface base address adjustement for pageflips. Note that on
* gen4+ this only adjusts up to a tile, offsets within a tile are
* handled in the hw itself (with the TILEOFF register). */
Expand Down Expand Up @@ -395,7 +397,7 @@ intel_get_crtc_for_plane(struct drm_device *dev, int plane)

struct intel_unpin_work {
struct work_struct work;
struct drm_device *dev;
struct drm_crtc *crtc;
struct drm_i915_gem_object *old_fb_obj;
struct drm_i915_gem_object *pending_flip_obj;
struct drm_pending_vblank_event *event;
Expand Down

0 comments on commit bdba754

Please sign in to comment.