diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 46 |
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 | ||
2686 | static void i915_gem_write_fence__ipi(void *data) | ||
2687 | { | ||
2688 | wbinvd(); | ||
2689 | } | ||
2690 | |||
2686 | static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | 2691 | static 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; |