summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBen Widawsky <benjamin.widawsky@intel.com>2013-11-02 21:07:24 -0700
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-11-08 18:09:47 +0100
commit9df15b499b083821b5e93fda8766b4e8eeabcd2b (patch)
treef31433b3f74cbb7dcfbc50f7fbb17a24c5c0e6c7 /drivers
parent459108b8cccfeeb965653b51be0160784e51fdc0 (diff)
drm/i915/bdw: Implement PPGTT insert
GEN8 insertion is very similar to GEN6. v2: Rebase on top of Imre's for_each_sg_page helpers. v3: Fixup my conversion (spotted by Ville). v4: Rebase on top of the address space refactoring. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> (v1) Reviewed-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2f138ed3730e..39bfaf290a95 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -230,6 +230,37 @@ static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
}
}
+static void gen8_ppgtt_insert_entries(struct i915_address_space *vm,
+ struct sg_table *pages,
+ unsigned first_entry,
+ enum i915_cache_level cache_level)
+{
+ struct i915_hw_ppgtt *ppgtt =
+ container_of(vm, struct i915_hw_ppgtt, base);
+ gen8_gtt_pte_t *pt_vaddr;
+ unsigned act_pt = first_entry / GEN8_PTES_PER_PAGE;
+ unsigned act_pte = first_entry % GEN8_PTES_PER_PAGE;
+ struct sg_page_iter sg_iter;
+
+ pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]);
+ for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) {
+ dma_addr_t page_addr;
+
+ page_addr = sg_dma_address(sg_iter.sg) +
+ (sg_iter.sg_pgoffset << PAGE_SHIFT);
+ pt_vaddr[act_pte] = gen8_pte_encode(page_addr, cache_level,
+ true);
+ if (++act_pte == GEN8_PTES_PER_PAGE) {
+ kunmap_atomic(pt_vaddr);
+ act_pt++;
+ pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]);
+ act_pte = 0;
+
+ }
+ }
+ kunmap_atomic(pt_vaddr);
+}
+
static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
{
struct i915_hw_ppgtt *ppgtt =
@@ -296,7 +327,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT);
ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE;
ppgtt->base.clear_range = gen8_ppgtt_clear_range;
- ppgtt->base.insert_entries = NULL;
+ ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
ppgtt->base.cleanup = gen8_ppgtt_cleanup;
BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS);