diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-20 10:41:01 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-21 06:24:17 -0400 |
commit | 265db9585e570814d2f7aca109c5563bcde9c948 (patch) | |
tree | 5319dd865de1d85c9135b8b9227f32db636b9aca /drivers | |
parent | c78ec30bba52754b9f21a899eac2e2f5a7486116 (diff) |
drm/i915: Drain any pending flips on the fb prior to unpinning
If we have queued a page flip on the current fb and then request a mode
change, wait until the page flip completes before performing the new
request.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 41 |
3 files changed, 26 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 37a44c80efd2..ce8ff8fdc55c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1024,6 +1024,9 @@ int i915_do_wait_request(struct drm_device *dev, | |||
1024 | uint32_t seqno, | 1024 | uint32_t seqno, |
1025 | bool interruptible, | 1025 | bool interruptible, |
1026 | struct intel_ring_buffer *ring); | 1026 | struct intel_ring_buffer *ring); |
1027 | int i915_gem_wait_for_pending_flip(struct drm_device *dev, | ||
1028 | struct drm_gem_object **object_list, | ||
1029 | int count); | ||
1027 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); | 1030 | int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); |
1028 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | 1031 | int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, |
1029 | int write); | 1032 | int write); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 58baecc821a5..a8ddcd499b3b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3497,7 +3497,7 @@ i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer2 *exec, | |||
3497 | return 0; | 3497 | return 0; |
3498 | } | 3498 | } |
3499 | 3499 | ||
3500 | static int | 3500 | int |
3501 | i915_gem_wait_for_pending_flip(struct drm_device *dev, | 3501 | i915_gem_wait_for_pending_flip(struct drm_device *dev, |
3502 | struct drm_gem_object **object_list, | 3502 | struct drm_gem_object **object_list, |
3503 | int count) | 3503 | int count) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 791374c888da..461bf4879e0a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1564,11 +1564,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1564 | struct drm_device *dev = crtc->dev; | 1564 | struct drm_device *dev = crtc->dev; |
1565 | struct drm_i915_master_private *master_priv; | 1565 | struct drm_i915_master_private *master_priv; |
1566 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1566 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1567 | struct intel_framebuffer *intel_fb; | ||
1568 | struct drm_i915_gem_object *obj_priv; | ||
1569 | struct drm_gem_object *obj; | ||
1570 | int pipe = intel_crtc->pipe; | ||
1571 | int plane = intel_crtc->plane; | ||
1572 | int ret; | 1567 | int ret; |
1573 | 1568 | ||
1574 | /* no fb bound */ | 1569 | /* no fb bound */ |
@@ -1577,38 +1572,46 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1577 | return 0; | 1572 | return 0; |
1578 | } | 1573 | } |
1579 | 1574 | ||
1580 | switch (plane) { | 1575 | switch (intel_crtc->plane) { |
1581 | case 0: | 1576 | case 0: |
1582 | case 1: | 1577 | case 1: |
1583 | break; | 1578 | break; |
1584 | default: | 1579 | default: |
1585 | DRM_ERROR("Can't update plane %d in SAREA\n", plane); | ||
1586 | return -EINVAL; | 1580 | return -EINVAL; |
1587 | } | 1581 | } |
1588 | 1582 | ||
1589 | intel_fb = to_intel_framebuffer(crtc->fb); | ||
1590 | obj = intel_fb->obj; | ||
1591 | obj_priv = to_intel_bo(obj); | ||
1592 | |||
1593 | mutex_lock(&dev->struct_mutex); | 1583 | mutex_lock(&dev->struct_mutex); |
1594 | ret = intel_pin_and_fence_fb_obj(dev, obj, false); | 1584 | ret = intel_pin_and_fence_fb_obj(dev, |
1585 | to_intel_framebuffer(crtc->fb)->obj, | ||
1586 | false); | ||
1595 | if (ret != 0) { | 1587 | if (ret != 0) { |
1596 | mutex_unlock(&dev->struct_mutex); | 1588 | mutex_unlock(&dev->struct_mutex); |
1597 | return ret; | 1589 | return ret; |
1598 | } | 1590 | } |
1599 | 1591 | ||
1592 | if (old_fb) { | ||
1593 | struct drm_gem_object *obj = to_intel_framebuffer(old_fb)->obj; | ||
1594 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | ||
1595 | |||
1596 | if (atomic_read(&obj_priv->pending_flip)) { | ||
1597 | ret = i915_gem_wait_for_pending_flip(dev, &obj, 1); | ||
1598 | if (ret) { | ||
1599 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); | ||
1600 | mutex_unlock(&dev->struct_mutex); | ||
1601 | return ret; | ||
1602 | } | ||
1603 | } | ||
1604 | } | ||
1605 | |||
1600 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y); | 1606 | ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y); |
1601 | if (ret) { | 1607 | if (ret) { |
1602 | i915_gem_object_unpin(obj); | 1608 | i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); |
1603 | mutex_unlock(&dev->struct_mutex); | 1609 | mutex_unlock(&dev->struct_mutex); |
1604 | return ret; | 1610 | return ret; |
1605 | } | 1611 | } |
1606 | 1612 | ||
1607 | if (old_fb) { | 1613 | if (old_fb) |
1608 | intel_fb = to_intel_framebuffer(old_fb); | 1614 | i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj); |
1609 | obj_priv = to_intel_bo(intel_fb->obj); | ||
1610 | i915_gem_object_unpin(intel_fb->obj); | ||
1611 | } | ||
1612 | 1615 | ||
1613 | mutex_unlock(&dev->struct_mutex); | 1616 | mutex_unlock(&dev->struct_mutex); |
1614 | 1617 | ||
@@ -1619,7 +1622,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1619 | if (!master_priv->sarea_priv) | 1622 | if (!master_priv->sarea_priv) |
1620 | return 0; | 1623 | return 0; |
1621 | 1624 | ||
1622 | if (pipe) { | 1625 | if (intel_crtc->pipe) { |
1623 | master_priv->sarea_priv->pipeB_x = x; | 1626 | master_priv->sarea_priv->pipeB_x = x; |
1624 | master_priv->sarea_priv->pipeB_y = y; | 1627 | master_priv->sarea_priv->pipeB_y = y; |
1625 | } else { | 1628 | } else { |