diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-04-17 14:35:53 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-04-18 05:25:34 -0400 |
commit | 83d4092b0381e5dd6f312b2ec57121dcf0fcbade (patch) | |
tree | 750dcce461a9396b332999ed65682c13b682087b /drivers/gpu/drm | |
parent | a1e969e0332de7a430e62822cee8f2ec8d83cd7c (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.c | 50 |
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(); |
7685 | out: | 7685 | return 0; |
7686 | |||
7687 | err_unpin: | ||
7688 | intel_unpin_fb_obj(obj); | ||
7689 | err: | ||
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(); |
7724 | out: | 7728 | return 0; |
7729 | |||
7730 | err_unpin: | ||
7731 | intel_unpin_fb_obj(obj); | ||
7732 | err: | ||
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(); |
7763 | out: | 7771 | return 0; |
7772 | |||
7773 | err_unpin: | ||
7774 | intel_unpin_fb_obj(obj); | ||
7775 | err: | ||
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(); |
7794 | out: | 7806 | return 0; |
7807 | |||
7808 | err_unpin: | ||
7809 | intel_unpin_fb_obj(obj); | ||
7810 | err: | ||
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); |
7827 | out: | 7843 | return 0; |
7844 | |||
7845 | err_unpin: | ||
7846 | intel_unpin_fb_obj(obj); | ||
7847 | err: | ||
7828 | return ret; | 7848 | return ret; |
7829 | } | 7849 | } |
7830 | 7850 | ||