aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c47
1 files changed, 4 insertions, 43 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index a34e8e2ba98a..06d66e09da17 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2829,56 +2829,17 @@ static inline int fence_number(struct drm_i915_private *dev_priv,
2829 return fence - dev_priv->fence_regs; 2829 return fence - dev_priv->fence_regs;
2830} 2830}
2831 2831
2832struct write_fence {
2833 struct drm_device *dev;
2834 struct drm_i915_gem_object *obj;
2835 int fence;
2836};
2837
2838static void i915_gem_write_fence__ipi(void *data)
2839{
2840 struct write_fence *args = data;
2841
2842 /* Required for SNB+ with LLC */
2843 wbinvd();
2844
2845 /* Required for VLV */
2846 i915_gem_write_fence(args->dev, args->fence, args->obj);
2847}
2848
2849static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, 2832static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,
2850 struct drm_i915_fence_reg *fence, 2833 struct drm_i915_fence_reg *fence,
2851 bool enable) 2834 bool enable)
2852{ 2835{
2853 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 2836 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
2854 struct write_fence args = { 2837 int reg = fence_number(dev_priv, fence);
2855 .dev = obj->base.dev, 2838
2856 .fence = fence_number(dev_priv, fence), 2839 i915_gem_write_fence(obj->base.dev, reg, enable ? obj : NULL);
2857 .obj = enable ? obj : NULL,
2858 };
2859
2860 /* In order to fully serialize access to the fenced region and
2861 * the update to the fence register we need to take extreme
2862 * measures on SNB+. In theory, the write to the fence register
2863 * flushes all memory transactions before, and coupled with the
2864 * mb() placed around the register write we serialise all memory
2865 * operations with respect to the changes in the tiler. Yet, on
2866 * SNB+ we need to take a step further and emit an explicit wbinvd()
2867 * on each processor in order to manually flush all memory
2868 * transactions before updating the fence register.
2869 *
2870 * However, Valleyview complicates matter. There the wbinvd is
2871 * insufficient and unlike SNB/IVB requires the serialising
2872 * register write. (Note that that register write by itself is
2873 * conversely not sufficient for SNB+.) To compromise, we do both.
2874 */
2875 if (INTEL_INFO(args.dev)->gen >= 6)
2876 on_each_cpu(i915_gem_write_fence__ipi, &args, 1);
2877 else
2878 i915_gem_write_fence(args.dev, args.fence, args.obj);
2879 2840
2880 if (enable) { 2841 if (enable) {
2881 obj->fence_reg = args.fence; 2842 obj->fence_reg = reg;
2882 fence->obj = obj; 2843 fence->obj = obj;
2883 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list); 2844 list_move_tail(&fence->lru_list, &dev_priv->mm.fence_list);
2884 } else { 2845 } else {