root/drivers/gpu/drm/virtio/virtgpu_ttm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. virtio_gpu_get_vgdev
  2. virtio_gpu_mmap
  3. virtio_gpu_invalidate_caches
  4. ttm_bo_man_get_node
  5. ttm_bo_man_put_node
  6. ttm_bo_man_init
  7. ttm_bo_man_takedown
  8. ttm_bo_man_debug
  9. virtio_gpu_init_mem_type
  10. virtio_gpu_evict_flags
  11. virtio_gpu_verify_access
  12. virtio_gpu_ttm_io_mem_reserve
  13. virtio_gpu_ttm_io_mem_free
  14. virtio_gpu_ttm_tt_bind
  15. virtio_gpu_ttm_tt_unbind
  16. virtio_gpu_ttm_tt_destroy
  17. virtio_gpu_ttm_tt_create
  18. virtio_gpu_bo_swap_notify
  19. virtio_gpu_ttm_init
  20. virtio_gpu_ttm_fini

   1 /*
   2  * Copyright (C) 2015 Red Hat, Inc.
   3  * All Rights Reserved.
   4  *
   5  * Authors:
   6  *    Dave Airlie
   7  *    Alon Levy
   8  *
   9  * Permission is hereby granted, free of charge, to any person obtaining a
  10  * copy of this software and associated documentation files (the "Software"),
  11  * to deal in the Software without restriction, including without limitation
  12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13  * and/or sell copies of the Software, and to permit persons to whom the
  14  * Software is furnished to do so, subject to the following conditions:
  15  *
  16  * The above copyright notice and this permission notice shall be included in
  17  * all copies or substantial portions of the Software.
  18  *
  19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25  * OTHER DEALINGS IN THE SOFTWARE.
  26  */
  27 
  28 #include <linux/delay.h>
  29 
  30 #include <drm/drm.h>
  31 #include <drm/drm_file.h>
  32 #include <drm/ttm/ttm_bo_api.h>
  33 #include <drm/ttm/ttm_bo_driver.h>
  34 #include <drm/ttm/ttm_module.h>
  35 #include <drm/ttm/ttm_page_alloc.h>
  36 #include <drm/ttm/ttm_placement.h>
  37 #include <drm/virtgpu_drm.h>
  38 
  39 #include "virtgpu_drv.h"
  40 
  41 static struct
  42 virtio_gpu_device *virtio_gpu_get_vgdev(struct ttm_bo_device *bdev)
  43 {
  44         struct virtio_gpu_mman *mman;
  45         struct virtio_gpu_device *vgdev;
  46 
  47         mman = container_of(bdev, struct virtio_gpu_mman, bdev);
  48         vgdev = container_of(mman, struct virtio_gpu_device, mman);
  49         return vgdev;
  50 }
  51 
  52 int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma)
  53 {
  54         struct drm_file *file_priv;
  55         struct virtio_gpu_device *vgdev;
  56         int r;
  57 
  58         file_priv = filp->private_data;
  59         vgdev = file_priv->minor->dev->dev_private;
  60         if (vgdev == NULL) {
  61                 DRM_ERROR(
  62                  "filp->private_data->minor->dev->dev_private == NULL\n");
  63                 return -EINVAL;
  64         }
  65         r = ttm_bo_mmap(filp, vma, &vgdev->mman.bdev);
  66 
  67         return r;
  68 }
  69 
  70 static int virtio_gpu_invalidate_caches(struct ttm_bo_device *bdev,
  71                                         uint32_t flags)
  72 {
  73         return 0;
  74 }
  75 
  76 static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
  77                                struct ttm_buffer_object *bo,
  78                                const struct ttm_place *place,
  79                                struct ttm_mem_reg *mem)
  80 {
  81         mem->mm_node = (void *)1;
  82         return 0;
  83 }
  84 
  85 static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
  86                                 struct ttm_mem_reg *mem)
  87 {
  88         mem->mm_node = (void *)NULL;
  89 }
  90 
  91 static int ttm_bo_man_init(struct ttm_mem_type_manager *man,
  92                            unsigned long p_size)
  93 {
  94         return 0;
  95 }
  96 
  97 static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
  98 {
  99         return 0;
 100 }
 101 
 102 static void ttm_bo_man_debug(struct ttm_mem_type_manager *man,
 103                              struct drm_printer *printer)
 104 {
 105 }
 106 
 107 static const struct ttm_mem_type_manager_func virtio_gpu_bo_manager_func = {
 108         .init = ttm_bo_man_init,
 109         .takedown = ttm_bo_man_takedown,
 110         .get_node = ttm_bo_man_get_node,
 111         .put_node = ttm_bo_man_put_node,
 112         .debug = ttm_bo_man_debug
 113 };
 114 
 115 static int virtio_gpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 116                                     struct ttm_mem_type_manager *man)
 117 {
 118         switch (type) {
 119         case TTM_PL_SYSTEM:
 120                 /* System memory */
 121                 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
 122                 man->available_caching = TTM_PL_MASK_CACHING;
 123                 man->default_caching = TTM_PL_FLAG_CACHED;
 124                 break;
 125         case TTM_PL_TT:
 126                 man->func = &virtio_gpu_bo_manager_func;
 127                 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
 128                 man->available_caching = TTM_PL_MASK_CACHING;
 129                 man->default_caching = TTM_PL_FLAG_CACHED;
 130                 break;
 131         default:
 132                 DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
 133                 return -EINVAL;
 134         }
 135         return 0;
 136 }
 137 
 138 static void virtio_gpu_evict_flags(struct ttm_buffer_object *bo,
 139                                 struct ttm_placement *placement)
 140 {
 141         static const struct ttm_place placements = {
 142                 .fpfn  = 0,
 143                 .lpfn  = 0,
 144                 .flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM,
 145         };
 146 
 147         placement->placement = &placements;
 148         placement->busy_placement = &placements;
 149         placement->num_placement = 1;
 150         placement->num_busy_placement = 1;
 151 }
 152 
 153 static int virtio_gpu_verify_access(struct ttm_buffer_object *bo,
 154                                     struct file *filp)
 155 {
 156         return 0;
 157 }
 158 
 159 static int virtio_gpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
 160                                          struct ttm_mem_reg *mem)
 161 {
 162         struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
 163 
 164         mem->bus.addr = NULL;
 165         mem->bus.offset = 0;
 166         mem->bus.size = mem->num_pages << PAGE_SHIFT;
 167         mem->bus.base = 0;
 168         mem->bus.is_iomem = false;
 169         if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
 170                 return -EINVAL;
 171         switch (mem->mem_type) {
 172         case TTM_PL_SYSTEM:
 173         case TTM_PL_TT:
 174                 /* system memory */
 175                 return 0;
 176         default:
 177                 return -EINVAL;
 178         }
 179         return 0;
 180 }
 181 
 182 static void virtio_gpu_ttm_io_mem_free(struct ttm_bo_device *bdev,
 183                                        struct ttm_mem_reg *mem)
 184 {
 185 }
 186 
 187 /*
 188  * TTM backend functions.
 189  */
 190 struct virtio_gpu_ttm_tt {
 191         struct ttm_dma_tt               ttm;
 192         struct virtio_gpu_object        *obj;
 193 };
 194 
 195 static int virtio_gpu_ttm_tt_bind(struct ttm_tt *ttm,
 196                                   struct ttm_mem_reg *bo_mem)
 197 {
 198         struct virtio_gpu_ttm_tt *gtt =
 199                 container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm);
 200         struct virtio_gpu_device *vgdev =
 201                 virtio_gpu_get_vgdev(gtt->obj->tbo.bdev);
 202 
 203         virtio_gpu_object_attach(vgdev, gtt->obj, NULL);
 204         return 0;
 205 }
 206 
 207 static int virtio_gpu_ttm_tt_unbind(struct ttm_tt *ttm)
 208 {
 209         struct virtio_gpu_ttm_tt *gtt =
 210                 container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm);
 211         struct virtio_gpu_device *vgdev =
 212                 virtio_gpu_get_vgdev(gtt->obj->tbo.bdev);
 213 
 214         virtio_gpu_object_detach(vgdev, gtt->obj);
 215         return 0;
 216 }
 217 
 218 static void virtio_gpu_ttm_tt_destroy(struct ttm_tt *ttm)
 219 {
 220         struct virtio_gpu_ttm_tt *gtt =
 221                 container_of(ttm, struct virtio_gpu_ttm_tt, ttm.ttm);
 222 
 223         ttm_dma_tt_fini(&gtt->ttm);
 224         kfree(gtt);
 225 }
 226 
 227 static struct ttm_backend_func virtio_gpu_tt_func = {
 228         .bind = &virtio_gpu_ttm_tt_bind,
 229         .unbind = &virtio_gpu_ttm_tt_unbind,
 230         .destroy = &virtio_gpu_ttm_tt_destroy,
 231 };
 232 
 233 static struct ttm_tt *virtio_gpu_ttm_tt_create(struct ttm_buffer_object *bo,
 234                                                uint32_t page_flags)
 235 {
 236         struct virtio_gpu_device *vgdev;
 237         struct virtio_gpu_ttm_tt *gtt;
 238 
 239         vgdev = virtio_gpu_get_vgdev(bo->bdev);
 240         gtt = kzalloc(sizeof(struct virtio_gpu_ttm_tt), GFP_KERNEL);
 241         if (gtt == NULL)
 242                 return NULL;
 243         gtt->ttm.ttm.func = &virtio_gpu_tt_func;
 244         gtt->obj = container_of(bo, struct virtio_gpu_object, tbo);
 245         if (ttm_dma_tt_init(&gtt->ttm, bo, page_flags)) {
 246                 kfree(gtt);
 247                 return NULL;
 248         }
 249         return &gtt->ttm.ttm;
 250 }
 251 
 252 static void virtio_gpu_bo_swap_notify(struct ttm_buffer_object *tbo)
 253 {
 254         struct virtio_gpu_object *bo;
 255 
 256         bo = container_of(tbo, struct virtio_gpu_object, tbo);
 257 
 258         if (bo->pages)
 259                 virtio_gpu_object_free_sg_table(bo);
 260 }
 261 
 262 static struct ttm_bo_driver virtio_gpu_bo_driver = {
 263         .ttm_tt_create = &virtio_gpu_ttm_tt_create,
 264         .invalidate_caches = &virtio_gpu_invalidate_caches,
 265         .init_mem_type = &virtio_gpu_init_mem_type,
 266         .eviction_valuable = ttm_bo_eviction_valuable,
 267         .evict_flags = &virtio_gpu_evict_flags,
 268         .verify_access = &virtio_gpu_verify_access,
 269         .io_mem_reserve = &virtio_gpu_ttm_io_mem_reserve,
 270         .io_mem_free = &virtio_gpu_ttm_io_mem_free,
 271         .swap_notify = &virtio_gpu_bo_swap_notify,
 272 };
 273 
 274 int virtio_gpu_ttm_init(struct virtio_gpu_device *vgdev)
 275 {
 276         int r;
 277 
 278         /* No others user of address space so set it to 0 */
 279         r = ttm_bo_device_init(&vgdev->mman.bdev,
 280                                &virtio_gpu_bo_driver,
 281                                vgdev->ddev->anon_inode->i_mapping,
 282                                false);
 283         if (r) {
 284                 DRM_ERROR("failed initializing buffer object driver(%d).\n", r);
 285                 goto err_dev_init;
 286         }
 287 
 288         r = ttm_bo_init_mm(&vgdev->mman.bdev, TTM_PL_TT, 0);
 289         if (r) {
 290                 DRM_ERROR("Failed initializing GTT heap.\n");
 291                 goto err_mm_init;
 292         }
 293         return 0;
 294 
 295 err_mm_init:
 296         ttm_bo_device_release(&vgdev->mman.bdev);
 297 err_dev_init:
 298         return r;
 299 }
 300 
 301 void virtio_gpu_ttm_fini(struct virtio_gpu_device *vgdev)
 302 {
 303         ttm_bo_device_release(&vgdev->mman.bdev);
 304         DRM_INFO("virtio_gpu: ttm finalized\n");
 305 }

/* [<][>][^][v][top][bottom][index][help] */