aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-04-17 14:35:53 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-04-18 05:25:34 -0400
commit83d4092b0381e5dd6f312b2ec57121dcf0fcbade (patch)
tree750dcce461a9396b332999ed65682c13b682087b /drivers/gpu/drm
parenta1e969e0332de7a430e62822cee8f2ec8d83cd7c (diff)
drm/i915: Unpin the flip target if we fail to queue the flip
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 96fc4679d438..16930c5cc249 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7658,14 +7658,14 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
7658 7658
7659 ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); 7659 ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
7660 if (ret) 7660 if (ret)
7661 goto out; 7661 goto err;
7662 7662
7663 /* Offset into the new buffer for cases of shared fbs between CRTCs */ 7663 /* Offset into the new buffer for cases of shared fbs between CRTCs */
7664 offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; 7664 offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8;
7665 7665
7666 ret = BEGIN_LP_RING(6); 7666 ret = BEGIN_LP_RING(6);
7667 if (ret) 7667 if (ret)
7668 goto out; 7668 goto err_unpin;
7669 7669
7670 /* Can't queue multiple flips, so wait for the previous 7670 /* Can't queue multiple flips, so wait for the previous
7671 * one to finish before executing the next. 7671 * one to finish before executing the next.
@@ -7682,7 +7682,11 @@ static int intel_gen2_queue_flip(struct drm_device *dev,
7682 OUT_RING(obj->gtt_offset + offset); 7682 OUT_RING(obj->gtt_offset + offset);
7683 OUT_RING(0); /* aux display base address, unused */ 7683 OUT_RING(0); /* aux display base address, unused */
7684 ADVANCE_LP_RING(); 7684 ADVANCE_LP_RING();
7685out: 7685 return 0;
7686
7687err_unpin:
7688 intel_unpin_fb_obj(obj);
7689err:
7686 return ret; 7690 return ret;
7687} 7691}
7688 7692
@@ -7699,14 +7703,14 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
7699 7703
7700 ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); 7704 ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
7701 if (ret) 7705 if (ret)
7702 goto out; 7706 goto err;
7703 7707
7704 /* Offset into the new buffer for cases of shared fbs between CRTCs */ 7708 /* Offset into the new buffer for cases of shared fbs between CRTCs */
7705 offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8; 7709 offset = crtc->y * fb->pitches[0] + crtc->x * fb->bits_per_pixel/8;
7706 7710
7707 ret = BEGIN_LP_RING(6); 7711 ret = BEGIN_LP_RING(6);
7708 if (ret) 7712 if (ret)
7709 goto out; 7713 goto err_unpin;
7710 7714
7711 if (intel_crtc->plane) 7715 if (intel_crtc->plane)
7712 flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; 7716 flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
@@ -7721,7 +7725,11 @@ static int intel_gen3_queue_flip(struct drm_device *dev,
7721 OUT_RING(MI_NOOP); 7725 OUT_RING(MI_NOOP);
7722 7726
7723 ADVANCE_LP_RING(); 7727 ADVANCE_LP_RING();
7724out: 7728 return 0;
7729
7730err_unpin:
7731 intel_unpin_fb_obj(obj);
7732err:
7725 return ret; 7733 return ret;
7726} 7734}
7727 7735
@@ -7737,11 +7745,11 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
7737 7745
7738 ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); 7746 ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
7739 if (ret) 7747 if (ret)
7740 goto out; 7748 goto err;
7741 7749
7742 ret = BEGIN_LP_RING(4); 7750 ret = BEGIN_LP_RING(4);
7743 if (ret) 7751 if (ret)
7744 goto out; 7752 goto err_unpin;
7745 7753
7746 /* i965+ uses the linear or tiled offsets from the 7754 /* i965+ uses the linear or tiled offsets from the
7747 * Display Registers (which do not change across a page-flip) 7755 * Display Registers (which do not change across a page-flip)
@@ -7760,7 +7768,11 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
7760 pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; 7768 pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
7761 OUT_RING(pf | pipesrc); 7769 OUT_RING(pf | pipesrc);
7762 ADVANCE_LP_RING(); 7770 ADVANCE_LP_RING();
7763out: 7771 return 0;
7772
7773err_unpin:
7774 intel_unpin_fb_obj(obj);
7775err:
7764 return ret; 7776 return ret;
7765} 7777}
7766 7778
@@ -7776,11 +7788,11 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
7776 7788
7777 ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); 7789 ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
7778 if (ret) 7790 if (ret)
7779 goto out; 7791 goto err;
7780 7792
7781 ret = BEGIN_LP_RING(4); 7793 ret = BEGIN_LP_RING(4);
7782 if (ret) 7794 if (ret)
7783 goto out; 7795 goto err_unpin;
7784 7796
7785 OUT_RING(MI_DISPLAY_FLIP | 7797 OUT_RING(MI_DISPLAY_FLIP |
7786 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); 7798 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
@@ -7791,7 +7803,11 @@ static int intel_gen6_queue_flip(struct drm_device *dev,
7791 pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; 7803 pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
7792 OUT_RING(pf | pipesrc); 7804 OUT_RING(pf | pipesrc);
7793 ADVANCE_LP_RING(); 7805 ADVANCE_LP_RING();
7794out: 7806 return 0;
7807
7808err_unpin:
7809 intel_unpin_fb_obj(obj);
7810err:
7795 return ret; 7811 return ret;
7796} 7812}
7797 7813
@@ -7813,18 +7829,22 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
7813 7829
7814 ret = intel_pin_and_fence_fb_obj(dev, obj, ring); 7830 ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
7815 if (ret) 7831 if (ret)
7816 goto out; 7832 goto err;
7817 7833
7818 ret = intel_ring_begin(ring, 4); 7834 ret = intel_ring_begin(ring, 4);
7819 if (ret) 7835 if (ret)
7820 goto out; 7836 goto err_unpin;
7821 7837
7822 intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19)); 7838 intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19));
7823 intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); 7839 intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
7824 intel_ring_emit(ring, (obj->gtt_offset)); 7840 intel_ring_emit(ring, (obj->gtt_offset));
7825 intel_ring_emit(ring, (MI_NOOP)); 7841 intel_ring_emit(ring, (MI_NOOP));
7826 intel_ring_advance(ring); 7842 intel_ring_advance(ring);
7827out: 7843 return 0;
7844
7845err_unpin:
7846 intel_unpin_fb_obj(obj);
7847err:
7828 return ret; 7848 return ret;
7829} 7849}
7830 7850