Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 #include <linux/pagemap.h>
0003 #include <linux/slab.h>
0004 
0005 #include "nouveau_drv.h"
0006 #include "nouveau_mem.h"
0007 #include "nouveau_ttm.h"
0008 #include "nouveau_bo.h"
0009 
0010 struct nouveau_sgdma_be {
0011     /* this has to be the first field so populate/unpopulated in
0012      * nouve_bo.c works properly, otherwise have to move them here
0013      */
0014     struct ttm_tt ttm;
0015     struct nouveau_mem *mem;
0016 };
0017 
0018 void
0019 nouveau_sgdma_destroy(struct ttm_device *bdev, struct ttm_tt *ttm)
0020 {
0021     struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
0022 
0023     if (ttm) {
0024         ttm_tt_fini(&nvbe->ttm);
0025         kfree(nvbe);
0026     }
0027 }
0028 
0029 int
0030 nouveau_sgdma_bind(struct ttm_device *bdev, struct ttm_tt *ttm, struct ttm_resource *reg)
0031 {
0032     struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
0033     struct nouveau_drm *drm = nouveau_bdev(bdev);
0034     struct nouveau_mem *mem = nouveau_mem(reg);
0035     int ret;
0036 
0037     if (nvbe->mem)
0038         return 0;
0039 
0040     ret = nouveau_mem_host(reg, &nvbe->ttm);
0041     if (ret)
0042         return ret;
0043 
0044     if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA) {
0045         ret = nouveau_mem_map(mem, &mem->cli->vmm.vmm, &mem->vma[0]);
0046         if (ret) {
0047             nouveau_mem_fini(mem);
0048             return ret;
0049         }
0050     }
0051 
0052     nvbe->mem = mem;
0053     return 0;
0054 }
0055 
0056 void
0057 nouveau_sgdma_unbind(struct ttm_device *bdev, struct ttm_tt *ttm)
0058 {
0059     struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
0060     if (nvbe->mem) {
0061         nouveau_mem_fini(nvbe->mem);
0062         nvbe->mem = NULL;
0063     }
0064 }
0065 
0066 struct ttm_tt *
0067 nouveau_sgdma_create_ttm(struct ttm_buffer_object *bo, uint32_t page_flags)
0068 {
0069     struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
0070     struct nouveau_bo *nvbo = nouveau_bo(bo);
0071     struct nouveau_sgdma_be *nvbe;
0072     enum ttm_caching caching;
0073 
0074     if (nvbo->force_coherent)
0075         caching = ttm_uncached;
0076     else if (drm->agp.bridge)
0077         caching = ttm_write_combined;
0078     else
0079         caching = ttm_cached;
0080 
0081     nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL);
0082     if (!nvbe)
0083         return NULL;
0084 
0085     if (ttm_sg_tt_init(&nvbe->ttm, bo, page_flags, caching)) {
0086         kfree(nvbe);
0087         return NULL;
0088     }
0089     return &nvbe->ttm;
0090 }