diff options
-rw-r--r-- | drivers/gpu/drm/radeon/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_blit_kms.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_blit_kms.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_benchmark.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_drv.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_object.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_prime.c | 176 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_sa.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_test.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ttm.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 6 |
17 files changed, 232 insertions, 25 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 1efb6eba3c25..a6598fd66423 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -72,7 +72,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
72 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ | 72 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ |
73 | evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \ | 73 | evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \ |
74 | atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ | 74 | atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ |
75 | si_blit_shaders.o | 75 | si_blit_shaders.o radeon_prime.o |
76 | 76 | ||
77 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 77 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
78 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o | 78 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 30f04800b38b..1e96bd458cfd 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
@@ -668,7 +668,7 @@ int evergreen_blit_init(struct radeon_device *rdev) | |||
668 | obj_size = ALIGN(obj_size, 256); | 668 | obj_size = ALIGN(obj_size, 256); |
669 | 669 | ||
670 | r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 670 | r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
671 | &rdev->r600_blit.shader_obj); | 671 | NULL, &rdev->r600_blit.shader_obj); |
672 | if (r) { | 672 | if (r) { |
673 | DRM_ERROR("evergreen failed to allocate shader\n"); | 673 | DRM_ERROR("evergreen failed to allocate shader\n"); |
674 | return r; | 674 | return r; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index ab5d6f2a06c2..f388a1d73b63 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1231,7 +1231,7 @@ int r600_vram_scratch_init(struct radeon_device *rdev) | |||
1231 | if (rdev->vram_scratch.robj == NULL) { | 1231 | if (rdev->vram_scratch.robj == NULL) { |
1232 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, | 1232 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, |
1233 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 1233 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
1234 | &rdev->vram_scratch.robj); | 1234 | NULL, &rdev->vram_scratch.robj); |
1235 | if (r) { | 1235 | if (r) { |
1236 | return r; | 1236 | return r; |
1237 | } | 1237 | } |
@@ -2769,7 +2769,7 @@ int r600_ih_ring_alloc(struct radeon_device *rdev) | |||
2769 | r = radeon_bo_create(rdev, rdev->ih.ring_size, | 2769 | r = radeon_bo_create(rdev, rdev->ih.ring_size, |
2770 | PAGE_SIZE, true, | 2770 | PAGE_SIZE, true, |
2771 | RADEON_GEM_DOMAIN_GTT, | 2771 | RADEON_GEM_DOMAIN_GTT, |
2772 | &rdev->ih.ring_obj); | 2772 | NULL, &rdev->ih.ring_obj); |
2773 | if (r) { | 2773 | if (r) { |
2774 | DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r); | 2774 | DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r); |
2775 | return r; | 2775 | return r; |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index ef20822a1586..03b6e0d3d503 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -552,7 +552,7 @@ int r600_blit_init(struct radeon_device *rdev) | |||
552 | obj_size = ALIGN(obj_size, 256); | 552 | obj_size = ALIGN(obj_size, 256); |
553 | 553 | ||
554 | r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 554 | r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
555 | &rdev->r600_blit.shader_obj); | 555 | NULL, &rdev->r600_blit.shader_obj); |
556 | if (r) { | 556 | if (r) { |
557 | DRM_ERROR("r600 failed to allocate shader\n"); | 557 | DRM_ERROR("r600 failed to allocate shader\n"); |
558 | return r; | 558 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index fef7b722b05d..364f5b1a04b9 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -103,7 +103,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, | |||
103 | int time; | 103 | int time; |
104 | 104 | ||
105 | n = RADEON_BENCHMARK_ITERATIONS; | 105 | n = RADEON_BENCHMARK_ITERATIONS; |
106 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, &sobj); | 106 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, NULL, &sobj); |
107 | if (r) { | 107 | if (r) { |
108 | goto out_cleanup; | 108 | goto out_cleanup; |
109 | } | 109 | } |
@@ -115,7 +115,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, | |||
115 | if (r) { | 115 | if (r) { |
116 | goto out_cleanup; | 116 | goto out_cleanup; |
117 | } | 117 | } |
118 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, &dobj); | 118 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, NULL, &dobj); |
119 | if (r) { | 119 | if (r) { |
120 | goto out_cleanup; | 120 | goto out_cleanup; |
121 | } | 121 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 57637017eed6..066c98b888a5 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -193,7 +193,7 @@ int radeon_wb_init(struct radeon_device *rdev) | |||
193 | 193 | ||
194 | if (rdev->wb.wb_obj == NULL) { | 194 | if (rdev->wb.wb_obj == NULL) { |
195 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, | 195 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, |
196 | RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj); | 196 | RADEON_GEM_DOMAIN_GTT, NULL, &rdev->wb.wb_obj); |
197 | if (r) { | 197 | if (r) { |
198 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); | 198 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); |
199 | return r; | 199 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index e62e56a57ee4..f0bb2b543b13 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -105,6 +105,11 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, | |||
105 | int radeon_mode_dumb_destroy(struct drm_file *file_priv, | 105 | int radeon_mode_dumb_destroy(struct drm_file *file_priv, |
106 | struct drm_device *dev, | 106 | struct drm_device *dev, |
107 | uint32_t handle); | 107 | uint32_t handle); |
108 | struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, | ||
109 | struct drm_gem_object *obj, | ||
110 | int flags); | ||
111 | struct drm_gem_object *radeon_gem_prime_import(struct drm_device *dev, | ||
112 | struct dma_buf *dma_buf); | ||
108 | 113 | ||
109 | #if defined(CONFIG_DEBUG_FS) | 114 | #if defined(CONFIG_DEBUG_FS) |
110 | int radeon_debugfs_init(struct drm_minor *minor); | 115 | int radeon_debugfs_init(struct drm_minor *minor); |
@@ -333,7 +338,8 @@ static const struct file_operations radeon_driver_kms_fops = { | |||
333 | static struct drm_driver kms_driver = { | 338 | static struct drm_driver kms_driver = { |
334 | .driver_features = | 339 | .driver_features = |
335 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | | 340 | DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG | |
336 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_GEM, | 341 | DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED | DRIVER_GEM | |
342 | DRIVER_PRIME, | ||
337 | .dev_priv_size = 0, | 343 | .dev_priv_size = 0, |
338 | .load = radeon_driver_load_kms, | 344 | .load = radeon_driver_load_kms, |
339 | .firstopen = radeon_driver_firstopen_kms, | 345 | .firstopen = radeon_driver_firstopen_kms, |
@@ -368,6 +374,12 @@ static struct drm_driver kms_driver = { | |||
368 | .dumb_map_offset = radeon_mode_dumb_mmap, | 374 | .dumb_map_offset = radeon_mode_dumb_mmap, |
369 | .dumb_destroy = radeon_mode_dumb_destroy, | 375 | .dumb_destroy = radeon_mode_dumb_destroy, |
370 | .fops = &radeon_driver_kms_fops, | 376 | .fops = &radeon_driver_kms_fops, |
377 | |||
378 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, | ||
379 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, | ||
380 | .gem_prime_export = radeon_gem_prime_export, | ||
381 | .gem_prime_import = radeon_gem_prime_import, | ||
382 | |||
371 | .name = DRIVER_NAME, | 383 | .name = DRIVER_NAME, |
372 | .desc = DRIVER_DESC, | 384 | .desc = DRIVER_DESC, |
373 | .date = DRIVER_DATE, | 385 | .date = DRIVER_DATE, |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 8e9ef3403acd..4fa540273f15 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -80,7 +80,7 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) | |||
80 | if (rdev->gart.robj == NULL) { | 80 | if (rdev->gart.robj == NULL) { |
81 | r = radeon_bo_create(rdev, rdev->gart.table_size, | 81 | r = radeon_bo_create(rdev, rdev->gart.table_size, |
82 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 82 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
83 | &rdev->gart.robj); | 83 | NULL, &rdev->gart.robj); |
84 | if (r) { | 84 | if (r) { |
85 | return r; | 85 | return r; |
86 | } | 86 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index e15cb1fe2c39..c0130b052e3e 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -42,6 +42,8 @@ void radeon_gem_object_free(struct drm_gem_object *gobj) | |||
42 | struct radeon_bo *robj = gem_to_radeon_bo(gobj); | 42 | struct radeon_bo *robj = gem_to_radeon_bo(gobj); |
43 | 43 | ||
44 | if (robj) { | 44 | if (robj) { |
45 | if (robj->gem_base.import_attach) | ||
46 | drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg); | ||
45 | radeon_bo_unref(&robj); | 47 | radeon_bo_unref(&robj); |
46 | } | 48 | } |
47 | } | 49 | } |
@@ -59,7 +61,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, | |||
59 | if (alignment < PAGE_SIZE) { | 61 | if (alignment < PAGE_SIZE) { |
60 | alignment = PAGE_SIZE; | 62 | alignment = PAGE_SIZE; |
61 | } | 63 | } |
62 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, &robj); | 64 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj); |
63 | if (r) { | 65 | if (r) { |
64 | if (r != -ERESTARTSYS) | 66 | if (r != -ERESTARTSYS) |
65 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", | 67 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1affbc954c56..830f1a7b486f 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -104,7 +104,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
104 | 104 | ||
105 | int radeon_bo_create(struct radeon_device *rdev, | 105 | int radeon_bo_create(struct radeon_device *rdev, |
106 | unsigned long size, int byte_align, bool kernel, u32 domain, | 106 | unsigned long size, int byte_align, bool kernel, u32 domain, |
107 | struct radeon_bo **bo_ptr) | 107 | struct sg_table *sg, struct radeon_bo **bo_ptr) |
108 | { | 108 | { |
109 | struct radeon_bo *bo; | 109 | struct radeon_bo *bo; |
110 | enum ttm_bo_type type; | 110 | enum ttm_bo_type type; |
@@ -120,6 +120,8 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
120 | } | 120 | } |
121 | if (kernel) { | 121 | if (kernel) { |
122 | type = ttm_bo_type_kernel; | 122 | type = ttm_bo_type_kernel; |
123 | } else if (sg) { | ||
124 | type = ttm_bo_type_sg; | ||
123 | } else { | 125 | } else { |
124 | type = ttm_bo_type_device; | 126 | type = ttm_bo_type_device; |
125 | } | 127 | } |
@@ -155,7 +157,7 @@ retry: | |||
155 | mutex_lock(&rdev->vram_mutex); | 157 | mutex_lock(&rdev->vram_mutex); |
156 | r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, | 158 | r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, |
157 | &bo->placement, page_align, 0, !kernel, NULL, | 159 | &bo->placement, page_align, 0, !kernel, NULL, |
158 | acc_size, NULL, &radeon_ttm_bo_destroy); | 160 | acc_size, sg, &radeon_ttm_bo_destroy); |
159 | mutex_unlock(&rdev->vram_mutex); | 161 | mutex_unlock(&rdev->vram_mutex); |
160 | if (unlikely(r != 0)) { | 162 | if (unlikely(r != 0)) { |
161 | if (r != -ERESTARTSYS) { | 163 | if (r != -ERESTARTSYS) { |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index befec7d12132..17fb99f177cf 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -111,9 +111,10 @@ extern int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, | |||
111 | bool no_wait); | 111 | bool no_wait); |
112 | 112 | ||
113 | extern int radeon_bo_create(struct radeon_device *rdev, | 113 | extern int radeon_bo_create(struct radeon_device *rdev, |
114 | unsigned long size, int byte_align, | 114 | unsigned long size, int byte_align, |
115 | bool kernel, u32 domain, | 115 | bool kernel, u32 domain, |
116 | struct radeon_bo **bo_ptr); | 116 | struct sg_table *sg, |
117 | struct radeon_bo **bo_ptr); | ||
117 | extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); | 118 | extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); |
118 | extern void radeon_bo_kunmap(struct radeon_bo *bo); | 119 | extern void radeon_bo_kunmap(struct radeon_bo *bo); |
119 | extern void radeon_bo_unref(struct radeon_bo **bo); | 120 | extern void radeon_bo_unref(struct radeon_bo **bo); |
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c new file mode 100644 index 000000000000..24f51753c9aa --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_prime.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * based on nouveau_prime.c | ||
23 | * | ||
24 | * Authors: Alex Deucher | ||
25 | */ | ||
26 | #include "drmP.h" | ||
27 | #include "drm.h" | ||
28 | |||
29 | #include "radeon.h" | ||
30 | #include "radeon_drm.h" | ||
31 | |||
32 | #include <linux/dma-buf.h> | ||
33 | |||
34 | static struct sg_table *radeon_gem_map_dma_buf(struct dma_buf_attachment *attachment, | ||
35 | enum dma_data_direction dir) | ||
36 | { | ||
37 | struct radeon_bo *bo = attachment->dmabuf->priv; | ||
38 | struct drm_device *dev = bo->rdev->ddev; | ||
39 | int npages = bo->tbo.num_pages; | ||
40 | struct sg_table *sg; | ||
41 | int nents; | ||
42 | |||
43 | mutex_lock(&dev->struct_mutex); | ||
44 | sg = drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages); | ||
45 | nents = dma_map_sg(attachment->dev, sg->sgl, sg->nents, dir); | ||
46 | mutex_unlock(&dev->struct_mutex); | ||
47 | return sg; | ||
48 | } | ||
49 | |||
50 | static void radeon_gem_unmap_dma_buf(struct dma_buf_attachment *attachment, | ||
51 | struct sg_table *sg, enum dma_data_direction dir) | ||
52 | { | ||
53 | dma_unmap_sg(attachment->dev, sg->sgl, sg->nents, dir); | ||
54 | sg_free_table(sg); | ||
55 | kfree(sg); | ||
56 | } | ||
57 | |||
58 | static void radeon_gem_dmabuf_release(struct dma_buf *dma_buf) | ||
59 | { | ||
60 | struct radeon_bo *bo = dma_buf->priv; | ||
61 | |||
62 | if (bo->gem_base.export_dma_buf == dma_buf) { | ||
63 | DRM_ERROR("unreference dmabuf %p\n", &bo->gem_base); | ||
64 | bo->gem_base.export_dma_buf = NULL; | ||
65 | drm_gem_object_unreference_unlocked(&bo->gem_base); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | static void *radeon_gem_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num) | ||
70 | { | ||
71 | return NULL; | ||
72 | } | ||
73 | |||
74 | static void radeon_gem_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr) | ||
75 | { | ||
76 | |||
77 | } | ||
78 | static void *radeon_gem_kmap(struct dma_buf *dma_buf, unsigned long page_num) | ||
79 | { | ||
80 | return NULL; | ||
81 | } | ||
82 | |||
83 | static void radeon_gem_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr) | ||
84 | { | ||
85 | |||
86 | } | ||
87 | |||
88 | struct dma_buf_ops radeon_dmabuf_ops = { | ||
89 | .map_dma_buf = radeon_gem_map_dma_buf, | ||
90 | .unmap_dma_buf = radeon_gem_unmap_dma_buf, | ||
91 | .release = radeon_gem_dmabuf_release, | ||
92 | .kmap = radeon_gem_kmap, | ||
93 | .kmap_atomic = radeon_gem_kmap_atomic, | ||
94 | .kunmap = radeon_gem_kunmap, | ||
95 | .kunmap_atomic = radeon_gem_kunmap_atomic, | ||
96 | }; | ||
97 | |||
98 | static int radeon_prime_create(struct drm_device *dev, | ||
99 | size_t size, | ||
100 | struct sg_table *sg, | ||
101 | struct radeon_bo **pbo) | ||
102 | { | ||
103 | struct radeon_device *rdev = dev->dev_private; | ||
104 | struct radeon_bo *bo; | ||
105 | int ret; | ||
106 | |||
107 | ret = radeon_bo_create(rdev, size, PAGE_SIZE, false, | ||
108 | RADEON_GEM_DOMAIN_GTT, sg, pbo); | ||
109 | if (ret) | ||
110 | return ret; | ||
111 | bo = *pbo; | ||
112 | bo->gem_base.driver_private = bo; | ||
113 | |||
114 | mutex_lock(&rdev->gem.mutex); | ||
115 | list_add_tail(&bo->list, &rdev->gem.objects); | ||
116 | mutex_unlock(&rdev->gem.mutex); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, | ||
122 | struct drm_gem_object *obj, | ||
123 | int flags) | ||
124 | { | ||
125 | struct radeon_bo *bo = gem_to_radeon_bo(obj); | ||
126 | int ret = 0; | ||
127 | |||
128 | /* pin buffer into GTT */ | ||
129 | ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); | ||
130 | if (ret) | ||
131 | return ERR_PTR(ret); | ||
132 | |||
133 | return dma_buf_export(bo, &radeon_dmabuf_ops, obj->size, flags); | ||
134 | } | ||
135 | |||
136 | struct drm_gem_object *radeon_gem_prime_import(struct drm_device *dev, | ||
137 | struct dma_buf *dma_buf) | ||
138 | { | ||
139 | struct dma_buf_attachment *attach; | ||
140 | struct sg_table *sg; | ||
141 | struct radeon_bo *bo; | ||
142 | int ret; | ||
143 | |||
144 | if (dma_buf->ops == &radeon_dmabuf_ops) { | ||
145 | bo = dma_buf->priv; | ||
146 | if (bo->gem_base.dev == dev) { | ||
147 | drm_gem_object_reference(&bo->gem_base); | ||
148 | return &bo->gem_base; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | /* need to attach */ | ||
153 | attach = dma_buf_attach(dma_buf, dev->dev); | ||
154 | if (IS_ERR(attach)) | ||
155 | return ERR_CAST(attach); | ||
156 | |||
157 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); | ||
158 | if (IS_ERR(sg)) { | ||
159 | ret = PTR_ERR(sg); | ||
160 | goto fail_detach; | ||
161 | } | ||
162 | |||
163 | ret = radeon_prime_create(dev, dma_buf->size, sg, &bo); | ||
164 | if (ret) | ||
165 | goto fail_unmap; | ||
166 | |||
167 | bo->gem_base.import_attach = attach; | ||
168 | |||
169 | return &bo->gem_base; | ||
170 | |||
171 | fail_unmap: | ||
172 | dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL); | ||
173 | fail_detach: | ||
174 | dma_buf_detach(dma_buf, attach); | ||
175 | return ERR_PTR(ret); | ||
176 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index a5dee76f4ebb..493a7be75306 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -390,8 +390,8 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig | |||
390 | /* Allocate ring buffer */ | 390 | /* Allocate ring buffer */ |
391 | if (ring->ring_obj == NULL) { | 391 | if (ring->ring_obj == NULL) { |
392 | r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, | 392 | r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, |
393 | RADEON_GEM_DOMAIN_GTT, | 393 | RADEON_GEM_DOMAIN_GTT, |
394 | &ring->ring_obj); | 394 | NULL, &ring->ring_obj); |
395 | if (r) { | 395 | if (r) { |
396 | dev_err(rdev->dev, "(%d) ring create failed\n", r); | 396 | dev_err(rdev->dev, "(%d) ring create failed\n", r); |
397 | return r; | 397 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c index c3ac7f4c7b70..32059b745728 100644 --- a/drivers/gpu/drm/radeon/radeon_sa.c +++ b/drivers/gpu/drm/radeon/radeon_sa.c | |||
@@ -65,7 +65,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev, | |||
65 | } | 65 | } |
66 | 66 | ||
67 | r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true, | 67 | r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true, |
68 | RADEON_GEM_DOMAIN_CPU, &sa_manager->bo); | 68 | RADEON_GEM_DOMAIN_CPU, NULL, &sa_manager->bo); |
69 | if (r) { | 69 | if (r) { |
70 | dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r); | 70 | dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r); |
71 | return r; | 71 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index b05738762790..efff929ea49d 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -59,7 +59,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
59 | } | 59 | } |
60 | 60 | ||
61 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 61 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
62 | &vram_obj); | 62 | NULL, &vram_obj); |
63 | if (r) { | 63 | if (r) { |
64 | DRM_ERROR("Failed to create VRAM object\n"); | 64 | DRM_ERROR("Failed to create VRAM object\n"); |
65 | goto out_cleanup; | 65 | goto out_cleanup; |
@@ -78,7 +78,7 @@ void radeon_test_moves(struct radeon_device *rdev) | |||
78 | void **vram_start, **vram_end; | 78 | void **vram_start, **vram_end; |
79 | 79 | ||
80 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, | 80 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, |
81 | RADEON_GEM_DOMAIN_GTT, gtt_obj + i); | 81 | RADEON_GEM_DOMAIN_GTT, NULL, gtt_obj + i); |
82 | if (r) { | 82 | if (r) { |
83 | DRM_ERROR("Failed to create GTT object %d\n", i); | 83 | DRM_ERROR("Failed to create GTT object %d\n", i); |
84 | goto out_cleanup; | 84 | goto out_cleanup; |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 0f6aee8aa152..c94a2257761f 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -611,10 +611,18 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm) | |||
611 | struct radeon_ttm_tt *gtt = (void *)ttm; | 611 | struct radeon_ttm_tt *gtt = (void *)ttm; |
612 | unsigned i; | 612 | unsigned i; |
613 | int r; | 613 | int r; |
614 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); | ||
614 | 615 | ||
615 | if (ttm->state != tt_unpopulated) | 616 | if (ttm->state != tt_unpopulated) |
616 | return 0; | 617 | return 0; |
617 | 618 | ||
619 | if (slave && ttm->sg) { | ||
620 | drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, | ||
621 | gtt->ttm.dma_address, ttm->num_pages); | ||
622 | ttm->state = tt_unbound; | ||
623 | return 0; | ||
624 | } | ||
625 | |||
618 | rdev = radeon_get_rdev(ttm->bdev); | 626 | rdev = radeon_get_rdev(ttm->bdev); |
619 | #if __OS_HAS_AGP | 627 | #if __OS_HAS_AGP |
620 | if (rdev->flags & RADEON_IS_AGP) { | 628 | if (rdev->flags & RADEON_IS_AGP) { |
@@ -655,6 +663,10 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm) | |||
655 | struct radeon_device *rdev; | 663 | struct radeon_device *rdev; |
656 | struct radeon_ttm_tt *gtt = (void *)ttm; | 664 | struct radeon_ttm_tt *gtt = (void *)ttm; |
657 | unsigned i; | 665 | unsigned i; |
666 | bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); | ||
667 | |||
668 | if (slave) | ||
669 | return; | ||
658 | 670 | ||
659 | rdev = radeon_get_rdev(ttm->bdev); | 671 | rdev = radeon_get_rdev(ttm->bdev); |
660 | #if __OS_HAS_AGP | 672 | #if __OS_HAS_AGP |
@@ -726,8 +738,8 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
726 | return r; | 738 | return r; |
727 | } | 739 | } |
728 | r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true, | 740 | r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true, |
729 | RADEON_GEM_DOMAIN_VRAM, | 741 | RADEON_GEM_DOMAIN_VRAM, |
730 | &rdev->stollen_vga_memory); | 742 | NULL, &rdev->stollen_vga_memory); |
731 | if (r) { | 743 | if (r) { |
732 | return r; | 744 | return r; |
733 | } | 745 | } |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 63ae41dac5ca..549732e56ca9 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -2976,7 +2976,8 @@ int si_rlc_init(struct radeon_device *rdev) | |||
2976 | /* save restore block */ | 2976 | /* save restore block */ |
2977 | if (rdev->rlc.save_restore_obj == NULL) { | 2977 | if (rdev->rlc.save_restore_obj == NULL) { |
2978 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, | 2978 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, |
2979 | RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.save_restore_obj); | 2979 | RADEON_GEM_DOMAIN_VRAM, NULL, |
2980 | &rdev->rlc.save_restore_obj); | ||
2980 | if (r) { | 2981 | if (r) { |
2981 | dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r); | 2982 | dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r); |
2982 | return r; | 2983 | return r; |
@@ -3000,7 +3001,8 @@ int si_rlc_init(struct radeon_device *rdev) | |||
3000 | /* clear state block */ | 3001 | /* clear state block */ |
3001 | if (rdev->rlc.clear_state_obj == NULL) { | 3002 | if (rdev->rlc.clear_state_obj == NULL) { |
3002 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, | 3003 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, |
3003 | RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.clear_state_obj); | 3004 | RADEON_GEM_DOMAIN_VRAM, NULL, |
3005 | &rdev->rlc.clear_state_obj); | ||
3004 | if (r) { | 3006 | if (r) { |
3005 | dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r); | 3007 | dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r); |
3006 | si_rlc_fini(rdev); | 3008 | si_rlc_fini(rdev); |