diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 45 |
1 files changed, 29 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index c02b37e32f7b..06fb928bdab3 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -538,27 +538,40 @@ static void gen8_ppgtt_insert_entries(struct i915_address_space *vm, } } -static void gen8_free_page_tables(struct i915_pagedir *pd, struct drm_device *dev) +static void gen8_teardown_va_range(struct i915_address_space *vm, + uint64_t start, uint64_t length) { - int i; - - if (!pd->page) - return; - - for (i = 0; i < I915_PDES_PER_PD; i++) { - free_pt_single(pd->page_tables[i], dev); - pd->page_tables[i] = NULL; + struct i915_hw_ppgtt *ppgtt = + container_of(vm, struct i915_hw_ppgtt, base); + struct i915_pagedir *pd; + struct i915_pagetab *pt; + uint64_t temp; + uint32_t pdpe, pde; + + gen8_for_each_pdpe(pd, &ppgtt->pdp, start, length, temp, pdpe) { + uint64_t pd_len = gen8_clamp_pd(start, length); + uint64_t pd_start = start; + gen8_for_each_pde(pt, pd, pd_start, pd_len, temp, pde) { + free_pt_single(pt, vm->dev); + } + free_pd_single(pd, vm->dev); } } -static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt) +/* This function will die soon */ +static void gen8_free_full_pagedir(struct i915_hw_ppgtt *ppgtt, int i) { - int i; + gen8_teardown_va_range(&ppgtt->base, + i << GEN8_PDPE_SHIFT, + (1 << GEN8_PDPE_SHIFT)); +} - for (i = 0; i < ppgtt->num_pd_pages; i++) { - gen8_free_page_tables(ppgtt->pdp.pagedirs[i], ppgtt->base.dev); - free_pd_single(ppgtt->pdp.pagedirs[i], ppgtt->base.dev); - } +static void gen8_ppgtt_free(struct i915_hw_ppgtt *ppgtt) +{ + trace_i915_va_teardown(&ppgtt->base, + ppgtt->base.start, ppgtt->base.total); + gen8_teardown_va_range(&ppgtt->base, + ppgtt->base.start, ppgtt->base.total); } static void gen8_ppgtt_cleanup(struct i915_address_space *vm) @@ -587,7 +600,7 @@ static int gen8_ppgtt_allocate_page_tables(struct i915_hw_ppgtt *ppgtt) unwind_out: while (i--) - gen8_free_page_tables(ppgtt->pdp.pagedirs[i], ppgtt->base.dev); + gen8_free_full_pagedir(ppgtt, i); return -ENOMEM; } |