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.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 911bd40ef513..6be940effefd 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2683,17 +2683,35 @@ static inline int fence_number(struct drm_i915_private *dev_priv,
2683 return fence - dev_priv->fence_regs; 2683 return fence - dev_priv->fence_regs;
2684} 2684}
2685 2685
2686static void i915_gem_write_fence__ipi(void *data)
2687{
2688 wbinvd();
2689}
2690
2686static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, 2691static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
2687 struct drm_i915_fence_reg *fence, 2692 struct drm_i915_fence_reg *fence,
2688 bool enable) 2693 bool enable)
2689{ 2694{
2690 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 2695 struct drm_device *dev = obj->base.dev;
2691 int reg = fence_number(dev_priv, fence); 2696 struct drm_i915_private *dev_priv = dev->dev_private;
2692 2697 int fence_reg = fence_number(dev_priv, fence);
2693 i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL); 2698
2699 /* In order to fully serialize access to the fenced region and
2700 * the update to the fence register we need to take extreme
2701 * measures on SNB+. In theory, the write to the fence register
2702 * flushes all memory transactions before, and coupled with the
2703 * mb() placed around the register write we serialise all memory
2704 * operations with respect to the changes in the tiler. Yet, on
2705 * SNB+ we need to take a step further and emit an explicit wbinvd()
2706 * on each processor in order to manually flush all memory
2707 * transactions before updating the fence register.
2708 */
2709 if (HAS_LLC(obj->base.dev))
2710 on_each_cpu(i915_gem_write_fence__ipi, NULL, 1);
2711 i915_gem_write_fence(dev, fence_reg, enable ? obj : NULL);
2694 2712
2695 if (enable) { 2713 if (enable) {
2696 obj->fence_reg = reg; 2714 obj->fence_reg = fence_reg;
2697 fence->obj = obj; 2715 fence->obj = obj;
2698 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); 2716 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
2699 } else { 2717 } else {
@@ -3992,6 +4010,12 @@ i915_gem_init_hw(struct drm_device *dev)
3992 if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1)) 4010 if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1))
3993 I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000); 4011 I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000);
3994 4012
4013 if (HAS_PCH_NOP(dev)) {
4014 u32 temp = I915_READ(GEN7_MSG_CTL);
4015 temp &= ~(WAIT_FOR_PCH_FLR_ACK | WAIT_FOR_PCH_RESET_ACK);
4016 I915_WRITE(GEN7_MSG_CTL, temp);
4017 }
4018
3995 i915_gem_l3_remap(dev); 4019 i915_gem_l3_remap(dev);
3996 4020
3997 i915_gem_init_swizzling(dev); 4021 i915_gem_init_swizzling(dev);
@@ -4005,7 +4029,13 @@ i915_gem_init_hw(struct drm_device *dev)
4005 * contexts before PPGTT. 4029 * contexts before PPGTT.
4006 */ 4030 */
4007 i915_gem_context_init(dev); 4031 i915_gem_context_init(dev);
4008 i915_gem_init_ppgtt(dev); 4032 if (dev_priv->mm.aliasing_ppgtt) {
4033 ret = dev_priv->mm.aliasing_ppgtt->enable(dev);
4034 if (ret) {
4035 i915_gem_cleanup_aliasing_ppgtt(dev);
4036 DRM_INFO("PPGTT enable failed. This is not fatal, but unexpected\n");
4037 }
4038 }
4009 4039
4010 return 0; 4040 return 0;
4011} 4041}
@@ -4160,7 +4190,9 @@ i915_gem_load(struct drm_device *dev)
4160 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 4190 if (!drm_core_check_feature(dev, DRIVER_MODESET))
4161 dev_priv->fence_reg_start = 3; 4191 dev_priv->fence_reg_start = 3;
4162 4192
4163 if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) 4193 if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev))
4194 dev_priv->num_fence_regs = 32;
4195 else if (INTEL_INFO(dev)->gen >= 4 || IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
4164 dev_priv->num_fence_regs = 16; 4196 dev_priv->num_fence_regs = 16;
4165 else 4197 else
4166 dev_priv->num_fence_regs = 8; 4198 dev_priv->num_fence_regs = 8;