diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 30 |
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 | ||
2699 | static void i915_write_fence_reg(struct drm_device *dev, int reg, | 2717 | static void i915_write_fence_reg(struct drm_device *dev, int reg, |