udl: support vmapping imported dma-bufs
authorDave Airlie <airlied@redhat.com>
Mon, 26 Mar 2012 13:36:56 +0000 (14:36 +0100)
committerDave Airlie <airlied@redhat.com>
Thu, 31 May 2012 13:13:59 +0000 (14:13 +0100)
This allows udl to get a vmapping of an imported buffer for scanout.

Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/udl/udl_fb.c
drivers/gpu/drm/udl/udl_gem.c

index a029ee39b0c526d0e0fe63150acd25ea992f73c0..ce9a61179925cd540f4d4956b991513ca53b27e2 100644 (file)
@@ -156,8 +156,17 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
        if (!fb->active_16)
                return 0;
 
-       if (!fb->obj->vmapping)
-               udl_gem_vmap(fb->obj);
+       if (!fb->obj->vmapping) {
+               ret = udl_gem_vmap(fb->obj);
+               if (ret == -ENOMEM) {
+                       DRM_ERROR("failed to vmap fb\n");
+                       return 0;
+               }
+               if (!fb->obj->vmapping) {
+                       DRM_ERROR("failed to vmapping\n");
+                       return 0;
+               }
+       }
 
        start_cycles = get_cycles();
 
index 97acc9c6c95b074c8b4ec7261e84360b5f93fccf..7bd65bdd15a8092e955d959c08fd6dd04781d490 100644 (file)
@@ -180,6 +180,18 @@ int udl_gem_vmap(struct udl_gem_object *obj)
        int page_count = obj->base.size / PAGE_SIZE;
        int ret;
 
+       if (obj->base.import_attach) {
+               ret = dma_buf_begin_cpu_access(obj->base.import_attach->dmabuf,
+                                              0, obj->base.size, DMA_BIDIRECTIONAL);
+               if (ret)
+                       return -EINVAL;
+
+               obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf);
+               if (!obj->vmapping)
+                       return -ENOMEM;
+               return 0;
+       }
+               
        ret = udl_gem_get_pages(obj, GFP_KERNEL);
        if (ret)
                return ret;
@@ -192,6 +204,13 @@ int udl_gem_vmap(struct udl_gem_object *obj)
 
 void udl_gem_vunmap(struct udl_gem_object *obj)
 {
+       if (obj->base.import_attach) {
+               dma_buf_vunmap(obj->base.import_attach->dmabuf, obj->vmapping);
+               dma_buf_end_cpu_access(obj->base.import_attach->dmabuf, 0,
+                                      obj->base.size, DMA_BIDIRECTIONAL);
+               return;
+       }
+
        if (obj->vmapping)
                vunmap(obj->vmapping);
 
@@ -202,12 +221,12 @@ void udl_gem_free_object(struct drm_gem_object *gem_obj)
 {
        struct udl_gem_object *obj = to_udl_bo(gem_obj);
 
-       if (gem_obj->import_attach)
-               drm_prime_gem_destroy(gem_obj, obj->sg);
-
        if (obj->vmapping)
                udl_gem_vunmap(obj);
 
+       if (gem_obj->import_attach)
+               drm_prime_gem_destroy(gem_obj, obj->sg);
+
        if (obj->pages)
                udl_gem_put_pages(obj);