/*
 * Copyright 2014 Canonical
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Andreas Pokorny
 */

#include <drm/drm_prime.h>
#include <linux/virtio_dma_buf.h>

#include "virtgpu_drv.h"

MODULE_IMPORT_NS("DMA_BUF");

static int virtgpu_virtio_get_uuid(struct dma_buf *buf,
				   uuid_t *uuid)
{
	struct drm_gem_object *obj = buf->priv;
	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
	struct virtio_gpu_device *vgdev = obj->dev->dev_private;

	wait_event(vgdev->resp_wq, bo->uuid_state != STATE_INITIALIZING);
	if (bo->uuid_state != STATE_OK)
		return -ENODEV;

	uuid_copy(uuid, &bo->uuid);

	return 0;
}

static struct sg_table *
virtgpu_gem_map_dma_buf(struct dma_buf_attachment *attach,
			enum dma_data_direction dir)
{
	struct drm_gem_object *obj = attach->dmabuf->priv;
	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);

	if (virtio_gpu_is_vram(bo))
		return virtio_gpu_vram_map_dma_buf(bo, attach->dev, dir);

	return drm_gem_map_dma_buf(attach, dir);
}

static void virtgpu_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
				      struct sg_table *sgt,
				      enum dma_data_direction dir)
{
	struct drm_gem_object *obj = attach->dmabuf->priv;
	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);

	if (virtio_gpu_is_vram(bo)) {
		virtio_gpu_vram_unmap_dma_buf(attach->dev, sgt, dir);
		return;
	}

	drm_gem_unmap_dma_buf(attach, sgt, dir);
}

static const struct virtio_dma_buf_ops virtgpu_dmabuf_ops =  {
	.ops = {
		.attach = virtio_dma_buf_attach,
		.detach = drm_gem_map_detach,
		.map_dma_buf = virtgpu_gem_map_dma_buf,
		.unmap_dma_buf = virtgpu_gem_unmap_dma_buf,
		.release = drm_gem_dmabuf_release,
		.mmap = drm_gem_dmabuf_mmap,
		.vmap = drm_gem_dmabuf_vmap,
		.vunmap = drm_gem_dmabuf_vunmap,
	},
	.device_attach = drm_gem_map_attach,
	.get_uuid = virtgpu_virtio_get_uuid,
};

int virtio_gpu_resource_assign_uuid(struct virtio_gpu_device *vgdev,
				    struct virtio_gpu_object *bo)
{
	struct virtio_gpu_object_array *objs;

	objs = virtio_gpu_array_alloc(1);
	if (!objs)
		return -ENOMEM;

	virtio_gpu_array_add_obj(objs, &bo->base.base);

	return virtio_gpu_cmd_resource_assign_uuid(vgdev, objs);
}

struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
					 int flags)
{
	struct dma_buf *buf;
	struct drm_device *dev = obj->dev;
	struct virtio_gpu_device *vgdev = dev->dev_private;
	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
	int ret = 0;
	bool blob = bo->host3d_blob || bo->guest_blob;
	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

	if (!blob) {
		if (vgdev->has_resource_assign_uuid) {
			ret = virtio_gpu_resource_assign_uuid(vgdev, bo);
			if (ret)
				return ERR_PTR(ret);

			virtio_gpu_notify(vgdev);
		} else {
			bo->uuid_state = STATE_ERR;
		}
	} else if (!(bo->blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE)) {
		bo->uuid_state = STATE_ERR;
	}

	exp_info.ops = &virtgpu_dmabuf_ops.ops;
	exp_info.size = obj->size;
	exp_info.flags = flags;
	exp_info.priv = obj;
	exp_info.resv = obj->resv;

	buf = virtio_dma_buf_export(&exp_info);
	if (IS_ERR(buf))
		return buf;

	drm_dev_get(dev);
	drm_gem_object_get(obj);

	return buf;
}

int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents,
			       unsigned int *nents,
			       struct virtio_gpu_object *bo,
			       struct dma_buf_attachment *attach)
{
	struct scatterlist *sl;
	struct sg_table *sgt;
	long i, ret;

	dma_resv_assert_held(attach->dmabuf->resv);

	ret = dma_resv_wait_timeout(attach->dmabuf->resv,
				    DMA_RESV_USAGE_KERNEL,
				    false, MAX_SCHEDULE_TIMEOUT);
	if (ret <= 0)
		return ret < 0 ? ret : -ETIMEDOUT;

	sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
	if (IS_ERR(sgt))
		return PTR_ERR(sgt);

	*ents = kvmalloc_objs(struct virtio_gpu_mem_entry, sgt->nents);
	if (!(*ents)) {
		dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
		return -ENOMEM;
	}

	*nents = sgt->nents;
	for_each_sgtable_dma_sg(sgt, sl, i) {
		(*ents)[i].addr = cpu_to_le64(sg_dma_address(sl));
		(*ents)[i].length = cpu_to_le32(sg_dma_len(sl));
		(*ents)[i].padding = 0;
	}

	bo->sgt = sgt;
	return 0;
}

static void virtgpu_dma_buf_unmap(struct virtio_gpu_object *bo)
{
	struct dma_buf_attachment *attach = bo->base.base.import_attach;

	dma_resv_assert_held(attach->dmabuf->resv);

	if (bo->created) {
		virtio_gpu_detach_object_fenced(bo);

		if (bo->sgt)
			dma_buf_unmap_attachment(attach, bo->sgt,
						 DMA_BIDIRECTIONAL);

		bo->sgt = NULL;
	}
}

static void virtgpu_dma_buf_free_obj(struct drm_gem_object *obj)
{
	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
	struct virtio_gpu_device *vgdev = obj->dev->dev_private;
	struct dma_buf_attachment *attach = obj->import_attach;

	if (drm_gem_is_imported(obj)) {
		struct dma_buf *dmabuf = attach->dmabuf;

		dma_resv_lock(dmabuf->resv, NULL);
		virtgpu_dma_buf_unmap(bo);
		dma_resv_unlock(dmabuf->resv);

		dma_buf_detach(dmabuf, attach);
		dma_buf_put(dmabuf);
	}

	if (bo->created) {
		virtio_gpu_cmd_unref_resource(vgdev, bo);
		virtio_gpu_notify(vgdev);
		return;
	}
	virtio_gpu_cleanup_object(bo);
}

static int virtgpu_dma_buf_init_obj(struct drm_device *dev,
				    struct virtio_gpu_object *bo,
				    struct dma_buf_attachment *attach)
{
	struct virtio_gpu_device *vgdev = dev->dev_private;
	struct virtio_gpu_object_params params = { 0 };
	struct dma_resv *resv = attach->dmabuf->resv;
	struct virtio_gpu_mem_entry *ents = NULL;
	unsigned int nents;
	int ret;

	ret = virtio_gpu_resource_id_get(vgdev, &bo->hw_res_handle);
	if (ret) {
		virtgpu_dma_buf_free_obj(&bo->base.base);
		return ret;
	}

	dma_resv_lock(resv, NULL);

	ret = dma_buf_pin(attach);
	if (ret)
		goto err_pin;

	ret = virtgpu_dma_buf_import_sgt(&ents, &nents, bo, attach);
	if (ret)
		goto err_import;

	params.blob = true;
	params.blob_mem = VIRTGPU_BLOB_MEM_GUEST;
	params.blob_flags = VIRTGPU_BLOB_FLAG_USE_SHAREABLE;
	params.size = attach->dmabuf->size;

	virtio_gpu_cmd_resource_create_blob(vgdev, bo, &params,
					    ents, nents);
	bo->guest_blob = true;

	dma_buf_unpin(attach);
	dma_resv_unlock(resv);

	return 0;

err_import:
	dma_buf_unpin(attach);
err_pin:
	dma_resv_unlock(resv);
	virtgpu_dma_buf_free_obj(&bo->base.base);
	return ret;
}

static const struct drm_gem_object_funcs virtgpu_gem_dma_buf_funcs = {
	.free = virtgpu_dma_buf_free_obj,
};

static void virtgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)
{
	struct drm_gem_object *obj = attach->importer_priv;
	struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);

	virtgpu_dma_buf_unmap(bo);
}

static const struct dma_buf_attach_ops virtgpu_dma_buf_attach_ops = {
	.allow_peer2peer = true,
	.move_notify = virtgpu_dma_buf_move_notify
};

struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
						struct dma_buf *buf)
{
	struct virtio_gpu_device *vgdev = dev->dev_private;
	struct dma_buf_attachment *attach;
	struct virtio_gpu_object *bo;
	struct drm_gem_object *obj;
	int ret;

	if (buf->ops == &virtgpu_dmabuf_ops.ops) {
		obj = buf->priv;
		if (obj->dev == dev) {
			/*
			 * Importing dmabuf exported from our own gem increases
			 * refcount on gem itself instead of f_count of dmabuf.
			 */
			drm_gem_object_get(obj);
			return obj;
		}
	}

	if (!vgdev->has_resource_blob || vgdev->has_virgl_3d)
		return drm_gem_prime_import(dev, buf);

	bo = kzalloc_obj(*bo);
	if (!bo)
		return ERR_PTR(-ENOMEM);

	obj = &bo->base.base;
	obj->resv = buf->resv;
	obj->funcs = &virtgpu_gem_dma_buf_funcs;
	drm_gem_private_object_init(dev, obj, buf->size);

	attach = dma_buf_dynamic_attach(buf, dev->dev,
					&virtgpu_dma_buf_attach_ops, obj);
	if (IS_ERR(attach)) {
		kfree(bo);
		return ERR_CAST(attach);
	}

	obj->import_attach = attach;
	get_dma_buf(buf);

	ret = virtgpu_dma_buf_init_obj(dev, bo, attach);
	if (ret < 0)
		return ERR_PTR(ret);

	return obj;
}

struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
	struct drm_device *dev, struct dma_buf_attachment *attach,
	struct sg_table *table)
{
	return ERR_PTR(-ENODEV);
}
