diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.h')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.h | 117 |
1 files changed, 73 insertions, 44 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index c4da8191fbf3..95af4a77e9c7 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -170,9 +170,33 @@ struct i915_vma { /* Only use this if you know you want a strictly aliased binding */ #define ALIASING_BIND (1<<1) #define PTE_READ_ONLY (1<<2) - void (*bind_vma)(struct i915_vma *vma, - enum i915_cache_level cache_level, - u32 flags); + int (*bind_vma)(struct i915_vma *vma, + enum i915_cache_level cache_level, + u32 flags); +}; + + +struct i915_pagetab { + struct page *page; + dma_addr_t daddr; + + unsigned long *used_ptes; + unsigned int scratch:1; +}; + +struct i915_pagedir { + struct page *page; /* NULL for GEN6-GEN7 */ + union { + uint32_t pd_offset; + dma_addr_t daddr; + }; + + struct i915_pagetab *page_tables[I915_PDES_PER_PD]; +}; + +struct i915_pagedirpo { + /* struct page *page; */ + struct i915_pagedir *pagedirs[GEN8_LEGACY_PDPES]; }; struct i915_address_space { @@ -214,6 +238,12 @@ struct i915_address_space { gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr, enum i915_cache_level level, bool valid, u32 flags); /* Create a valid PTE */ + int (*allocate_va_range)(struct i915_address_space *vm, + uint64_t start, + uint64_t length); + void (*teardown_va_range)(struct i915_address_space *vm, + uint64_t start, + uint64_t length); void (*clear_range)(struct i915_address_space *vm, uint64_t start, uint64_t length, @@ -225,6 +255,30 @@ struct i915_address_space { void (*cleanup)(struct i915_address_space *vm); }; +struct i915_hw_ppgtt { + struct i915_address_space base; + struct kref ref; + struct drm_mm_node node; + unsigned num_pd_entries; + unsigned num_pd_pages; /* gen8+ */ + union { + struct i915_pagedirpo pdp; + struct i915_pagedir pd; + }; + + struct i915_pagetab *scratch_pt; + + struct intel_context *ctx; + + gen6_gtt_pte_t __iomem *pd_addr; + + int (*enable)(struct i915_hw_ppgtt *ppgtt); + int (*switch_mm)(struct i915_hw_ppgtt *ppgtt, + struct intel_engine_cs *ring, + bool synchronous); + void (*debug_dump)(struct i915_hw_ppgtt *ppgtt, struct seq_file *m); +}; + /* The Graphics Translation Table is the way in which GEN hardware translates a * Graphics Virtual Address into a Physical Address. In addition to the normal * collateral associated with any va->pa translations GEN hardware also has a @@ -253,47 +307,22 @@ struct i915_gtt { unsigned long *mappable_end); }; -struct i915_pagetab { - struct page *page; - dma_addr_t daddr; -}; - -struct i915_pagedir { - struct page *page; /* NULL for GEN6-GEN7 */ - union { - uint32_t pd_offset; - dma_addr_t daddr; - }; - - struct i915_pagetab *page_tables[I915_PDES_PER_PD]; /* PDEs */ -}; - -struct i915_pagedirpo { - /* struct page *page; */ - struct i915_pagedir *pagedir[GEN8_LEGACY_PDPES]; -}; - -struct i915_hw_ppgtt { - struct i915_address_space base; - struct kref ref; - struct drm_mm_node node; - unsigned num_pd_entries; - unsigned num_pd_pages; /* gen8+ */ - union { - struct i915_pagedirpo pdp; - struct i915_pagedir pd; - }; - - struct intel_context *ctx; - - gen6_gtt_pte_t __iomem *pd_addr; - - int (*enable)(struct i915_hw_ppgtt *ppgtt); - int (*switch_mm)(struct i915_hw_ppgtt *ppgtt, - struct intel_engine_cs *ring, - bool synchronous); - void (*debug_dump)(struct i915_hw_ppgtt *ppgtt, struct seq_file *m); -}; +/* For each pde iterates over every pde between from start until start + length. + * If start, and start+length are not perfectly divisible, the macro will round + * down, and up as needed. The macro modifies pde, start, and length. Dev is + * only used to differentiate shift values. Temp is temp. On gen6/7, start = 0, + * and length = 2G effectively iterates over every PDE in the system. On gen8+ + * it simply iterates over every page directory entry in a page directory. + * + * XXX: temp is not actually needed, but it saves doing the ALIGN operation. + */ +#define gen6_for_each_pde(pt, pd, start, length, temp, iter) \ + for (iter = gen6_pde_index(start), pt = (pd)->page_tables[iter]; \ + length > 0 && iter < I915_PDES_PER_PD; \ + pt = (pd)->page_tables[++iter], \ + temp = ALIGN(start+1, 1 << GEN6_PDE_SHIFT) - start, \ + temp = min(temp, (unsigned)length), \ + start += temp, length -= temp) static inline uint32_t i915_pte_index(uint64_t address, uint32_t pde_shift) { |