// SPDX-License-Identifier: GPL-2.0 OR MIT
/* 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>
#include <linux/dma-mapping.h>

#include <drm/drm_file.h>
#include <drm/drm_syncobj.h>
#include <drm/drm_utils.h>

#include <drm/lima_drm.h>

#include "lima_drv.h"
#include "lima_gem.h"
#include "lima_vm.h"

int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
{
	struct page **pages;
	struct address_space *mapping = bo->base.base.filp->f_mapping;
	struct device *dev = bo->base.base.dev->dev;
	size_t old_size = bo->heap_size;
	size_t new_size = bo->heap_size ? bo->heap_size * 2 :
		(lima_heap_init_nr_pages << PAGE_SHIFT);
	struct sg_table sgt;
	int i, ret;

	if (bo->heap_size >= bo->base.base.size)
		return -ENOSPC;

	new_size = min(new_size, bo->base.base.size);

	dma_resv_lock(bo->base.base.resv, NULL);

	if (bo->base.pages) {
		pages = bo->base.pages;
	} else {
		pages = kvmalloc_array(bo->base.base.size >> PAGE_SHIFT,
				       sizeof(*pages), GFP_KERNEL | __GFP_ZERO);
		if (!pages) {
			dma_resv_unlock(bo->base.base.resv);
			return -ENOMEM;
		}

		bo->base.pages = pages;
		bo->base.pages_use_count = 1;

		mapping_set_unevictable(mapping);
	}

	for (i = old_size >> PAGE_SHIFT; i < new_size >> PAGE_SHIFT; i++) {
		struct page *page = shmem_read_mapping_page(mapping, i);

		if (IS_ERR(page)) {
			dma_resv_unlock(bo->base.base.resv);
			return PTR_ERR(page);
		}
		pages[i] = page;
	}

	dma_resv_unlock(bo->base.base.resv);

	ret = sg_alloc_table_from_pages(&sgt, pages, i, 0,
					new_size, GFP_KERNEL);
	if (ret)
		return ret;

	if (bo->base.sgt) {
		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) {
			ret = -ENOMEM;
			goto err_out0;
		}
	}

	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)
			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,
			   u32 size, u32 flags, u32 *handle)
{
	int err;
	gfp_t mask;
	struct drm_gem_shmem_object *shmem;
	struct drm_gem_object *obj;
	struct lima_bo *bo;
	bool is_heap = flags & LIMA_BO_FLAG_HEAP;

	shmem = drm_gem_shmem_create(dev, size);
	if (IS_ERR(shmem))
		return PTR_ERR(shmem);

	obj = &shmem->base;

	/* Mali Utgard GPU can only support 32bit address space */
	mask = mapping_gfp_mask(obj->filp->f_mapping);
	mask &= ~__GFP_HIGHMEM;
	mask |= __GFP_DMA32;
	mapping_set_gfp_mask(obj->filp->f_mapping, mask);

	if (is_heap) {
		bo = to_lima_bo(obj);
		err = lima_heap_alloc(bo, NULL);
		if (err)
			goto out;
	} else {
		struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(shmem);

		if (IS_ERR(sgt)) {
			err = PTR_ERR(sgt);
			goto out;
		}
	}

	err = drm_gem_handle_create(file, obj, handle);

out:
	/* drop reference from allocate - handle holds it now */
	drm_gem_object_put(obj);

	return err;
}

static void lima_gem_free_object(struct drm_gem_object *obj)
{
	struct lima_bo *bo = to_lima_bo(obj);

	if (!list_empty(&bo->va))
		dev_err(obj->dev->dev, "lima gem free bo still has va\n");

	drm_gem_shmem_free(&bo->base);
}

static int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file)
{
	struct lima_bo *bo = to_lima_bo(obj);
	struct lima_drm_priv *priv = to_lima_drm_priv(file);
	struct lima_vm *vm = priv->vm;

	return lima_vm_bo_add(vm, bo, true);
}

static void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *file)
{
	struct lima_bo *bo = to_lima_bo(obj);
	struct lima_drm_priv *priv = to_lima_drm_priv(file);
	struct lima_vm *vm = priv->vm;

	lima_vm_bo_del(vm, bo);
}

static int lima_gem_pin(struct drm_gem_object *obj)
{
	struct lima_bo *bo = to_lima_bo(obj);

	if (bo->heap_size)
		return -EINVAL;

	return drm_gem_shmem_pin(&bo->base);
}

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 -EINVAL;

	return drm_gem_shmem_vmap(&bo->base, map);
}

static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
{
	struct lima_bo *bo = to_lima_bo(obj);

	if (bo->heap_size)
		return -EINVAL;

	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_object_print_info,
	.pin = lima_gem_pin,
	.unpin = drm_gem_shmem_object_unpin,
	.get_sg_table = drm_gem_shmem_object_get_sg_table,
	.vmap = lima_gem_vmap,
	.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)
{
	struct lima_bo *bo;

	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
	if (!bo)
		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;
}

int lima_gem_get_info(struct drm_file *file, u32 handle, u32 *va, u64 *offset)
{
	struct drm_gem_object *obj;
	struct lima_bo *bo;
	struct lima_drm_priv *priv = to_lima_drm_priv(file);
	struct lima_vm *vm = priv->vm;

	obj = drm_gem_object_lookup(file, handle);
	if (!obj)
		return -ENOENT;

	bo = to_lima_bo(obj);

	*va = lima_vm_get_va(vm, bo);

	*offset = drm_vma_node_offset_addr(&obj->vma_node);

	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;

	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_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)
{
	int i, err;

	for (i = 0; i < ARRAY_SIZE(submit->in_sync); i++) {
		if (!submit->in_sync[i])
			continue;

		err = drm_sched_job_add_syncobj_dependency(&submit->task->base, file,
							   submit->in_sync[i], 0);
		if (err)
			return err;
	}

	return 0;
}

int lima_gem_submit(struct drm_file *file, struct lima_submit *submit)
{
	int i, err = 0;
	struct ww_acquire_ctx ctx;
	struct lima_drm_priv *priv = to_lima_drm_priv(file);
	struct lima_vm *vm = priv->vm;
	struct drm_syncobj *out_sync = NULL;
	struct dma_fence *fence;
	struct lima_bo **bos = submit->lbos;

	if (submit->out_sync) {
		out_sync = drm_syncobj_find(file, submit->out_sync);
		if (!out_sync)
			return -ENOENT;
	}

	for (i = 0; i < submit->nr_bos; i++) {
		struct drm_gem_object *obj;
		struct lima_bo *bo;

		obj = drm_gem_object_lookup(file, submit->bos[i].handle);
		if (!obj) {
			err = -ENOENT;
			goto err_out0;
		}

		bo = to_lima_bo(obj);

		/* increase refcnt of gpu va map to prevent unmapped when executing,
		 * will be decreased when task done
		 */
		err = lima_vm_bo_add(vm, bo, false);
		if (err) {
			drm_gem_object_put(obj);
			goto err_out0;
		}

		bos[i] = bo;
	}

	err = drm_gem_lock_reservations((struct drm_gem_object **)bos,
					submit->nr_bos, &ctx);
	if (err)
		goto err_out0;

	err = lima_sched_task_init(
		submit->task, submit->ctx->context + submit->pipe,
		bos, submit->nr_bos, vm);
	if (err)
		goto err_out1;

	err = lima_gem_add_deps(file, submit);
	if (err)
		goto err_out2;

	for (i = 0; i < submit->nr_bos; i++) {
		err = lima_gem_sync_bo(
			submit->task, bos[i],
			submit->bos[i].flags & LIMA_SUBMIT_BO_WRITE,
			submit->flags & LIMA_SUBMIT_FLAG_EXPLICIT_FENCE);
		if (err)
			goto err_out2;
	}

	fence = lima_sched_context_queue_task(submit->task);

	for (i = 0; i < submit->nr_bos; i++) {
		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(&bos[i]->base.base);

	if (out_sync) {
		drm_syncobj_replace_fence(out_sync, fence);
		drm_syncobj_put(out_sync);
	}

	dma_fence_put(fence);

	return 0;

err_out2:
	lima_sched_task_fini(submit->task);
err_out1:
	drm_gem_unlock_reservations((struct drm_gem_object **)bos,
				    submit->nr_bos, &ctx);
err_out0:
	for (i = 0; i < submit->nr_bos; i++) {
		if (!bos[i])
			break;
		lima_vm_bo_del(vm, bos[i]);
		drm_gem_object_put(&bos[i]->base.base);
	}
	if (out_sync)
		drm_syncobj_put(out_sync);
	return err;
}

int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, s64 timeout_ns)
{
	bool write = op & LIMA_GEM_WAIT_WRITE;
	long ret, timeout;

	if (!op)
		return 0;

	timeout = drm_timeout_abs_to_jiffies(timeout_ns);

	ret = drm_gem_dma_resv_wait(file, handle, write, timeout);
	if (ret == -ETIME)
		ret = timeout ? -ETIMEDOUT : -EBUSY;

	return ret;
}
