// SPDX-License-Identifier: GPL-2.0+
/*
 * Direct Memory Access U-Class Simulation driver
 *
 * Copyright (C) 2018 Texas Instruments Incorporated <www.ti.com>
 *
 * Author: Grygorii Strashko <grygorii.strashko@ti.com>
 */

#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <dm/read.h>
#include <dma-uclass.h>
#include <dt-structs.h>
#include <errno.h>
#include <linux/printk.h>

#define SANDBOX_DMA_CH_CNT 3
#define SANDBOX_DMA_BUF_SIZE 1024

struct sandbox_dma_chan {
	struct sandbox_dma_dev *ud;
	char name[20];
	u32 id;
	enum dma_direction dir;
	bool in_use;
	bool enabled;
};

struct sandbox_dma_dev {
	struct device *dev;
	u32 ch_count;
	struct sandbox_dma_chan channels[SANDBOX_DMA_CH_CNT];
	uchar   buf[SANDBOX_DMA_BUF_SIZE];
	uchar	*buf_rx;
	size_t	data_len;
	u32	meta;
};

static int sandbox_dma_transfer(struct udevice *dev, int direction,
				dma_addr_t dst, dma_addr_t src, size_t len)
{
	memcpy((void *)dst, (void *)src, len);

	return 0;
}

static int sandbox_dma_of_xlate(struct dma *dma,
				struct ofnode_phandle_args *args)
{
	struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
	struct sandbox_dma_chan *uc;

	debug("%s(dma id=%u)\n", __func__, args->args[0]);

	if (args->args[0] >= SANDBOX_DMA_CH_CNT)
		return -EINVAL;

	dma->id = args->args[0];

	uc = &ud->channels[dma->id];

	if (dma->id == 1)
		uc->dir = DMA_MEM_TO_DEV;
	else if (dma->id == 2)
		uc->dir = DMA_DEV_TO_MEM;
	else
		uc->dir = DMA_MEM_TO_MEM;
	debug("%s(dma id=%lu dir=%d)\n", __func__, dma->id, uc->dir);

	return 0;
}

static int sandbox_dma_request(struct dma *dma)
{
	struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
	struct sandbox_dma_chan *uc;

	if (dma->id >= SANDBOX_DMA_CH_CNT)
		return -EINVAL;

	uc = &ud->channels[dma->id];
	if (uc->in_use)
		return -EBUSY;

	uc->in_use = true;
	debug("%s(dma id=%lu in_use=%d)\n", __func__, dma->id, uc->in_use);

	return 0;
}

static int sandbox_dma_rfree(struct dma *dma)
{
	struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
	struct sandbox_dma_chan *uc;

	if (dma->id >= SANDBOX_DMA_CH_CNT)
		return -EINVAL;

	uc = &ud->channels[dma->id];
	if (!uc->in_use)
		return -EINVAL;

	uc->in_use = false;
	ud->buf_rx = NULL;
	ud->data_len = 0;
	debug("%s(dma id=%lu in_use=%d)\n", __func__, dma->id, uc->in_use);

	return 0;
}

static int sandbox_dma_enable(struct dma *dma)
{
	struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
	struct sandbox_dma_chan *uc;

	if (dma->id >= SANDBOX_DMA_CH_CNT)
		return -EINVAL;

	uc = &ud->channels[dma->id];
	if (!uc->in_use)
		return -EINVAL;
	if (uc->enabled)
		return -EINVAL;

	uc->enabled = true;
	debug("%s(dma id=%lu enabled=%d)\n", __func__, dma->id, uc->enabled);

	return 0;
}

static int sandbox_dma_disable(struct dma *dma)
{
	struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
	struct sandbox_dma_chan *uc;

	if (dma->id >= SANDBOX_DMA_CH_CNT)
		return -EINVAL;

	uc = &ud->channels[dma->id];
	if (!uc->in_use)
		return -EINVAL;
	if (!uc->enabled)
		return -EINVAL;

	uc->enabled = false;
	debug("%s(dma id=%lu enabled=%d)\n", __func__, dma->id, uc->enabled);

	return 0;
}

static int sandbox_dma_send(struct dma *dma,
			    void *src, size_t len, void *metadata)
{
	struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
	struct sandbox_dma_chan *uc;

	if (dma->id >= SANDBOX_DMA_CH_CNT)
		return -EINVAL;
	if (!src || !metadata)
		return -EINVAL;

	debug("%s(dma id=%lu)\n", __func__, dma->id);

	uc = &ud->channels[dma->id];
	if (uc->dir != DMA_MEM_TO_DEV)
		return -EINVAL;
	if (!uc->in_use)
		return -EINVAL;
	if (!uc->enabled)
		return -EINVAL;
	if (len >= SANDBOX_DMA_BUF_SIZE)
		return -EINVAL;

	memcpy(ud->buf, src, len);
	ud->data_len = len;
	ud->meta = *((u32 *)metadata);

	debug("%s(dma id=%lu len=%zu meta=%08x)\n",
	      __func__, dma->id, len, ud->meta);

	return 0;
}

static int sandbox_dma_receive(struct dma *dma, void **dst, void *metadata)
{
	struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);
	struct sandbox_dma_chan *uc;

	if (dma->id >= SANDBOX_DMA_CH_CNT)
		return -EINVAL;
	if (!dst || !metadata)
		return -EINVAL;

	uc = &ud->channels[dma->id];
	if (uc->dir != DMA_DEV_TO_MEM)
		return -EINVAL;
	if (!uc->in_use)
		return -EINVAL;
	if (!uc->enabled)
		return -EINVAL;
	if (!ud->data_len)
		return 0;

	if (ud->buf_rx) {
		memcpy(ud->buf_rx, ud->buf, ud->data_len);
		*dst = ud->buf_rx;
	} else {
		memcpy(*dst, ud->buf, ud->data_len);
	}

	*((u32 *)metadata) = ud->meta;

	debug("%s(dma id=%lu len=%zu meta=%08x %p)\n",
	      __func__, dma->id, ud->data_len, ud->meta, *dst);

	return ud->data_len;
}

static int sandbox_dma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size)
{
	struct sandbox_dma_dev *ud = dev_get_priv(dma->dev);

	ud->buf_rx = dst;

	return 0;
}

static const struct dma_ops sandbox_dma_ops = {
	.transfer	= sandbox_dma_transfer,
	.of_xlate	= sandbox_dma_of_xlate,
	.request	= sandbox_dma_request,
	.rfree		= sandbox_dma_rfree,
	.enable		= sandbox_dma_enable,
	.disable	= sandbox_dma_disable,
	.send		= sandbox_dma_send,
	.receive	= sandbox_dma_receive,
	.prepare_rcv_buf = sandbox_dma_prepare_rcv_buf,
};

static int sandbox_dma_probe(struct udevice *dev)
{
	struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct sandbox_dma_dev *ud = dev_get_priv(dev);
	int i, ret = 0;

	uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM |
			     DMA_SUPPORTS_MEM_TO_DEV |
			     DMA_SUPPORTS_DEV_TO_MEM;

	ud->ch_count = SANDBOX_DMA_CH_CNT;
	ud->buf_rx = NULL;
	ud->meta = 0;
	ud->data_len = 0;

	pr_err("Number of channels: %u\n", ud->ch_count);

	for (i = 0; i < ud->ch_count; i++) {
		struct sandbox_dma_chan *uc = &ud->channels[i];

		uc->ud = ud;
		uc->id = i;
		sprintf(uc->name, "DMA chan%d\n", i);
		uc->in_use = false;
		uc->enabled = false;
	}

	return ret;
}

static const struct udevice_id sandbox_dma_ids[] = {
	{ .compatible = "sandbox,dma" },
	{ }
};

U_BOOT_DRIVER(sandbox_dma) = {
	.name	= "sandbox-dma",
	.id	= UCLASS_DMA,
	.of_match = sandbox_dma_ids,
	.ops	= &sandbox_dma_ops,
	.probe = sandbox_dma_probe,
	.priv_auto	= sizeof(struct sandbox_dma_dev),
};
