aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 21:01:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 21:01:18 -0400
commit9fdadb2cbaf4b482dfd6086e8bd3d2db071a1702 (patch)
tree4a6e11e3379ee93c1992cfd595872dded1fd2fac
parent76f901eb4659779ecacd0e4eba49f55442daef53 (diff)
parent63bc620b45af8c743ac291c8725933278c712692 (diff)
Merge branch 'drm-prime-vmap' of git://people.freedesktop.org/~airlied/linux
Pull drm prime mmap/vmap code from Dave Airlie: "As mentioned previously these are the extra bits of drm that relied on the dma-buf pull to work, the first three just stub out the mmap interface, and the next set provide vmap export to i915/radeon/nouveau and vmap import to udl." * 'drm-prime-vmap' of git://people.freedesktop.org/~airlied/linux: radeon: add radeon prime vmap support. nouveau: add vmap support to nouveau prime support udl: support vmapping imported dma-bufs i915: add dma-buf vmap support for exporting vmapped buffer radeon: add stub dma-buf mmap functionality nouveau: add stub dma-buf mmap functionality. i915: add stub dma-buf mmap callback.
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_dmabuf.c61
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_prime.c45
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_prime.c44
-rw-r--r--drivers/gpu/drm/udl/udl_fb.c13
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c25
8 files changed, 192 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 377c21f531e4..c9cfc67c2cf5 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -942,6 +942,9 @@ struct drm_i915_gem_object {
942 942
943 /* prime dma-buf support */ 943 /* prime dma-buf support */
944 struct sg_table *sg_table; 944 struct sg_table *sg_table;
945 void *dma_buf_vmapping;
946 int vmapping_count;
947
945 /** 948 /**
946 * Used for performing relocations during execbuffer insertion. 949 * Used for performing relocations during execbuffer insertion.
947 */ 950 */
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index 8e269178d6a5..aa308e1337db 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -74,6 +74,59 @@ static void i915_gem_dmabuf_release(struct dma_buf *dma_buf)
74 } 74 }
75} 75}
76 76
77static void *i915_gem_dmabuf_vmap(struct dma_buf *dma_buf)
78{
79 struct drm_i915_gem_object *obj = dma_buf->priv;
80 struct drm_device *dev = obj->base.dev;
81 int ret;
82
83 ret = i915_mutex_lock_interruptible(dev);
84 if (ret)
85 return ERR_PTR(ret);
86
87 if (obj->dma_buf_vmapping) {
88 obj->vmapping_count++;
89 goto out_unlock;
90 }
91
92 if (!obj->pages) {
93 ret = i915_gem_object_get_pages_gtt(obj, __GFP_NORETRY | __GFP_NOWARN);
94 if (ret) {
95 mutex_unlock(&dev->struct_mutex);
96 return ERR_PTR(ret);
97 }
98 }
99
100 obj->dma_buf_vmapping = vmap(obj->pages, obj->base.size / PAGE_SIZE, 0, PAGE_KERNEL);
101 if (!obj->dma_buf_vmapping) {
102 DRM_ERROR("failed to vmap object\n");
103 goto out_unlock;
104 }
105
106 obj->vmapping_count = 1;
107out_unlock:
108 mutex_unlock(&dev->struct_mutex);
109 return obj->dma_buf_vmapping;
110}
111
112static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
113{
114 struct drm_i915_gem_object *obj = dma_buf->priv;
115 struct drm_device *dev = obj->base.dev;
116 int ret;
117
118 ret = i915_mutex_lock_interruptible(dev);
119 if (ret)
120 return;
121
122 --obj->vmapping_count;
123 if (obj->vmapping_count == 0) {
124 vunmap(obj->dma_buf_vmapping);
125 obj->dma_buf_vmapping = NULL;
126 }
127 mutex_unlock(&dev->struct_mutex);
128}
129
77static void *i915_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num) 130static void *i915_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, unsigned long page_num)
78{ 131{
79 return NULL; 132 return NULL;
@@ -93,6 +146,11 @@ static void i915_gem_dmabuf_kunmap(struct dma_buf *dma_buf, unsigned long page_n
93 146
94} 147}
95 148
149static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
150{
151 return -EINVAL;
152}
153
96static const struct dma_buf_ops i915_dmabuf_ops = { 154static const struct dma_buf_ops i915_dmabuf_ops = {
97 .map_dma_buf = i915_gem_map_dma_buf, 155 .map_dma_buf = i915_gem_map_dma_buf,
98 .unmap_dma_buf = i915_gem_unmap_dma_buf, 156 .unmap_dma_buf = i915_gem_unmap_dma_buf,
@@ -101,6 +159,9 @@ static const struct dma_buf_ops i915_dmabuf_ops = {
101 .kmap_atomic = i915_gem_dmabuf_kmap_atomic, 159 .kmap_atomic = i915_gem_dmabuf_kmap_atomic,
102 .kunmap = i915_gem_dmabuf_kunmap, 160 .kunmap = i915_gem_dmabuf_kunmap,
103 .kunmap_atomic = i915_gem_dmabuf_kunmap_atomic, 161 .kunmap_atomic = i915_gem_dmabuf_kunmap_atomic,
162 .mmap = i915_gem_dmabuf_mmap,
163 .vmap = i915_gem_dmabuf_vmap,
164 .vunmap = i915_gem_dmabuf_vunmap,
104}; 165};
105 166
106struct dma_buf *i915_gem_prime_export(struct drm_device *dev, 167struct dma_buf *i915_gem_prime_export(struct drm_device *dev,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 634d222c93de..8613cb23808c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -123,6 +123,9 @@ struct nouveau_bo {
123 123
124 struct drm_gem_object *gem; 124 struct drm_gem_object *gem;
125 int pin_refcnt; 125 int pin_refcnt;
126
127 struct ttm_bo_kmap_obj dma_buf_vmap;
128 int vmapping_count;
126}; 129};
127 130
128#define nouveau_bo_tile_layout(nvbo) \ 131#define nouveau_bo_tile_layout(nvbo) \
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
index c58aab7370c5..a89240e5fb29 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -61,6 +61,48 @@ static void nouveau_gem_kunmap(struct dma_buf *dma_buf, unsigned long page_num,
61 61
62} 62}
63 63
64static int nouveau_gem_prime_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
65{
66 return -EINVAL;
67}
68
69static void *nouveau_gem_prime_vmap(struct dma_buf *dma_buf)
70{
71 struct nouveau_bo *nvbo = dma_buf->priv;
72 struct drm_device *dev = nvbo->gem->dev;
73 int ret;
74
75 mutex_lock(&dev->struct_mutex);
76 if (nvbo->vmapping_count) {
77 nvbo->vmapping_count++;
78 goto out_unlock;
79 }
80
81 ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.num_pages,
82 &nvbo->dma_buf_vmap);
83 if (ret) {
84 mutex_unlock(&dev->struct_mutex);
85 return ERR_PTR(ret);
86 }
87 nvbo->vmapping_count = 1;
88out_unlock:
89 mutex_unlock(&dev->struct_mutex);
90 return nvbo->dma_buf_vmap.virtual;
91}
92
93static void nouveau_gem_prime_vunmap(struct dma_buf *dma_buf, void *vaddr)
94{
95 struct nouveau_bo *nvbo = dma_buf->priv;
96 struct drm_device *dev = nvbo->gem->dev;
97
98 mutex_lock(&dev->struct_mutex);
99 nvbo->vmapping_count--;
100 if (nvbo->vmapping_count == 0) {
101 ttm_bo_kunmap(&nvbo->dma_buf_vmap);
102 }
103 mutex_unlock(&dev->struct_mutex);
104}
105
64static const struct dma_buf_ops nouveau_dmabuf_ops = { 106static const struct dma_buf_ops nouveau_dmabuf_ops = {
65 .map_dma_buf = nouveau_gem_map_dma_buf, 107 .map_dma_buf = nouveau_gem_map_dma_buf,
66 .unmap_dma_buf = nouveau_gem_unmap_dma_buf, 108 .unmap_dma_buf = nouveau_gem_unmap_dma_buf,
@@ -69,6 +111,9 @@ static const struct dma_buf_ops nouveau_dmabuf_ops = {
69 .kmap_atomic =