drm/vram: Provide vmap and vunmap operations for GEM VRAM objects
authorThomas Zimmermann <tzimmermann@suse.de>
Wed, 11 Sep 2019 12:03:50 +0000 (14:03 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Tue, 17 Sep 2019 11:09:38 +0000 (13:09 +0200)
The implementation of vmap and vunmap for GEM VRAM helpers is
already in PRIME helpers. The patch moves the operations to separate
functions and exports them for general use.

v3:
* remove v2's obsolete note on ref-counting
v2:
* fix documentation
* add cross references to function documentation
* document (the lack of) ref-counting for GEM VRAM BO mappings

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190911120352.20084-2-tzimmermann@suse.de
drivers/gpu/drm/drm_gem_vram_helper.c
include/drm/drm_gem_vram_helper.h

index 7bee80c6b6e85b819c939ffcf4c8653ffbc0e3bb..49588de889599299839e46d931b388454dd20f6f 100644 (file)
@@ -392,6 +392,77 @@ void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo)
 }
 EXPORT_SYMBOL(drm_gem_vram_kunmap);
 
+/**
+ * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
+ *                       space
+ * @gbo:       The GEM VRAM object to map
+ *
+ * The vmap function pins a GEM VRAM object to its current location, either
+ * system or video memory, and maps its buffer into kernel address space.
+ * As pinned object cannot be relocated, you should avoid pinning objects
+ * permanently. Call drm_gem_vram_vunmap() with the returned address to
+ * unmap and unpin the GEM VRAM object.
+ *
+ * If you have special requirements for the pinning or mapping operations,
+ * call drm_gem_vram_pin() and drm_gem_vram_kmap() directly.
+ *
+ * Returns:
+ * The buffer's virtual address on success, or
+ * an ERR_PTR()-encoded error code otherwise.
+ */
+void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo)
+{
+       int ret;
+       void *base;
+
+       ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
+       if (ret)
+               return ERR_PTR(ret);
+
+       ret = drm_gem_vram_pin_locked(gbo, 0);
+       if (ret)
+               goto err_ttm_bo_unreserve;
+       base = drm_gem_vram_kmap_locked(gbo, true, NULL);
+       if (IS_ERR(base)) {
+               ret = PTR_ERR(base);
+               goto err_drm_gem_vram_unpin_locked;
+       }
+
+       ttm_bo_unreserve(&gbo->bo);
+
+       return base;
+
+err_drm_gem_vram_unpin_locked:
+       drm_gem_vram_unpin_locked(gbo);
+err_ttm_bo_unreserve:
+       ttm_bo_unreserve(&gbo->bo);
+       return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(drm_gem_vram_vmap);
+
+/**
+ * drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
+ * @gbo:       The GEM VRAM object to unmap
+ * @vaddr:     The mapping's base address as returned by drm_gem_vram_vmap()
+ *
+ * A call to drm_gem_vram_vunmap() unmaps and unpins a GEM VRAM buffer. See
+ * the documentation for drm_gem_vram_vmap() for more information.
+ */
+void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, void *vaddr)
+{
+       int ret;
+
+       ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
+       if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
+               return;
+
+       drm_gem_vram_kunmap_locked(gbo);
+       drm_gem_vram_unpin_locked(gbo);
+
+       ttm_bo_unreserve(&gbo->bo);
+}
+EXPORT_SYMBOL(drm_gem_vram_vunmap);
+
 /**
  * drm_gem_vram_fill_create_dumb() - \
        Helper for implementing &struct drm_driver.dumb_create
@@ -622,31 +693,12 @@ static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
 static void *drm_gem_vram_object_vmap(struct drm_gem_object *gem)
 {
        struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
-       int ret;
        void *base;
 
-       ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
-       if (ret)
-               return ERR_PTR(ret);
-
-       ret = drm_gem_vram_pin_locked(gbo, 0);
-       if (ret)
-               goto err_ttm_bo_unreserve;
-       base = drm_gem_vram_kmap_locked(gbo, true, NULL);
-       if (IS_ERR(base)) {
-               ret = PTR_ERR(base);
-               goto err_drm_gem_vram_unpin_locked;
-       }
-
-       ttm_bo_unreserve(&gbo->bo);
-
+       base = drm_gem_vram_vmap(gbo);
+       if (IS_ERR(base))
+               return NULL;
        return base;
-
-err_drm_gem_vram_unpin_locked:
-       drm_gem_vram_unpin_locked(gbo);
-err_ttm_bo_unreserve:
-       ttm_bo_unreserve(&gbo->bo);
-       return ERR_PTR(ret);
 }
 
 /**
@@ -659,16 +711,8 @@ static void drm_gem_vram_object_vunmap(struct drm_gem_object *gem,
                                       void *vaddr)
 {
        struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
-       int ret;
-
-       ret = ttm_bo_reserve(&gbo->bo, false, false, NULL);
-       if (WARN_ONCE(ret, "ttm_bo_reserve_failed(): ret=%d\n", ret))
-               return;
 
-       drm_gem_vram_kunmap_locked(gbo);
-       drm_gem_vram_unpin_locked(gbo);
-
-       ttm_bo_unreserve(&gbo->bo);
+       drm_gem_vram_vunmap(gbo, vaddr);
 }
 
 /*
index 9aaef4f8c32707e06f2ea4a4d84e7b5986098a66..418eb1122861a444e463a4491a6560007d457609 100644 (file)
@@ -43,7 +43,8 @@ struct vm_area_struct;
  * operations. So a buffer object that has been pinned N times with
  * drm_gem_vram_pin() must be unpinned N times with
  * drm_gem_vram_unpin(). The same applies to pairs of
- * drm_gem_vram_kmap() and drm_gem_vram_kunmap().
+ * drm_gem_vram_kmap() and drm_gem_vram_kunmap(), as well as pairs of
+ * drm_gem_vram_vmap() and drm_gem_vram_vunmap().
  */
 struct drm_gem_vram_object {
        struct ttm_buffer_object bo;
@@ -101,6 +102,8 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo);
 void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map,
                        bool *is_iomem);
 void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo);
+void *drm_gem_vram_vmap(struct drm_gem_vram_object *gbo);
+void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo, void *vaddr);
 
 int drm_gem_vram_fill_create_dumb(struct drm_file *file,
                                  struct drm_device *dev,