From 9271d959dc03fc7514030e22280cdbd6ca763ca5 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Wed, 8 Apr 2015 12:13:26 +0100 Subject: [PATCH] drm/i915/gen8: Add dynamic allocation macros and helper functions Similar to gen6, we will use for_each_pde/for_each_pdpe and pte/pde/pdpe_index to iterate over these new structures. v2: Match trace_i915_va_teardown params v3: Multiple rebases. v4: Updated to use unmap_and_free_pt. v5: teardown_va_range logic no longer needed. v6: Rebase after s/page_tables/page_table/. v7: Renamed commit to match what it does now (it was "Use dynamic allocation idioms on free"). v8: Prevent (harmless) out of range access in gen8_for_each_pde and gen8_for_each_pdpe_e. Signed-off-by: Ben Widawsky Signed-off-by: Michel Thierry (v2+) Reviewed-by: Mika Kuoppala [danvet: s/BUG/WARN/] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.h | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 1384789..63fda82 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -397,6 +397,58 @@ static inline uint32_t gen6_pde_index(uint32_t addr) return i915_pde_index(addr, GEN6_PDE_SHIFT); } +/* Equivalent to the gen6 version, For each pde iterates over every pde + * between from start until start + length. On gen8+ it simply iterates + * over every page directory entry in a page directory. + */ +#define gen8_for_each_pde(pt, pd, start, length, temp, iter) \ + for (iter = gen8_pde_index(start); \ + pt = (pd)->page_table[iter], length > 0 && iter < I915_PDES; \ + iter++, \ + temp = ALIGN(start+1, 1 << GEN8_PDE_SHIFT) - start, \ + temp = min(temp, length), \ + start += temp, length -= temp) + +#define gen8_for_each_pdpe(pd, pdp, start, length, temp, iter) \ + for (iter = gen8_pdpe_index(start); \ + pd = (pdp)->page_directory[iter], length > 0 && iter < GEN8_LEGACY_PDPES; \ + iter++, \ + temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT) - start, \ + temp = min(temp, length), \ + start += temp, length -= temp) + +/* Clamp length to the next page_directory boundary */ +static inline uint64_t gen8_clamp_pd(uint64_t start, uint64_t length) +{ + uint64_t next_pd = ALIGN(start + 1, 1 << GEN8_PDPE_SHIFT); + + if (next_pd > (start + length)) + return length; + + return next_pd - start; +} + +static inline uint32_t gen8_pte_index(uint64_t address) +{ + return i915_pte_index(address, GEN8_PDE_SHIFT); +} + +static inline uint32_t gen8_pde_index(uint64_t address) +{ + return i915_pde_index(address, GEN8_PDE_SHIFT); +} + +static inline uint32_t gen8_pdpe_index(uint64_t address) +{ + return (address >> GEN8_PDPE_SHIFT) & GEN8_PDPE_MASK; +} + +static inline uint32_t gen8_pml4e_index(uint64_t address) +{ + WARN_ON(1); /* For 64B */ + return 0; +} + int i915_gem_gtt_init(struct drm_device *dev); void i915_gem_init_global_gtt(struct drm_device *dev); void i915_global_gtt_cleanup(struct drm_device *dev); -- 2.7.4