aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c101
1 files changed, 49 insertions, 52 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 4200c32407ec..d9e2208cfe98 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1880,6 +1880,10 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
1880 u32 seqno = intel_ring_get_seqno(ring); 1880 u32 seqno = intel_ring_get_seqno(ring);
1881 1881
1882 BUG_ON(ring == NULL); 1882 BUG_ON(ring == NULL);
1883 if (obj->ring != ring && obj->last_write_seqno) {
1884 /* Keep the seqno relative to the current ring */
1885 obj->last_write_seqno = seqno;
1886 }
1883 obj->ring = ring; 1887 obj->ring = ring;
1884 1888
1885 /* Add a reference if we're newly entering the active list. */ 1889 /* Add a reference if we're newly entering the active list. */
@@ -2254,7 +2258,17 @@ void i915_gem_restore_fences(struct drm_device *dev)
2254 2258
2255 for (i = 0; i < dev_priv->num_fence_regs; i++) { 2259 for (i = 0; i < dev_priv->num_fence_regs; i++) {
2256 struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; 2260 struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i];
2257 i915_gem_write_fence(dev, i, reg->obj); 2261
2262 /*
2263 * Commit delayed tiling changes if we have an object still
2264 * attached to the fence, otherwise just clear the fence.
2265 */
2266 if (reg->obj) {
2267 i915_gem_object_update_fence(reg->obj, reg,
2268 reg->obj->tiling_mode);
2269 } else {
2270 i915_gem_write_fence(dev, i, NULL);
2271 }
2258 } 2272 }
2259} 2273}
2260 2274
@@ -2653,7 +2667,6 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
2653 drm_i915_private_t *dev_priv = dev->dev_private; 2667 drm_i915_private_t *dev_priv = dev->dev_private;
2654 int fence_reg; 2668 int fence_reg;
2655 int fence_pitch_shift; 2669 int fence_pitch_shift;
2656 uint64_t val;
2657 2670
2658 if (INTEL_INFO(dev)->gen >= 6) { 2671 if (INTEL_INFO(dev)->gen >= 6) {
2659 fence_reg = FENCE_REG_SANDYBRIDGE_0; 2672 fence_reg = FENCE_REG_SANDYBRIDGE_0;
@@ -2663,8 +2676,23 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
2663 fence_pitch_shift = I965_FENCE_PITCH_SHIFT; 2676 fence_pitch_shift = I965_FENCE_PITCH_SHIFT;
2664 } 2677 }
2665 2678
2679 fence_reg += reg * 8;
2680
2681 /* To w/a incoherency with non-atomic 64-bit register updates,
2682 * we split the 64-bit update into two 32-bit writes. In order
2683 * for a partial fence not to be evaluated between writes, we
2684 * precede the update with write to turn off the fence register,
2685 * and only enable the fence as the last step.
2686 *
2687 * For extra levels of paranoia, we make sure each step lands
2688 * before applying the next step.
2689 */
2690 I915_WRITE(fence_reg, 0);
2691 POSTING_READ(fence_reg);
2692
2666 if (obj) { 2693 if (obj) {
2667 u32 size = obj->gtt_space->size; 2694 u32 size = obj->gtt_space->size;
2695 uint64_t val;
2668 2696
2669 val = (uint64_t)((obj->gtt_offset + size - 4096) & 2697 val = (uint64_t)((obj->gtt_offset + size - 4096) &
2670 0xfffff000) << 32; 2698 0xfffff000) << 32;
@@ -2673,12 +2701,16 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
2673 if (obj->tiling_mode == I915_TILING_Y) 2701 if (obj->tiling_mode == I915_TILING_Y)
2674 val |= 1 << I965_FENCE_TILING_Y_SHIFT; 2702 val |= 1 << I965_FENCE_TILING_Y_SHIFT;
2675 val |= I965_FENCE_REG_VALID; 2703 val |= I965_FENCE_REG_VALID;
2676 } else
2677 val = 0;
2678 2704
2679 fence_reg += reg * 8; 2705 I915_WRITE(fence_reg + 4, val >> 32);
2680 I915_WRITE64(fence_reg, val); 2706 POSTING_READ(fence_reg + 4);
2681 POSTING_READ(fence_reg); 2707
2708 I915_WRITE(fence_reg + 0, val);
2709 POSTING_READ(fence_reg);
2710 } else {
2711 I915_WRITE(fence_reg + 4, 0);
2712 POSTING_READ(fence_reg + 4);
2713 }
2682} 2714}
2683 2715
2684static void i915_write_fence_reg(struct drm_device *dev, int reg, 2716static void i915_write_fence_reg(struct drm_device *dev, int reg,
@@ -2773,6 +2805,10 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg,
2773 if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj)) 2805 if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj))
2774 mb(); 2806 mb();
2775 2807
2808 WARN(obj && (!obj->stride || !obj->tiling_mode),
2809 "bogus fence setup with stride: 0x%x, tiling mode: %i\n",
2810 obj->stride, obj->tiling_mode);
2811
2776 switch (INTEL_INFO(dev)->gen) { 2812 switch (INTEL_INFO(dev)->gen) {
2777 case 7: 2813 case 7:
2778 case 6: 2814 case 6:
@@ -2796,56 +2832,17 @@ static inline int fence_number(struct drm_i915_private *dev_priv,
2796 return fence - dev_priv->fence_regs; 2832 return fence - dev_priv->fence_regs;
2797} 2833}
2798 2834
2799struct write_fence {
2800 struct drm_device *dev;
2801 struct drm_i915_gem_object *obj;
2802 int fence;
2803};
2804
2805static void i915_gem_write_fence__ipi(void *data)
2806{
2807 struct write_fence *args = data;
2808
2809 /* Required for SNB+ with LLC */
2810 wbinvd();
2811
2812 /* Required for VLV */
2813 i915_gem_write_fence(args->dev, args->fence, args->obj);
2814}
2815
2816static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, 2835static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
2817 struct drm_i915_fence_reg *fence, 2836 struct drm_i915_fence_reg *fence,
2818 bool enable) 2837 bool enable)
2819{ 2838{
2820 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 2839 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
2821 struct write_fence args = { 2840 int reg = fence_number(dev_priv, fence);
2822 .dev = obj->base.dev, 2841
2823 .fence = fence_number(dev_priv, fence), 2842 i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
2824 .obj = enable ? obj : NULL,
2825 };
2826
2827 /* In order to fully serialize access to the fenced region and
2828 * the update to the fence register we need to take extreme
2829 * measures on SNB+. In theory, the write to the fence register
2830 * flushes all memory transactions before, and coupled with the
2831 * mb() placed around the register write we serialise all memory
2832 * operations with respect to the changes in the tiler. Yet, on
2833 * SNB+ we need to take a step further and emit an explicit wbinvd()
2834 * on each processor in order to manually flush all memory
2835 * transactions before updating the fence register.
2836 *
2837 * However, Valleyview complicates matter. There the wbinvd is
2838 * insufficient and unlike SNB/IVB requires the serialising
2839 * register write. (Note that that register write by itself is
2840 * conversely not sufficient for SNB+.) To compromise, we do both.
2841 */
2842 if (INTEL_INFO(args.dev)->gen >= 6)
2843 on_each_cpu(i915_gem_write_fence__ipi, &args, 1);
2844 else
2845 i915_gem_write_fence(args.dev, args.fence, args.obj);
2846 2843
2847 if (enable) { 2844 if (enable) {
2848 obj->fence_reg = args.fence; 2845 obj->fence_reg = reg;
2849 fence->obj = obj; 2846 fence->obj = obj;
2850 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); 2847 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
2851 } else { 2848 } else {
@@ -2853,6 +2850,7 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
2853 fence->obj = NULL; 2850 fence->obj = NULL;
2854 list_del_init(&fence->lru_list); 2851 list_del_init(&fence->lru_list);
2855 } 2852 }
2853 obj->fence_dirty = false;
2856} 2854}
2857 2855
2858static int 2856static int
@@ -2982,7 +2980,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
2982 return 0; 2980 return 0;
2983 2981
2984 i915_gem_object_update_fence(obj, reg, enable); 2982 i915_gem_object_update_fence(obj, reg, enable);
2985 obj->fence_dirty = false;
2986 2983
2987 return 0; 2984 return 0;
2988} 2985}
@@ -4611,7 +4608,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
4611 list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list) 4608 list_for_each_entry(obj, &dev_priv->mm.unbound_list, global_list)
4612 if (obj->pages_pin_count == 0) 4609 if (obj->pages_pin_count == 0)
4613 cnt += obj->base.size >> PAGE_SHIFT; 4610 cnt += obj->base.size >> PAGE_SHIFT;
4614 list_for_each_entry(obj, &dev_priv->mm.inactive_list, global_list) 4611 list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list)
4615 if (obj->pin_count == 0 && obj->pages_pin_count == 0) 4612 if (obj->pin_count == 0 && obj->pages_pin_count == 0)
4616 cnt += obj->base.size >> PAGE_SHIFT; 4613 cnt += obj->base.size >> PAGE_SHIFT;
4617 4614