aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 8fd8e82ebda4..a34e8e2ba98a 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2668,7 +2668,6 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
2668 drm_i915_private_t *dev_priv = dev->dev_private; 2668 drm_i915_private_t *dev_priv = dev->dev_private;
2669 int fence_reg; 2669 int fence_reg;
2670 int fence_pitch_shift; 2670 int fence_pitch_shift;
2671 uint64_t val;
2672 2671
2673 if (INTEL_INFO(dev)->gen >= 6) { 2672 if (INTEL_INFO(dev)->gen >= 6) {
2674 fence_reg = FENCE_REG_SANDYBRIDGE_0; 2673 fence_reg = FENCE_REG_SANDYBRIDGE_0;
@@ -2678,8 +2677,23 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
2678 fence_pitch_shift = I965_FENCE_PITCH_SHIFT; 2677 fence_pitch_shift = I965_FENCE_PITCH_SHIFT;
2679 } 2678 }
2680 2679
2680 fence_reg += reg * 8;
2681
2682 /* To w/a incoherency with non-atomic 64-bit register updates,
2683 * we split the 64-bit update into two 32-bit writes. In order
2684 * for a partial fence not to be evaluated between writes, we
2685 * precede the update with write to turn off the fence register,
2686 * and only enable the fence as the last step.
2687 *
2688 * For extra levels of paranoia, we make sure each step lands
2689 * before applying the next step.
2690 */
2691 I915_WRITE(fence_reg, 0);
2692 POSTING_READ(fence_reg);
2693
2681 if (obj) { 2694 if (obj) {
2682 u32 size = obj->gtt_space->size; 2695 u32 size = obj->gtt_space->size;
2696 uint64_t val;
2683 2697
2684 val = (uint64_t)((obj->gtt_offset + size - 4096) & 2698 val = (uint64_t)((obj->gtt_offset + size - 4096) &
2685 0xfffff000) << 32; 2699 0xfffff000) << 32;
@@ -2688,12 +2702,16 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,
2688 if (obj->tiling_mode == I915_TILING_Y) 2702 if (obj->tiling_mode == I915_TILING_Y)
2689 val |= 1 << I965_FENCE_TILING_Y_SHIFT; 2703 val |= 1 << I965_FENCE_TILING_Y_SHIFT;
2690 val |= I965_FENCE_REG_VALID; 2704 val |= I965_FENCE_REG_VALID;
2691 } else
2692 val = 0;
2693 2705
2694 fence_reg += reg * 8; 2706 I915_WRITE(fence_reg + 4, val >> 32);
2695 I915_WRITE64(fence_reg, val); 2707 POSTING_READ(fence_reg + 4);
2696 POSTING_READ(fence_reg); 2708
2709 I915_WRITE(fence_reg + 0, val);
2710 POSTING_READ(fence_reg);
2711 } else {
2712 I915_WRITE(fence_reg + 4, 0);
2713 POSTING_READ(fence_reg + 4);
2714 }
2697} 2715}
2698 2716
2699static void i915_write_fence_reg(struct drm_device *dev, int reg, 2717static void i915_write_fence_reg(struct drm_device *dev, int reg,