summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_gem_gtt.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_gtt.h')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.h117
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)
{