diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-06-10 04:52:59 -0400 |
---|---|---|
committer | Tvrtko Ursulin <tvrtko.ursulin@intel.com> | 2016-06-13 05:03:54 -0400 |
commit | d6473f566417a507b9ea5b0fc44ff26d930d0e5d (patch) | |
tree | 59ddad85437028331a4496c8df8957f50f11d2e7 | |
parent | 4e50f79622716b444b5b07d3d1b5870fe1794e24 (diff) |
drm/i915: Add support for mapping an object page by page
Introduced a new vm specfic callback insert_page() to program a single pte in
ggtt or ppgtt. This allows us to map a single page in to the mappable aperture
space. This can be iterated over to access the whole object by using space as
meagre as page size.
v2: Added low level rpm assertions to insert_page routines (Chris)
v3: Added POSTING_READ post register write (Tvrtko)
v4: Rebase (Ankit)
v5: Removed wmb() and FLUSH_CTL from insert_page, caller to take care
of it (Chris)
v6: insert_page not working correctly without FLSH_CNTL write, added the
write again.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ankitprasad Sharma <ankitprasad.r.sharma@intel.com>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
-rw-r--r-- | drivers/char/agp/intel-gtt.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 66 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.h | 5 | ||||
-rw-r--r-- | include/drm/intel-gtt.h | 3 |
4 files changed, 81 insertions, 1 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index aef87fdbd187..44311296ec02 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -840,6 +840,14 @@ static bool i830_check_flags(unsigned int flags) | |||
840 | return false; | 840 | return false; |
841 | } | 841 | } |
842 | 842 | ||
843 | void intel_gtt_insert_page(dma_addr_t addr, | ||
844 | unsigned int pg, | ||
845 | unsigned int flags) | ||
846 | { | ||
847 | intel_private.driver->write_entry(addr, pg, flags); | ||
848 | } | ||
849 | EXPORT_SYMBOL(intel_gtt_insert_page); | ||
850 | |||
843 | void intel_gtt_insert_sg_entries(struct sg_table *st, | 851 | void intel_gtt_insert_sg_entries(struct sg_table *st, |
844 | unsigned int pg_start, | 852 | unsigned int pg_start, |
845 | unsigned int flags) | 853 | unsigned int flags) |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 46684779d4d6..7a139a6d4487 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -2355,6 +2355,28 @@ static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) | |||
2355 | #endif | 2355 | #endif |
2356 | } | 2356 | } |
2357 | 2357 | ||
2358 | static void gen8_ggtt_insert_page(struct i915_address_space *vm, | ||
2359 | dma_addr_t addr, | ||
2360 | uint64_t offset, | ||
2361 | enum i915_cache_level level, | ||
2362 | u32 unused) | ||
2363 | { | ||
2364 | struct drm_i915_private *dev_priv = to_i915(vm->dev); | ||
2365 | gen8_pte_t __iomem *pte = | ||
2366 | (gen8_pte_t __iomem *)dev_priv->ggtt.gsm + | ||
2367 | (offset >> PAGE_SHIFT); | ||
2368 | int rpm_atomic_seq; | ||
2369 | |||
2370 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
2371 | |||
2372 | gen8_set_pte(pte, gen8_pte_encode(addr, level, true)); | ||
2373 | |||
2374 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | ||
2375 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | ||
2376 | |||
2377 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
2378 | } | ||
2379 | |||
2358 | static void gen8_ggtt_insert_entries(struct i915_address_space *vm, | 2380 | static void gen8_ggtt_insert_entries(struct i915_address_space *vm, |
2359 | struct sg_table *st, | 2381 | struct sg_table *st, |
2360 | uint64_t start, | 2382 | uint64_t start, |
@@ -2424,6 +2446,28 @@ static void gen8_ggtt_insert_entries__BKL(struct i915_address_space *vm, | |||
2424 | stop_machine(gen8_ggtt_insert_entries__cb, &arg, NULL); | 2446 | stop_machine(gen8_ggtt_insert_entries__cb, &arg, NULL); |
2425 | } | 2447 | } |
2426 | 2448 | ||
2449 | static void gen6_ggtt_insert_page(struct i915_address_space *vm, | ||
2450 | dma_addr_t addr, | ||
2451 | uint64_t offset, | ||
2452 | enum i915_cache_level level, | ||
2453 | u32 flags) | ||
2454 | { | ||
2455 | struct drm_i915_private *dev_priv = to_i915(vm->dev); | ||
2456 | gen6_pte_t __iomem *pte = | ||
2457 | (gen6_pte_t __iomem *)dev_priv->ggtt.gsm + | ||
2458 | (offset >> PAGE_SHIFT); | ||
2459 | int rpm_atomic_seq; | ||
2460 | |||
2461 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
2462 | |||
2463 | iowrite32(vm->pte_encode(addr, level, true, flags), pte); | ||
2464 | |||
2465 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | ||
2466 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | ||
2467 | |||
2468 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
2469 | } | ||
2470 | |||
2427 | /* | 2471 | /* |
2428 | * Binds an object into the global gtt with the specified cache level. The object | 2472 | * Binds an object into the global gtt with the specified cache level. The object |
2429 | * will be accessible to the GPU via commands whose operands reference offsets | 2473 | * will be accessible to the GPU via commands whose operands reference offsets |
@@ -2543,6 +2587,24 @@ static void gen6_ggtt_clear_range(struct i915_address_space *vm, | |||
2543 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | 2587 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); |
2544 | } | 2588 | } |
2545 | 2589 | ||
2590 | static void i915_ggtt_insert_page(struct i915_address_space *vm, | ||
2591 | dma_addr_t addr, | ||
2592 | uint64_t offset, | ||
2593 | enum i915_cache_level cache_level, | ||
2594 | u32 unused) | ||
2595 | { | ||
2596 | struct drm_i915_private *dev_priv = to_i915(vm->dev); | ||
2597 | unsigned int flags = (cache_level == I915_CACHE_NONE) ? | ||
2598 | AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY; | ||
2599 | int rpm_atomic_seq; | ||
2600 | |||
2601 | rpm_atomic_seq = assert_rpm_atomic_begin(dev_priv); | ||
2602 | |||
2603 | intel_gtt_insert_page(addr, offset >> PAGE_SHIFT, flags); | ||
2604 | |||
2605 | assert_rpm_atomic_end(dev_priv, rpm_atomic_seq); | ||
2606 | } | ||
2607 | |||
2546 | static void i915_ggtt_insert_entries(struct i915_address_space *vm, | 2608 | static void i915_ggtt_insert_entries(struct i915_address_space *vm, |
2547 | struct sg_table *pages, | 2609 | struct sg_table *pages, |
2548 | uint64_t start, | 2610 | uint64_t start, |
@@ -3076,7 +3138,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) | |||
3076 | 3138 | ||
3077 | ggtt->base.bind_vma = ggtt_bind_vma; | 3139 | ggtt->base.bind_vma = ggtt_bind_vma; |
3078 | ggtt->base.unbind_vma = ggtt_unbind_vma; | 3140 | ggtt->base.unbind_vma = ggtt_unbind_vma; |
3079 | 3141 | ggtt->base.insert_page = gen8_ggtt_insert_page; | |
3080 | ggtt->base.clear_range = nop_clear_range; | 3142 | ggtt->base.clear_range = nop_clear_range; |
3081 | if (!USES_FULL_PPGTT(dev_priv)) | 3143 | if (!USES_FULL_PPGTT(dev_priv)) |
3082 | ggtt->base.clear_range = gen8_ggtt_clear_range; | 3144 | ggtt->base.clear_range = gen8_ggtt_clear_range; |
@@ -3116,6 +3178,7 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt) | |||
3116 | ret = ggtt_probe_common(dev, ggtt->size); | 3178 | ret = ggtt_probe_common(dev, ggtt->size); |
3117 | 3179 | ||
3118 | ggtt->base.clear_range = gen6_ggtt_clear_range; | 3180 | ggtt->base.clear_range = gen6_ggtt_clear_range; |
3181 | ggtt->base.insert_page = gen6_ggtt_insert_page; | ||
3119 | ggtt->base.insert_entries = gen6_ggtt_insert_entries; | 3182 | ggtt->base.insert_entries = gen6_ggtt_insert_entries; |
3120 | ggtt->base.bind_vma = ggtt_bind_vma; | 3183 | ggtt->base.bind_vma = ggtt_bind_vma; |
3121 | ggtt->base.unbind_vma = ggtt_unbind_vma; | 3184 | ggtt->base.unbind_vma = ggtt_unbind_vma; |
@@ -3147,6 +3210,7 @@ static int i915_gmch_probe(struct i915_ggtt *ggtt) | |||
3147 | &ggtt->mappable_base, &ggtt->mappable_end); | 3210 | &ggtt->mappable_base, &ggtt->mappable_end); |
3148 | 3211 | ||
3149 | ggtt->do_idle_maps = needs_idle_maps(dev_priv->dev); | 3212 | ggtt->do_idle_maps = needs_idle_maps(dev_priv->dev); |
3213 | ggtt->base.insert_page = i915_ggtt_insert_page; | ||
3150 | ggtt->base.insert_entries = i915_ggtt_insert_entries; | 3214 | ggtt->base.insert_entries = i915_ggtt_insert_entries; |
3151 | ggtt->base.clear_range = i915_ggtt_clear_range; | 3215 | ggtt->base.clear_range = i915_ggtt_clear_range; |
3152 | ggtt->base.bind_vma = ggtt_bind_vma; | 3216 | ggtt->base.bind_vma = ggtt_bind_vma; |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 62be77cac5cd..163b564fb87d 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h | |||
@@ -319,6 +319,11 @@ struct i915_address_space { | |||
319 | uint64_t start, | 319 | uint64_t start, |
320 | uint64_t length, | 320 | uint64_t length, |
321 | bool use_scratch); | 321 | bool use_scratch); |
322 | void (*insert_page)(struct i915_address_space *vm, | ||
323 | dma_addr_t addr, | ||
324 | uint64_t offset, | ||
325 | enum i915_cache_level cache_level, | ||
326 | u32 flags); | ||
322 | void (*insert_entries)(struct i915_address_space *vm, | 327 | void (*insert_entries)(struct i915_address_space *vm, |
323 | struct sg_table *st, | 328 | struct sg_table *st, |
324 | uint64_t start, | 329 | uint64_t start, |
diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index 9e9bddaa58a5..f49edecd66a3 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h | |||
@@ -13,6 +13,9 @@ void intel_gmch_remove(void); | |||
13 | bool intel_enable_gtt(void); | 13 | bool intel_enable_gtt(void); |
14 | 14 | ||
15 | void intel_gtt_chipset_flush(void); | 15 | void intel_gtt_chipset_flush(void); |
16 | void intel_gtt_insert_page(dma_addr_t addr, | ||
17 | unsigned int pg, | ||
18 | unsigned int flags); | ||
16 | void intel_gtt_insert_sg_entries(struct sg_table *st, | 19 | void intel_gtt_insert_sg_entries(struct sg_table *st, |
17 | unsigned int pg_start, | 20 | unsigned int pg_start, |
18 | unsigned int flags); | 21 | unsigned int flags); |