aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vgem/vgem_drv.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-07-11 09:08:07 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2016-07-12 06:44:25 -0400
commite6f15b763ab2bc47000ec302123e2fb3bf2ad7d4 (patch)
tree3812c1881dd040f56675d3674e8b9a3ab4bec9a0 /drivers/gpu/drm/vgem/vgem_drv.c
parent5ba6c9ff961a79809ec0daf2713e8d39e3f77199 (diff)
drm/vgem: Enable dmabuf interface for export
Enable the standard GEM dma-buf interface provided by the DRM core, but only for exporting the VGEM object. This allows passing around the VGEM objects created from the dumb interface and using them as sources elsewhere. Creating a VGEM object for a foriegn handle is not supported. v2: With additional completeness. v3: Need to clear the CPU cache upon exporting the dma-addresses. v4: Use drm_gem_put_pages() as well. v5: Use drm_prime_pages_to_sg() Testcase: igt/vgem_basic/dmabuf-* Testcase: igt/prime_vgem Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Sean Paul <seanpaul@chromium.org> Cc: Zach Reizner <zachr@google.com> Acked-by: Zach Reizner <zachr@google.com> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1468242488-1505-3-git-send-email-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/vgem/vgem_drv.c')
-rw-r--r--drivers/gpu/drm/vgem/vgem_drv.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index c161b6d7e427..b5fb968d2d5c 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -192,14 +192,101 @@ static const struct file_operations vgem_driver_fops = {
192 .release = drm_release, 192 .release = drm_release,
193}; 193};
194 194
195static int vgem_prime_pin(struct drm_gem_object *obj)
196{
197 long n_pages = obj->size >> PAGE_SHIFT;
198 struct page **pages;
199
200 /* Flush the object from the CPU cache so that importers can rely
201 * on coherent indirect access via the exported dma-address.
202 */
203 pages = drm_gem_get_pages(obj);
204 if (IS_ERR(pages))
205 return PTR_ERR(pages);
206
207 drm_clflush_pages(pages, n_pages);
208 drm_gem_put_pages(obj, pages, true, false);
209
210 return 0;
211}
212
213static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj)
214{
215 struct sg_table *st;
216 struct page **pages;
217
218 pages = drm_gem_get_pages(obj);
219 if (IS_ERR(pages))
220 return ERR_CAST(pages);
221
222 st = drm_prime_pages_to_sg(pages, obj->size >> PAGE_SHIFT);
223 drm_gem_put_pages(obj, pages, false, false);
224
225 return st;
226}
227
228static void *vgem_prime_vmap(struct drm_gem_object *obj)
229{
230 long n_pages = obj->size >> PAGE_SHIFT;
231 struct page **pages;
232 void *addr;
233
234 pages = drm_gem_get_pages(obj);
235 if (IS_ERR(pages))
236 return NULL;
237
238 addr = vmap(pages, n_pages, 0, pgprot_writecombine(PAGE_KERNEL_IO));
239 drm_gem_put_pages(obj, pages, false, false);
240
241 return addr;
242}
243
244static void vgem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
245{
246 vunmap(vaddr);
247}
248
249static int vgem_prime_mmap(struct drm_gem_object *obj,
250 struct vm_area_struct *vma)
251{
252 int ret;
253
254 if (obj->size < vma->vm_end - vma->vm_start)
255 return -EINVAL;
256
257 if (!obj->filp)
258 return -ENODEV;
259
260 ret = obj->filp->f_op->mmap(obj->filp, vma);
261 if (ret)
262 return ret;
263
264 fput(vma->vm_file);
265 vma->vm_file = get_file(obj->filp);
266 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
267 vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
268
269 return 0;
270}
271
195static struct drm_driver vgem_driver = { 272static struct drm_driver vgem_driver = {
196 .driver_features = DRIVER_GEM, 273 .driver_features = DRIVER_GEM | DRIVER_PRIME,
197 .gem_free_object_unlocked = vgem_gem_free_object, 274 .gem_free_object_unlocked = vgem_gem_free_object,
198 .gem_vm_ops = &vgem_gem_vm_ops, 275 .gem_vm_ops = &vgem_gem_vm_ops,
199 .ioctls = vgem_ioctls, 276 .ioctls = vgem_ioctls,
200 .fops = &vgem_driver_fops, 277 .fops = &vgem_driver_fops,
278
201 .dumb_create = vgem_gem_dumb_create, 279 .dumb_create = vgem_gem_dumb_create,
202 .dumb_map_offset = vgem_gem_dumb_map, 280 .dumb_map_offset = vgem_gem_dumb_map,
281
282 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
283 .gem_prime_pin = vgem_prime_pin,
284 .gem_prime_export = drm_gem_prime_export,
285 .gem_prime_get_sg_table = vgem_prime_get_sg_table,
286 .gem_prime_vmap = vgem_prime_vmap,
287 .gem_prime_vunmap = vgem_prime_vunmap,
288 .gem_prime_mmap = vgem_prime_mmap,
289
203 .name = DRIVER_NAME, 290 .name = DRIVER_NAME,
204 .desc = DRIVER_DESC, 291 .desc = DRIVER_DESC,
205 .date = DRIVER_DATE, 292 .date = DRIVER_DATE,