// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021, NVIDIA Corporation.
 */

#include <linux/device.h>
#include <linux/kref.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pid.h>
#include <linux/slab.h>

#include "context.h"
#include "dev.h"

int host1x_memory_context_list_init(struct host1x *host1x)
{
	struct host1x_memory_context_list *cdl = &host1x->context_list;
	struct device_node *node = host1x->dev->of_node;
	struct host1x_memory_context *ctx;
	unsigned int i;
	int err;

	cdl->devs = NULL;
	cdl->len = 0;
	mutex_init(&cdl->lock);

	err = of_property_count_u32_elems(node, "iommu-map");
	if (err < 0)
		return 0;

	cdl->devs = kcalloc(err, sizeof(*cdl->devs), GFP_KERNEL);
	if (!cdl->devs)
		return -ENOMEM;
	cdl->len = err / 4;

	for (i = 0; i < cdl->len; i++) {
		struct iommu_fwspec *fwspec;

		ctx = &cdl->devs[i];

		ctx->host = host1x;

		device_initialize(&ctx->dev);

		/*
		 * Due to an issue with T194 NVENC, only 38 bits can be used.
		 * Anyway, 256GiB of IOVA ought to be enough for anyone.
		 */
		ctx->dma_mask = DMA_BIT_MASK(38);
		ctx->dev.dma_mask = &ctx->dma_mask;
		ctx->dev.coherent_dma_mask = ctx->dma_mask;
		dev_set_name(&ctx->dev, "host1x-ctx.%d", i);
		ctx->dev.bus = &host1x_context_device_bus_type;
		ctx->dev.parent = host1x->dev;

		dma_set_max_seg_size(&ctx->dev, UINT_MAX);

		err = device_add(&ctx->dev);
		if (err) {
			dev_err(host1x->dev, "could not add context device %d: %d\n", i, err);
			goto del_devices;
		}

		err = of_dma_configure_id(&ctx->dev, node, true, &i);
		if (err) {
			dev_err(host1x->dev, "IOMMU configuration failed for context device %d: %d\n",
				i, err);
			device_del(&ctx->dev);
			goto del_devices;
		}

		fwspec = dev_iommu_fwspec_get(&ctx->dev);
		if (!fwspec || !device_iommu_mapped(&ctx->dev)) {
			dev_err(host1x->dev, "Context device %d has no IOMMU!\n", i);
			device_del(&ctx->dev);
			goto del_devices;
		}

		ctx->stream_id = fwspec->ids[0] & 0xffff;
	}

	return 0;

del_devices:
	while (i--)
		device_del(&cdl->devs[i].dev);

	kfree(cdl->devs);
	cdl->len = 0;

	return err;
}

void host1x_memory_context_list_free(struct host1x_memory_context_list *cdl)
{
	unsigned int i;

	for (i = 0; i < cdl->len; i++)
		device_del(&cdl->devs[i].dev);

	kfree(cdl->devs);
	cdl->len = 0;
}

struct host1x_memory_context *host1x_memory_context_alloc(struct host1x *host1x,
							  struct device *dev,
							  struct pid *pid)
{
	struct host1x_memory_context_list *cdl = &host1x->context_list;
	struct host1x_memory_context *free = NULL;
	int i;

	if (!cdl->len)
		return ERR_PTR(-EOPNOTSUPP);

	mutex_lock(&cdl->lock);

	for (i = 0; i < cdl->len; i++) {
		struct host1x_memory_context *cd = &cdl->devs[i];

		if (cd->dev.iommu->iommu_dev != dev->iommu->iommu_dev)
			continue;

		if (cd->owner == pid) {
			refcount_inc(&cd->ref);
			mutex_unlock(&cdl->lock);
			return cd;
		} else if (!cd->owner && !free) {
			free = cd;
		}
	}

	if (!free) {
		mutex_unlock(&cdl->lock);
		return ERR_PTR(-EBUSY);
	}

	refcount_set(&free->ref, 1);
	free->owner = get_pid(pid);

	mutex_unlock(&cdl->lock);

	return free;
}
EXPORT_SYMBOL_GPL(host1x_memory_context_alloc);

void host1x_memory_context_get(struct host1x_memory_context *cd)
{
	refcount_inc(&cd->ref);
}
EXPORT_SYMBOL_GPL(host1x_memory_context_get);

void host1x_memory_context_put(struct host1x_memory_context *cd)
{
	struct host1x_memory_context_list *cdl = &cd->host->context_list;

	if (refcount_dec_and_mutex_lock(&cd->ref, &cdl->lock)) {
		put_pid(cd->owner);
		cd->owner = NULL;
		mutex_unlock(&cdl->lock);
	}
}
EXPORT_SYMBOL_GPL(host1x_memory_context_put);
