Commit 17f297b4 authored by Chris Wilson's avatar Chris Wilson

drm/i915/gtt: Push allocation to hw ppgtt constructor

In the next patch, we will subclass the gen6 hw_ppgtt. In order, for the
two different generations of hw ppgtt stucts to be of different size,
push the allocation down to the constructor.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Matthew Auld <matthew.william.auld@gmail.com>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180607163040.9781-1-chris@chris-wilson.co.uk
parent 93f2cde2
...@@ -1562,32 +1562,36 @@ static int gen8_preallocate_top_level_pdp(struct i915_hw_ppgtt *ppgtt) ...@@ -1562,32 +1562,36 @@ static int gen8_preallocate_top_level_pdp(struct i915_hw_ppgtt *ppgtt)
* space. * space.
* *
*/ */
static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt) static struct i915_hw_ppgtt *gen8_ppgtt_create(struct drm_i915_private *i915)
{ {
struct i915_address_space *vm = &ppgtt->vm; struct i915_hw_ppgtt *ppgtt;
struct drm_i915_private *dev_priv = vm->i915; int err;
int ret;
ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
if (!ppgtt)
return ERR_PTR(-ENOMEM);
ppgtt->vm.total = USES_FULL_48BIT_PPGTT(dev_priv) ? ppgtt->vm.i915 = i915;
ppgtt->vm.dma = &i915->drm.pdev->dev;
ppgtt->vm.total = USES_FULL_48BIT_PPGTT(i915) ?
1ULL << 48 : 1ULL << 48 :
1ULL << 32; 1ULL << 32;
/* There are only few exceptions for gen >=6. chv and bxt. /* There are only few exceptions for gen >=6. chv and bxt.
* And we are not sure about the latter so play safe for now. * And we are not sure about the latter so play safe for now.
*/ */
if (IS_CHERRYVIEW(dev_priv) || IS_BROXTON(dev_priv)) if (IS_CHERRYVIEW(i915) || IS_BROXTON(i915))
ppgtt->vm.pt_kmap_wc = true; ppgtt->vm.pt_kmap_wc = true;
ret = gen8_init_scratch(&ppgtt->vm); err = gen8_init_scratch(&ppgtt->vm);
if (ret) { if (err)
ppgtt->vm.total = 0; goto err_free;
return ret;
}
if (use_4lvl(vm)) { if (use_4lvl(&ppgtt->vm)) {
ret = setup_px(&ppgtt->vm, &ppgtt->pml4); err = setup_px(&ppgtt->vm, &ppgtt->pml4);
if (ret) if (err)
goto free_scratch; goto err_scratch;
gen8_initialize_pml4(&ppgtt->vm, &ppgtt->pml4); gen8_initialize_pml4(&ppgtt->vm, &ppgtt->pml4);
...@@ -1595,15 +1599,15 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ...@@ -1595,15 +1599,15 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->vm.insert_entries = gen8_ppgtt_insert_4lvl; ppgtt->vm.insert_entries = gen8_ppgtt_insert_4lvl;
ppgtt->vm.clear_range = gen8_ppgtt_clear_4lvl; ppgtt->vm.clear_range = gen8_ppgtt_clear_4lvl;
} else { } else {
ret = __pdp_init(&ppgtt->vm, &ppgtt->pdp); err = __pdp_init(&ppgtt->vm, &ppgtt->pdp);
if (ret) if (err)
goto free_scratch; goto err_scratch;
if (intel_vgpu_active(dev_priv)) { if (intel_vgpu_active(i915)) {
ret = gen8_preallocate_top_level_pdp(ppgtt); err = gen8_preallocate_top_level_pdp(ppgtt);
if (ret) { if (err) {
__pdp_fini(&ppgtt->pdp); __pdp_fini(&ppgtt->pdp);
goto free_scratch; goto err_scratch;
} }
} }
...@@ -1612,7 +1616,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ...@@ -1612,7 +1616,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->vm.clear_range = gen8_ppgtt_clear_3lvl; ppgtt->vm.clear_range = gen8_ppgtt_clear_3lvl;
} }
if (intel_vgpu_active(dev_priv)) if (intel_vgpu_active(i915))
gen8_ppgtt_notify_vgt(ppgtt, true); gen8_ppgtt_notify_vgt(ppgtt, true);
ppgtt->vm.cleanup = gen8_ppgtt_cleanup; ppgtt->vm.cleanup = gen8_ppgtt_cleanup;
...@@ -1623,11 +1627,13 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ...@@ -1623,11 +1627,13 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
ppgtt->vm.vma_ops.set_pages = ppgtt_set_pages; ppgtt->vm.vma_ops.set_pages = ppgtt_set_pages;
ppgtt->vm.vma_ops.clear_pages = clear_pages; ppgtt->vm.vma_ops.clear_pages = clear_pages;
return 0; return ppgtt;
free_scratch: err_scratch:
gen8_free_scratch(&ppgtt->vm); gen8_free_scratch(&ppgtt->vm);
return ret; err_free:
kfree(ppgtt);
return ERR_PTR(err);
} }
static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m) static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
...@@ -1638,8 +1644,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m) ...@@ -1638,8 +1644,7 @@ static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
u32 pd_entry, pte, pde; u32 pd_entry, pte, pde;
u32 start = 0, length = ppgtt->vm.total; u32 start = 0, length = ppgtt->vm.total;
scratch_pte = vm->pte_encode(vm->scratch_page.daddr, scratch_pte = vm->pte_encode(vm->scratch_page.daddr, I915_CACHE_LLC, 0);
I915_CACHE_LLC, 0);
gen6_for_each_pde(unused, &ppgtt->pd, start, length, pde) { gen6_for_each_pde(unused, &ppgtt->pd, start, length, pde) {
u32 expected; u32 expected;
...@@ -2027,36 +2032,41 @@ static void gen6_scratch_va_range(struct i915_hw_ppgtt *ppgtt, ...@@ -2027,36 +2032,41 @@ static void gen6_scratch_va_range(struct i915_hw_ppgtt *ppgtt,
ppgtt->pd.page_table[pde] = ppgtt->vm.scratch_pt; ppgtt->pd.page_table[pde] = ppgtt->vm.scratch_pt;
} }
static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) static struct i915_hw_ppgtt *gen6_ppgtt_create(struct drm_i915_private *i915)
{ {
struct drm_i915_private *dev_priv = ppgtt->vm.i915; struct i915_ggtt * const ggtt = &i915->ggtt;
struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_hw_ppgtt *ppgtt;
int ret; int err;
ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
if (!ppgtt)
return ERR_PTR(-ENOMEM);
ppgtt->vm.i915 = i915;
ppgtt->vm.dma = &i915->drm.pdev->dev;
ppgtt->vm.pte_encode = ggtt->vm.pte_encode; ppgtt->vm.pte_encode = ggtt->vm.pte_encode;
if (intel_vgpu_active(dev_priv) || IS_GEN6(dev_priv)) if (intel_vgpu_active(i915) || IS_GEN6(i915))
ppgtt->switch_mm = gen6_mm_switch; ppgtt->switch_mm = gen6_mm_switch;
else if (IS_HASWELL(dev_priv)) else if (IS_HASWELL(i915))
ppgtt->switch_mm = hsw_mm_switch; ppgtt->switch_mm = hsw_mm_switch;
else if (IS_GEN7(dev_priv)) else if (IS_GEN7(i915))
ppgtt->switch_mm = gen7_mm_switch; ppgtt->switch_mm = gen7_mm_switch;
else else
BUG(); BUG();
ret = gen6_ppgtt_alloc(ppgtt); err = gen6_ppgtt_alloc(ppgtt);
if (ret) if (err)
return ret; goto err_free;
ppgtt->vm.total = I915_PDES * GEN6_PTES * PAGE_SIZE; ppgtt->vm.total = I915_PDES * GEN6_PTES * PAGE_SIZE;
gen6_scratch_va_range(ppgtt, 0, ppgtt->vm.total); gen6_scratch_va_range(ppgtt, 0, ppgtt->vm.total);
gen6_write_page_range(ppgtt, 0, ppgtt->vm.total); gen6_write_page_range(ppgtt, 0, ppgtt->vm.total);
ret = gen6_alloc_va_range(&ppgtt->vm, 0, ppgtt->vm.total); err = gen6_alloc_va_range(&ppgtt->vm, 0, ppgtt->vm.total);
if (ret) { if (err)
gen6_ppgtt_cleanup(&ppgtt->vm); goto err_cleanup;
return ret;
}
ppgtt->vm.clear_range = gen6_ppgtt_clear_range; ppgtt->vm.clear_range = gen6_ppgtt_clear_range;
ppgtt->vm.insert_entries = gen6_ppgtt_insert_entries; ppgtt->vm.insert_entries = gen6_ppgtt_insert_entries;
...@@ -2075,19 +2085,13 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ...@@ -2075,19 +2085,13 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
DRM_DEBUG_DRIVER("Adding PPGTT at offset %x\n", DRM_DEBUG_DRIVER("Adding PPGTT at offset %x\n",
ppgtt->pd.base.ggtt_offset << 10); ppgtt->pd.base.ggtt_offset << 10);
return 0; return ppgtt;
}
static int __hw_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
struct drm_i915_private *dev_priv)
{
ppgtt->vm.i915 = dev_priv;
ppgtt->vm.dma = &dev_priv->drm.pdev->dev;
if (INTEL_GEN(dev_priv) < 8) err_cleanup:
return gen6_ppgtt_init(ppgtt); gen6_ppgtt_cleanup(&ppgtt->vm);
else err_free:
return gen8_ppgtt_init(ppgtt); kfree(ppgtt);
return ERR_PTR(err);
} }
static void i915_address_space_init(struct i915_address_space *vm, static void i915_address_space_init(struct i915_address_space *vm,
...@@ -2173,26 +2177,28 @@ int i915_ppgtt_init_hw(struct drm_i915_private *dev_priv) ...@@ -2173,26 +2177,28 @@ int i915_ppgtt_init_hw(struct drm_i915_private *dev_priv)
return 0; return 0;
} }
static struct i915_hw_ppgtt *
__hw_ppgtt_create(struct drm_i915_private *i915)
{
if (INTEL_GEN(i915) < 8)
return gen6_ppgtt_create(i915);
else
return gen8_ppgtt_create(i915);
}
struct i915_hw_ppgtt * struct i915_hw_ppgtt *
i915_ppgtt_create(struct drm_i915_private *dev_priv, i915_ppgtt_create(struct drm_i915_private *i915,
struct drm_i915_file_private *fpriv, struct drm_i915_file_private *fpriv,
const char *name) const char *name)
{ {
struct i915_hw_ppgtt *ppgtt; struct i915_hw_ppgtt *ppgtt;
int ret;
ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); ppgtt = __hw_ppgtt_create(i915);
if (!ppgtt) if (IS_ERR(ppgtt))
return ERR_PTR(-ENOMEM); return ppgtt;
ret = __hw_ppgtt_init(ppgtt, dev_priv);
if (ret) {
kfree(ppgtt);
return ERR_PTR(ret);
}
kref_init(&ppgtt->ref); kref_init(&ppgtt->ref);
i915_address_space_init(&ppgtt->vm, dev_priv, name); i915_address_space_init(&ppgtt->vm, i915, name);
ppgtt->vm.file = fpriv; ppgtt->vm.file = fpriv;
trace_i915_ppgtt_create(&ppgtt->vm); trace_i915_ppgtt_create(&ppgtt->vm);
......
...@@ -147,12 +147,16 @@ static int igt_ppgtt_alloc(void *arg) ...@@ -147,12 +147,16 @@ static int igt_ppgtt_alloc(void *arg)
return -ENOMEM; return -ENOMEM;
mutex_lock(&dev_priv->drm.struct_mutex); mutex_lock(&dev_priv->drm.struct_mutex);
err = __hw_ppgtt_init(ppgtt, dev_priv); ppgtt = __hw_ppgtt_create(dev_priv);
if (err) if (IS_ERR(ppgtt)) {
goto err_ppgtt; err = PTR_ERR(ppgtt);
goto err_unlock;
}
if (!ppgtt->vm.allocate_va_range) if (!ppgtt->vm.allocate_va_range) {
err = 0;
goto err_ppgtt_cleanup; goto err_ppgtt_cleanup;
}
/* Check we can allocate the entire range */ /* Check we can allocate the entire range */
for (size = 4096; for (size = 4096;
...@@ -189,9 +193,9 @@ static int igt_ppgtt_alloc(void *arg) ...@@ -189,9 +193,9 @@ static int igt_ppgtt_alloc(void *arg)
err_ppgtt_cleanup: err_ppgtt_cleanup:
ppgtt->vm.cleanup(&ppgtt->vm); ppgtt->vm.cleanup(&ppgtt->vm);
err_ppgtt:
mutex_unlock(&dev_priv->drm.struct_mutex);
kfree(ppgtt); kfree(ppgtt);
err_unlock:
mutex_unlock(&dev_priv->drm.struct_mutex);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment