diff options
Diffstat (limited to 'drivers/gpu/drm/lima/lima_gem.c')
| -rw-r--r-- | drivers/gpu/drm/lima/lima_gem.c | 108 |
1 files changed, 55 insertions, 53 deletions
diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c index 5404e0d668db..9722b847a539 100644 --- a/drivers/gpu/drm/lima/lima_gem.c +++ b/drivers/gpu/drm/lima/lima_gem.c @@ -2,6 +2,7 @@ /* Copyright 2017-2019 Qiang Yu <yuq825@gmail.com> */ #include <linux/mm.h> +#include <linux/iosys-map.h> #include <linux/sync_file.h> #include <linux/pagemap.h> #include <linux/shmem_fs.h> @@ -33,7 +34,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) new_size = min(new_size, bo->base.base.size); - mutex_lock(&bo->base.pages_lock); + dma_resv_lock(bo->base.base.resv, NULL); if (bo->base.pages) { pages = bo->base.pages; @@ -41,12 +42,12 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) pages = kvmalloc_array(bo->base.base.size >> PAGE_SHIFT, sizeof(*pages), GFP_KERNEL | __GFP_ZERO); if (!pages) { - mutex_unlock(&bo->base.pages_lock); + dma_resv_unlock(bo->base.base.resv); return -ENOMEM; } bo->base.pages = pages; - bo->base.pages_use_count = 1; + refcount_set(&bo->base.pages_use_count, 1); mapping_set_unevictable(mapping); } @@ -55,13 +56,13 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) struct page *page = shmem_read_mapping_page(mapping, i); if (IS_ERR(page)) { - mutex_unlock(&bo->base.pages_lock); + dma_resv_unlock(bo->base.base.resv); return PTR_ERR(page); } pages[i] = page; } - mutex_unlock(&bo->base.pages_lock); + dma_resv_unlock(bo->base.base.resv); ret = sg_alloc_table_from_pages(&sgt, pages, i, 0, new_size, GFP_KERNEL); @@ -69,29 +70,39 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) return ret; if (bo->base.sgt) { - dma_unmap_sg(dev, bo->base.sgt->sgl, - bo->base.sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); sg_free_table(bo->base.sgt); } else { bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL); if (!bo->base.sgt) { - sg_free_table(&sgt); - return -ENOMEM; + ret = -ENOMEM; + goto err_out0; } } - dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL); + ret = dma_map_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0); + if (ret) + goto err_out1; *bo->base.sgt = sgt; if (vm) { ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT); if (ret) - return ret; + goto err_out2; } bo->heap_size = new_size; return 0; + +err_out2: + dma_unmap_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0); +err_out1: + kfree(bo->base.sgt); + bo->base.sgt = NULL; +err_out0: + sg_free_table(&sgt); + return ret; } int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, @@ -122,7 +133,7 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, if (err) goto out; } else { - struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(obj); + struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(shmem); if (IS_ERR(sgt)) { err = PTR_ERR(sgt); @@ -134,7 +145,7 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file, out: /* drop reference from allocate - handle holds it now */ - drm_gem_object_put_unlocked(obj); + drm_gem_object_put(obj); return err; } @@ -146,7 +157,7 @@ static void lima_gem_free_object(struct drm_gem_object *obj) if (!list_empty(&bo->va)) dev_err(obj->dev->dev, "lima gem free bo still has va\n"); - drm_gem_shmem_free_object(obj); + drm_gem_shmem_free(&bo->base); } static int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file) @@ -174,17 +185,17 @@ static int lima_gem_pin(struct drm_gem_object *obj) if (bo->heap_size) return -EINVAL; - return drm_gem_shmem_pin(obj); + return drm_gem_shmem_pin_locked(&bo->base); } -static void *lima_gem_vmap(struct drm_gem_object *obj) +static int lima_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map) { struct lima_bo *bo = to_lima_bo(obj); if (bo->heap_size) - return ERR_PTR(-EINVAL); + return -EINVAL; - return drm_gem_shmem_vmap(obj); + return drm_gem_shmem_vmap_locked(&bo->base, map); } static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) @@ -194,20 +205,21 @@ static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) if (bo->heap_size) return -EINVAL; - return drm_gem_shmem_mmap(obj, vma); + return drm_gem_shmem_mmap(&bo->base, vma); } static const struct drm_gem_object_funcs lima_gem_funcs = { .free = lima_gem_free_object, .open = lima_gem_object_open, .close = lima_gem_object_close, - .print_info = drm_gem_shmem_print_info, + .print_info = drm_gem_shmem_object_print_info, .pin = lima_gem_pin, - .unpin = drm_gem_shmem_unpin, - .get_sg_table = drm_gem_shmem_get_sg_table, + .unpin = drm_gem_shmem_object_unpin, + .get_sg_table = drm_gem_shmem_object_get_sg_table, .vmap = lima_gem_vmap, - .vunmap = drm_gem_shmem_vunmap, + .vunmap = drm_gem_shmem_object_vunmap, .mmap = lima_gem_mmap, + .vm_ops = &drm_gem_shmem_vm_ops, }; struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t size) @@ -216,11 +228,11 @@ struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t siz bo = kzalloc(sizeof(*bo), GFP_KERNEL); if (!bo) - return NULL; + return ERR_PTR(-ENOMEM); mutex_init(&bo->lock); INIT_LIST_HEAD(&bo->va); - + bo->base.map_wc = true; bo->base.base.funcs = &lima_gem_funcs; return &bo->base.base; @@ -243,26 +255,26 @@ int lima_gem_get_info(struct drm_file *file, u32 handle, u32 *va, u64 *offset) *offset = drm_vma_node_offset_addr(&obj->vma_node); - drm_gem_object_put_unlocked(obj); + drm_gem_object_put(obj); return 0; } static int lima_gem_sync_bo(struct lima_sched_task *task, struct lima_bo *bo, bool write, bool explicit) { - int err = 0; + int err; - if (!write) { - err = dma_resv_reserve_shared(lima_bo_resv(bo), 1); - if (err) - return err; - } + err = dma_resv_reserve_fences(lima_bo_resv(bo), 1); + if (err) + return err; /* explicit sync use user passed dep fence */ if (explicit) return 0; - return drm_gem_fence_array_add_implicit(&task->deps, &bo->base.base, write); + return drm_sched_job_add_implicit_dependencies(&task->base, + &bo->base.base, + write); } static int lima_gem_add_deps(struct drm_file *file, struct lima_submit *submit) @@ -270,21 +282,13 @@ static int lima_gem_add_deps(struct drm_file *file, struct lima_submit *submit) int i, err; for (i = 0; i < ARRAY_SIZE(submit->in_sync); i++) { - struct dma_fence *fence = NULL; - if (!submit->in_sync[i]) continue; - err = drm_syncobj_find_fence(file, submit->in_sync[i], - 0, 0, &fence); + err = drm_sched_job_add_syncobj_dependency(&submit->task->base, file, + submit->in_sync[i], 0); if (err) return err; - - err = drm_gem_fence_array_add(&submit->task->deps, fence); - if (err) { - dma_fence_put(fence); - return err; - } } return 0; @@ -323,7 +327,7 @@ int lima_gem_submit(struct drm_file *file, struct lima_submit *submit) */ err = lima_vm_bo_add(vm, bo, false); if (err) { - drm_gem_object_put_unlocked(obj); + drm_gem_object_put(obj); goto err_out0; } @@ -337,7 +341,7 @@ int lima_gem_submit(struct drm_file *file, struct lima_submit *submit) err = lima_sched_task_init( submit->task, submit->ctx->context + submit->pipe, - bos, submit->nr_bos, vm); + bos, submit->nr_bos, vm, file->client_id); if (err) goto err_out1; @@ -354,21 +358,19 @@ int lima_gem_submit(struct drm_file *file, struct lima_submit *submit) goto err_out2; } - fence = lima_sched_context_queue_task( - submit->ctx->context + submit->pipe, submit->task); + fence = lima_sched_context_queue_task(submit->task); for (i = 0; i < submit->nr_bos; i++) { - if (submit->bos[i].flags & LIMA_SUBMIT_BO_WRITE) - dma_resv_add_excl_fence(lima_bo_resv(bos[i]), fence); - else - dma_resv_add_shared_fence(lima_bo_resv(bos[i]), fence); + dma_resv_add_fence(lima_bo_resv(bos[i]), fence, + submit->bos[i].flags & LIMA_SUBMIT_BO_WRITE ? + DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ); } drm_gem_unlock_reservations((struct drm_gem_object **)bos, submit->nr_bos, &ctx); for (i = 0; i < submit->nr_bos; i++) - drm_gem_object_put_unlocked(&bos[i]->base.base); + drm_gem_object_put(&bos[i]->base.base); if (out_sync) { drm_syncobj_replace_fence(out_sync, fence); @@ -389,7 +391,7 @@ err_out0: if (!bos[i]) break; lima_vm_bo_del(vm, bos[i]); - drm_gem_object_put_unlocked(&bos[i]->base.base); + drm_gem_object_put(&bos[i]->base.base); } if (out_sync) drm_syncobj_put(out_sync); |
