summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_gem_gtt.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-11-29 20:13:28 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2019-11-30 09:21:12 +0000
commit3cd6e8860ecd40f358b9d30d5bfecbc74fd7cfef (patch)
tree661769d0f711b9d18ccdc2c33539a9bf40f8fdc8 /drivers/gpu/drm/i915/i915_gem_gtt.c
parentf9a863c2ffc17f72137fae8cac3314961dc6be24 (diff)
drm/i915/gen7: Re-enable full-ppgtt for ivb & hsw
After much hair pulling, resort to preallocating the ppGTT entries on init to circumvent the apparent lack of PD invalidate following the write to PP_DCLV upon switching mm between contexts (and here the same context after binding new objects). However, the details of that PP_DCLV invalidate are still unknown, and it appears we need to reload the mm twice to cover over a timing issue. Worrying. Fixes: 3dc007fe9b2b ("drm/i915/gtt: Downgrade gen7 (ivb, byt, hsw) back to aliasing-ppgtt") Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191129201328.1398583-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 6239a9adbf14..98835fea38a9 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -1692,7 +1692,6 @@ static int gen6_alloc_va_range(struct i915_address_space *vm,
intel_wakeref_t wakeref;
u64 from = start;
unsigned int pde;
- bool flush = false;
int ret = 0;
wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm);
@@ -1717,11 +1716,6 @@ static int gen6_alloc_va_range(struct i915_address_space *vm,
spin_lock(&pd->lock);
if (pd->entry[pde] == &vm->scratch[1]) {
pd->entry[pde] = pt;
- if (i915_vma_is_bound(ppgtt->vma,
- I915_VMA_GLOBAL_BIND)) {
- gen6_write_pde(ppgtt, pde, pt);
- flush = true;
- }
} else {
alloc = pt;
pt = pd->entry[pde];
@@ -1732,9 +1726,19 @@ static int gen6_alloc_va_range(struct i915_address_space *vm,
}
spin_unlock(&pd->lock);
- if (flush)
+ if (i915_vma_is_bound(ppgtt->vma, I915_VMA_GLOBAL_BIND)) {
+ mutex_lock(&ppgtt->flush);
+
+ /* Rewrite them all! Anything less misses an invalidate. */
+ gen6_for_all_pdes(pt, pd, pde)
+ gen6_write_pde(ppgtt, pde, pt);
+
+ ioread32(ppgtt->pd_addr + pde - 1);
gen6_ggtt_invalidate(vm->gt->ggtt);
+ mutex_unlock(&ppgtt->flush);
+ }
+
goto out;
unwind_out:
@@ -1793,6 +1797,7 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
gen6_ppgtt_free_pd(ppgtt);
free_scratch(vm);
+ mutex_destroy(&ppgtt->flush);
mutex_destroy(&ppgtt->pin_mutex);
kfree(ppgtt->base.pd);
}
@@ -1958,6 +1963,7 @@ static struct i915_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
if (!ppgtt)
return ERR_PTR(-ENOMEM);
+ mutex_init(&ppgtt->flush);
mutex_init(&ppgtt->pin_mutex);
ppgtt_init(&ppgtt->base, &i915->gt);
@@ -1994,6 +2000,7 @@ err_scratch:
err_pd:
kfree(ppgtt->base.pd);
err_free:
+ mutex_destroy(&ppgtt->pin_mutex);
kfree(ppgtt);
return ERR_PTR(err);
}