aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-05-10 18:33:13 -0400
committerDave Airlie <airlied@redhat.com>2012-05-23 05:47:11 -0400
commit40f5cf996991577ec65d36cd3599cca7ec5d87d3 (patch)
tree903797b4e09b9444450fb35b4101c1fd9b8530b0 /drivers
parent1286ff7397737e407cdd8e5cd574318db177ba1f (diff)
drm/radeon: add PRIME support (v2)
This adds prime->fd and fd->prime support to radeon. It passes the sg object to ttm and then populates the gart entries using it. Compile tested only. v2: stub kmap + use new helpers + add reimporting Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/evergreen_blit_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/r600.c4
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_benchmark.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.h7
-rw-r--r--drivers/gpu/drm/radeon/radeon_prime.c176
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_sa.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_test.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c16
-rw-r--r--drivers/gpu/drm/radeon/si.c6
17 files changed, 232 insertions, 25 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index 1efb6eba3c2..a6598fd6642 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
77radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 77radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
78radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o 78radeon-$(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 30f04800b38..1e96bd458cf 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 ab5d6f2a06c..f388a1d73b6 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 ef20822a158..03b6e0d3d50 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 fef7b722b05..364f5b1a04b 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 57637017eed..066c98b888a 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 e62e56a57ee..f0bb2b543b1 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,
105int radeon_mode_dumb_destroy(struct drm_file *file_priv, 105int 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);
108struct dma_buf *radeon_gem_prime_export(struct drm_device *dev,
109 struct drm_gem_object *obj,
110 int flags);
111struct 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)
110int radeon_debugfs_init(struct drm_minor *minor); 115int radeon_debugfs_init(struct drm_minor *minor);
@@ -333,7 +338,8 @@ static const struct file_operations radeon_driver_kms_fops = {
333static struct drm_driver kms_driver = { 338static 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 8e9ef3403ac..4fa540273f1 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 e15cb1fe2c3..c0130b052e3 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 1affbc954c5..830f1a7b486 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
105int radeon_bo_create(struct radeon_device *rdev, 105int 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 befec7d1213..17fb99f177c 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
113extern int radeon_bo_create(struct radeon_device *rdev, 113extern 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);
117extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); 118extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr);
118extern void radeon_bo_kunmap(struct radeon_bo *bo); 119extern void radeon_bo_kunmap(struct radeon_bo *bo);
119extern void radeon_bo_unref(struct radeon_bo **bo); 120extern 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 00000000000..24f51753c9a
--- /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
34static 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
50static 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
58static 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
69static void *radeon_gem_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
70{
71 return NULL;
72}
73
74static void radeon_gem_kunmap_atomic(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
75{
76
77}
78static void *radeon_gem_kmap(struct dma_buf *dma_buf, unsigned long page_num)
79{
80 return NULL;
81}
82
83static void radeon_gem_kunmap(struct dma_buf *dma_buf, unsigned long page_num, void *addr)
84{
85
86}
87
88struct 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
98static 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
121struct 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
136struct 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
171fail_unmap:
172 dma_buf_unmap_attachment(attach, sg, DMA_BIDIRECTIONAL);
173fail_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 a5dee76f4eb..493a7be7530 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 c3ac7f4c7b7..32059b74572 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 b0573876279..efff929ea49 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 0f6aee8aa15..c94a2257761 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 63ae41dac5c..549732e56ca 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);