diff options
author | Ben Widawsky <benjamin.widawsky@intel.com> | 2013-11-03 00:07:24 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-11-08 12:09:47 -0500 |
commit | 9df15b499b083821b5e93fda8766b4e8eeabcd2b (patch) | |
tree | f31433b3f74cbb7dcfbc50f7fbb17a24c5c0e6c7 | |
parent | 459108b8cccfeeb965653b51be0160784e51fdc0 (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>
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 33 |
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, | |||
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
233 | static void gen8_ppgtt_insert_entries(struct i915_address_space *vm, | ||
234 | struct sg_table *pages, | ||
235 | unsigned first_entry, | ||
236 | enum i915_cache_level cache_level) | ||
237 | { | ||
238 | struct i915_hw_ppgtt *ppgtt = | ||
239 | container_of(vm, struct i915_hw_ppgtt, base); | ||
240 | gen8_gtt_pte_t *pt_vaddr; | ||
241 | unsigned act_pt = first_entry / GEN8_PTES_PER_PAGE; | ||
242 | unsigned act_pte = first_entry % GEN8_PTES_PER_PAGE; | ||
243 | struct sg_page_iter sg_iter; | ||
244 | |||
245 | pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]); | ||
246 | for_each_sg_page(pages->sgl, &sg_iter, pages->nents, 0) { | ||
247 | dma_addr_t page_addr; | ||
248 | |||
249 | page_addr = sg_dma_address(sg_iter.sg) + | ||
250 | (sg_iter.sg_pgoffset << PAGE_SHIFT); | ||
251 | pt_vaddr[act_pte] = gen8_pte_encode(page_addr, cache_level, | ||
252 | true); | ||
253 | if (++act_pte == GEN8_PTES_PER_PAGE) { | ||
254 | kunmap_atomic(pt_vaddr); | ||
255 | act_pt++; | ||
256 | pt_vaddr = kmap_atomic(&ppgtt->gen8_pt_pages[act_pt]); | ||
257 | act_pte = 0; | ||
258 | |||
259 | } | ||
260 | } | ||
261 | kunmap_atomic(pt_vaddr); | ||
262 | } | ||
263 | |||
233 | static void gen8_ppgtt_cleanup(struct i915_address_space *vm) | 264 | static void gen8_ppgtt_cleanup(struct i915_address_space *vm) |
234 | { | 265 | { |
235 | struct i915_hw_ppgtt *ppgtt = | 266 | struct i915_hw_ppgtt *ppgtt = |
@@ -296,7 +327,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) | |||
296 | ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT); | 327 | ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT); |
297 | ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; | 328 | ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; |
298 | ppgtt->base.clear_range = gen8_ppgtt_clear_range; | 329 | ppgtt->base.clear_range = gen8_ppgtt_clear_range; |
299 | ppgtt->base.insert_entries = NULL; | 330 | ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; |
300 | ppgtt->base.cleanup = gen8_ppgtt_cleanup; | 331 | ppgtt->base.cleanup = gen8_ppgtt_cleanup; |
301 | 332 | ||
302 | BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS); | 333 | BUG_ON(ppgtt->num_pd_pages > GEN8_LEGACY_PDPS); |