// 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 <common.h>
#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),
};
