Merge tag 'drm-next-2020-10-23' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / drivers / gpu / drm / drm_gem_vram_helper.c
index 3296ed3..50cad0e 100644 (file)
@@ -97,8 +97,8 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs;
  * hardware's draing engine.
  *
  * To access a buffer object's memory from the DRM driver, call
- * drm_gem_vram_kmap(). It (optionally) maps the buffer into kernel address
- * space and returns the memory address. Use drm_gem_vram_kunmap() to
+ * drm_gem_vram_vmap(). It maps the buffer into kernel address
+ * space and returns the memory address. Use drm_gem_vram_vunmap() to
  * release the mapping.
  */
 
@@ -135,28 +135,28 @@ static void ttm_buffer_object_destroy(struct ttm_buffer_object *bo)
 static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
                                   unsigned long pl_flag)
 {
+       u32 invariant_flags = 0;
        unsigned int i;
        unsigned int c = 0;
-       u32 invariant_flags = pl_flag & TTM_PL_FLAG_TOPDOWN;
+
+       if (pl_flag & DRM_GEM_VRAM_PL_FLAG_TOPDOWN)
+               pl_flag = TTM_PL_FLAG_TOPDOWN;
 
        gbo->placement.placement = gbo->placements;
        gbo->placement.busy_placement = gbo->placements;
 
-       if (pl_flag & TTM_PL_FLAG_VRAM)
+       if (pl_flag & DRM_GEM_VRAM_PL_FLAG_VRAM) {
+               gbo->placements[c].mem_type = TTM_PL_VRAM;
                gbo->placements[c++].flags = TTM_PL_FLAG_WC |
                                             TTM_PL_FLAG_UNCACHED |
-                                            TTM_PL_FLAG_VRAM |
-                                            invariant_flags;
-
-       if (pl_flag & TTM_PL_FLAG_SYSTEM)
-               gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
-                                            TTM_PL_FLAG_SYSTEM |
                                             invariant_flags;
+       }
 
-       if (!c)
+       if (pl_flag & DRM_GEM_VRAM_PL_FLAG_SYSTEM || !c) {
+               gbo->placements[c].mem_type = TTM_PL_SYSTEM;
                gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
-                                            TTM_PL_FLAG_SYSTEM |
                                             invariant_flags;
+       }
 
        gbo->placement.num_placement = c;
        gbo->placement.num_busy_placement = c;
@@ -167,6 +167,10 @@ static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
        }
 }
 
+/*
+ * Note that on error, drm_gem_vram_init will free the buffer object.
+ */
+
 static int drm_gem_vram_init(struct drm_device *dev,
                             struct drm_gem_vram_object *gbo,
                             size_t size, unsigned long pg_align)
@@ -176,32 +180,37 @@ static int drm_gem_vram_init(struct drm_device *dev,
        int ret;
        size_t acc_size;
 
-       if (WARN_ONCE(!vmm, "VRAM MM not initialized"))
+       if (WARN_ONCE(!vmm, "VRAM MM not initialized")) {
+               kfree(gbo);
                return -EINVAL;
+       }
        bdev = &vmm->bdev;
 
        gbo->bo.base.funcs = &drm_gem_vram_object_funcs;
 
        ret = drm_gem_object_init(dev, &gbo->bo.base, size);
-       if (ret)
+       if (ret) {
+               kfree(gbo);
                return ret;
+       }
 
        acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo));
 
        gbo->bo.bdev = bdev;
-       drm_gem_vram_placement(gbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
+       drm_gem_vram_placement(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM |
+                              DRM_GEM_VRAM_PL_FLAG_SYSTEM);
 
        ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device,
                          &gbo->placement, pg_align, false, acc_size,
                          NULL, NULL, ttm_buffer_object_destroy);
        if (ret)
-               goto err_drm_gem_object_release;
+               /*
+                * A failing ttm_bo_init will call ttm_buffer_object_destroy
+                * to release gbo->bo.base and kfree gbo.
+                */
+               return ret;
 
        return 0;
-
-err_drm_gem_object_release:
-       drm_gem_object_release(&gbo->bo.base);
-       return ret;
 }
 
 /**
@@ -235,13 +244,9 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
 
        ret = drm_gem_vram_init(dev, gbo, size, pg_align);
        if (ret < 0)
-               goto err_kfree;
+               return ERR_PTR(ret);
 
        return gbo;
-
-err_kfree:
-       kfree(gbo);
-       return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(drm_gem_vram_create);
 
@@ -436,39 +441,6 @@ out:
        return kmap->virtual;
 }
 
-/**
- * drm_gem_vram_kmap() - Maps a GEM VRAM object into kernel address space
- * @gbo:       the GEM VRAM object
- * @map:       establish a mapping if necessary
- * @is_iomem:  returns true if the mapped memory is I/O memory, or false \
-       otherwise; can be NULL
- *
- * This function maps the buffer object into the kernel's address space
- * or returns the current mapping. If the parameter map is false, the
- * function only queries the current mapping, but does not establish a
- * new one.
- *
- * Returns:
- * The buffers virtual address if mapped, or
- * NULL if not mapped, or
- * an ERR_PTR()-encoded error code otherwise.
- */
-void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map,
-                       bool *is_iomem)
-{
-       int ret;
-       void *virtual;
-
-       ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
-       if (ret)
-               return ERR_PTR(ret);
-       virtual = drm_gem_vram_kmap_locked(gbo, map, is_iomem);
-       ttm_bo_unreserve(&gbo->bo);
-
-       return virtual;
-}
-EXPORT_SYMBOL(drm_gem_vram_kmap);
-
 static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
 {
        if (WARN_ON_ONCE(!gbo->kmap_use_count))
@@ -484,22 +456,6 @@ static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo)
         */
 }
 
-/**
- * drm_gem_vram_kunmap() - Unmaps a GEM VRAM object
- * @gbo:       the GEM VRAM object
- */
-void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo)
-{
-       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);
-       ttm_bo_unreserve(&gbo->bo);
-}
-EXPORT_SYMBOL(drm_gem_vram_kunmap);
-
 /**
  * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
  *                       space
@@ -511,9 +467,6 @@ EXPORT_SYMBOL(drm_gem_vram_kunmap);
  * 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.
@@ -647,13 +600,13 @@ static bool drm_is_gem_vram(struct ttm_buffer_object *bo)
 static void drm_gem_vram_bo_driver_evict_flags(struct drm_gem_vram_object *gbo,
                                               struct ttm_placement *pl)
 {
-       drm_gem_vram_placement(gbo, TTM_PL_FLAG_SYSTEM);
+       drm_gem_vram_placement(gbo, DRM_GEM_VRAM_PL_FLAG_SYSTEM);
        *pl = gbo->placement;
 }
 
 static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,
                                               bool evict,
-                                              struct ttm_mem_reg *new_mem)
+                                              struct ttm_resource *new_mem)
 {
        struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
 
@@ -967,16 +920,13 @@ static const struct drm_gem_object_funcs drm_gem_vram_object_funcs = {
  * TTM TT
  */
 
-static void backend_func_destroy(struct ttm_tt *tt)
+static void bo_driver_ttm_tt_destroy(struct ttm_bo_device *bdev, struct ttm_tt *tt)
 {
+       ttm_tt_destroy_common(bdev, tt);
        ttm_tt_fini(tt);
        kfree(tt);
 }
 
-static struct ttm_backend_func backend_func = {
-       .destroy = backend_func_destroy
-};
-
 /*
  * TTM BO device
  */
@@ -991,8 +941,6 @@ static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo,
        if (!tt)
                return NULL;
 
-       tt->func = &backend_func;
-
        ret = ttm_tt_init(tt, bo, page_flags);
        if (ret < 0)
                goto err_ttm_tt_init;
@@ -1004,28 +952,6 @@ err_ttm_tt_init:
        return NULL;
 }
 
-static int bo_driver_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
-                                  struct ttm_mem_type_manager *man)
-{
-       switch (type) {
-       case TTM_PL_SYSTEM:
-               man->flags = 0;
-               man->available_caching = TTM_PL_MASK_CACHING;
-               man->default_caching = TTM_PL_FLAG_CACHED;
-               break;
-       case TTM_PL_VRAM:
-               man->func = &ttm_bo_manager_func;
-               man->flags = TTM_MEMTYPE_FLAG_FIXED;
-               man->available_caching = TTM_PL_FLAG_UNCACHED |
-                                        TTM_PL_FLAG_WC;
-               man->default_caching = TTM_PL_FLAG_WC;
-               break;
-       default:
-               return -EINVAL;
-       }
-       return 0;
-}
-
 static void bo_driver_evict_flags(struct ttm_buffer_object *bo,
                                  struct ttm_placement *placement)
 {
@@ -1042,7 +968,7 @@ static void bo_driver_evict_flags(struct ttm_buffer_object *bo,
 
 static void bo_driver_move_notify(struct ttm_buffer_object *bo,
                                  bool evict,
-                                 struct ttm_mem_reg *new_mem)
+                                 struct ttm_resource *new_mem)
 {
        struct drm_gem_vram_object *gbo;
 
@@ -1056,22 +982,15 @@ static void bo_driver_move_notify(struct ttm_buffer_object *bo,
 }
 
 static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,
-                                   struct ttm_mem_reg *mem)
+                                   struct ttm_resource *mem)
 {
        struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bdev);
 
-       mem->bus.addr = NULL;
-       mem->bus.size = mem->num_pages << PAGE_SHIFT;
-
        switch (mem->mem_type) {
        case TTM_PL_SYSTEM:     /* nothing to do */
-               mem->bus.offset = 0;
-               mem->bus.base = 0;
-               mem->bus.is_iomem = false;
                break;
        case TTM_PL_VRAM:
-               mem->bus.offset = mem->start << PAGE_SHIFT;
-               mem->bus.base = vmm->vram_base;
+               mem->bus.offset = (mem->start << PAGE_SHIFT) + vmm->vram_base;
                mem->bus.is_iomem = true;
                break;
        default:
@@ -1083,9 +1002,7 @@ static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,
 
 static struct ttm_bo_driver bo_driver = {
        .ttm_tt_create = bo_driver_ttm_tt_create,
-       .ttm_tt_populate = ttm_pool_populate,
-       .ttm_tt_unpopulate = ttm_pool_unpopulate,
-       .init_mem_type = bo_driver_init_mem_type,
+       .ttm_tt_destroy = bo_driver_ttm_tt_destroy,
        .eviction_valuable = ttm_bo_eviction_valuable,
        .evict_flags = bo_driver_evict_flags,
        .move_notify = bo_driver_move_notify,
@@ -1100,12 +1017,10 @@ static int drm_vram_mm_debugfs(struct seq_file *m, void *data)
 {
        struct drm_info_node *node = (struct drm_info_node *) m->private;
        struct drm_vram_mm *vmm = node->minor->dev->vram_mm;
-       struct drm_mm *mm = vmm->bdev.man[TTM_PL_VRAM].priv;
+       struct ttm_resource_manager *man = ttm_manager_type(&vmm->bdev, TTM_PL_VRAM);
        struct drm_printer p = drm_seq_file_printer(m);
 
-       spin_lock(&ttm_bo_glob.lru_lock);
-       drm_mm_print(mm, &p);
-       spin_unlock(&ttm_bo_glob.lru_lock);
+       ttm_resource_manager_debug(man, &p);
        return 0;
 }
 
@@ -1142,7 +1057,8 @@ static int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
        if (ret)
                return ret;
 
-       ret = ttm_bo_init_mm(&vmm->bdev, TTM_PL_VRAM, vram_size >> PAGE_SHIFT);
+       ret = ttm_range_man_init(&vmm->bdev, TTM_PL_VRAM,
+                                false, vram_size >> PAGE_SHIFT);
        if (ret)
                return ret;
 
@@ -1151,6 +1067,7 @@ static int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
 
 static void drm_vram_mm_cleanup(struct drm_vram_mm *vmm)
 {
+       ttm_range_man_fini(&vmm->bdev, TTM_PL_VRAM);
        ttm_bo_device_release(&vmm->bdev);
 }