aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-09-20 10:41:01 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-21 06:24:17 -0400
commit265db9585e570814d2f7aca109c5563bcde9c948 (patch)
tree5319dd865de1d85c9135b8b9227f32db636b9aca /drivers
parentc78ec30bba52754b9f21a899eac2e2f5a7486116 (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.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c41
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);
1027int i915_gem_wait_for_pending_flip(struct drm_device *dev,
1028 struct drm_gem_object **object_list,
1029 int count);
1027int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 1030int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
1028int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, 1031int 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
3500static int 3500int
3501i915_gem_wait_for_pending_flip(struct drm_device *dev, 3501i915_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 {