/*
 * Driver For Marvell Two-channel DMA Engine
 *
 * Copyright: Marvell International Ltd.
 *
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <mach/regs-icu.h>
#include <linux/platform_data/dma-mmp_tdma.h>
#include <linux/of_device.h>

#include "dmaengine.h"

/*
 * Two-Channel DMA registers
 */
#define TDBCR		0x00	/* Byte Count */
#define TDSAR		0x10	/* Src Addr */
#define TDDAR		0x20	/* Dst Addr */
#define TDNDPR		0x30	/* Next Desc */
#define TDCR		0x40	/* Control */
#define TDCP		0x60	/* Priority*/
#define TDCDPR		0x70	/* Current Desc */
#define TDIMR		0x80	/* Int Mask */
#define TDISR		0xa0	/* Int Status */

/* Two-Channel DMA Control Register */
#define TDCR_SSZ_8_BITS		(0x0 << 22)	/* Sample Size */
#define TDCR_SSZ_12_BITS	(0x1 << 22)
#define TDCR_SSZ_16_BITS	(0x2 << 22)
#define TDCR_SSZ_20_BITS	(0x3 << 22)
#define TDCR_SSZ_24_BITS	(0x4 << 22)
#define TDCR_SSZ_32_BITS	(0x5 << 22)
#define TDCR_SSZ_SHIFT		(0x1 << 22)
#define TDCR_SSZ_MASK		(0x7 << 22)
#define TDCR_SSPMOD		(0x1 << 21)	/* SSP MOD */
#define TDCR_ABR		(0x1 << 20)	/* Channel Abort */
#define TDCR_CDE		(0x1 << 17)	/* Close Desc Enable */
#define TDCR_PACKMOD		(0x1 << 16)	/* Pack Mode (ADMA Only) */
#define TDCR_CHANACT		(0x1 << 14)	/* Channel Active */
#define TDCR_FETCHND		(0x1 << 13)	/* Fetch Next Desc */
#define TDCR_CHANEN		(0x1 << 12)	/* Channel Enable */
#define TDCR_INTMODE		(0x1 << 10)	/* Interrupt Mode */
#define TDCR_CHAINMOD		(0x1 << 9)	/* Chain Mode */
#define TDCR_BURSTSZ_MSK	(0x7 << 6)	/* Burst Size */
#define TDCR_BURSTSZ_4B		(0x0 << 6)
#define TDCR_BURSTSZ_8B		(0x1 << 6)
#define TDCR_BURSTSZ_16B	(0x3 << 6)
#define TDCR_BURSTSZ_32B	(0x6 << 6)
#define TDCR_BURSTSZ_64B	(0x7 << 6)
#define TDCR_BURSTSZ_SQU_32B	(0x7 << 6)
#define TDCR_BURSTSZ_128B	(0x5 << 6)
#define TDCR_DSTDIR_MSK		(0x3 << 4)	/* Dst Direction */
#define TDCR_DSTDIR_ADDR_HOLD	(0x2 << 4)	/* Dst Addr Hold */
#define TDCR_DSTDIR_ADDR_INC	(0x0 << 4)	/* Dst Addr Increment */
#define TDCR_SRCDIR_MSK		(0x3 << 2)	/* Src Direction */
#define TDCR_SRCDIR_ADDR_HOLD	(0x2 << 2)	/* Src Addr Hold */
#define TDCR_SRCDIR_ADDR_INC	(0x0 << 2)	/* Src Addr Increment */
#define TDCR_DSTDESCCONT	(0x1 << 1)
#define TDCR_SRCDESTCONT	(0x1 << 0)

/* Two-Channel DMA Int Mask Register */
#define TDIMR_COMP		(0x1 << 0)

/* Two-Channel DMA Int Status Register */
#define TDISR_COMP		(0x1 << 0)

/*
 * Two-Channel DMA Descriptor Struct
 * NOTE: desc's buf must be aligned to 16 bytes.
 */
struct mmp_tdma_desc {
	u32 byte_cnt;
	u32 src_addr;
	u32 dst_addr;
	u32 nxt_desc;
};

enum mmp_tdma_type {
	MMP_AUD_TDMA = 0,
	PXA910_SQU,
};

#define TDMA_ALIGNMENT		3
#define TDMA_MAX_XFER_BYTES    SZ_64K

struct mmp_tdma_chan {
	struct device			*dev;
	struct dma_chan			chan;
	struct dma_async_tx_descriptor	desc;
	struct tasklet_struct		tasklet;

	struct mmp_tdma_desc		*desc_arr;
	phys_addr_t			desc_arr_phys;
	int				desc_num;
	enum dma_transfer_direction	dir;
	dma_addr_t			dev_addr;
	u32				burst_sz;
	enum dma_slave_buswidth		buswidth;
	enum dma_status			status;

	int				idx;
	enum mmp_tdma_type		type;
	int				irq;
	unsigned long			reg_base;

	size_t				buf_len;
	size_t				period_len;
	size_t				pos;
};

#define TDMA_CHANNEL_NUM 2
struct mmp_tdma_device {
	struct device			*dev;
	void __iomem			*base;
	struct dma_device		device;
	struct mmp_tdma_chan		*tdmac[TDMA_CHANNEL_NUM];
};

#define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan)

static void mmp_tdma_chan_set_desc(struct mmp_tdma_chan *tdmac, dma_addr_t phys)
{
	writel(phys, tdmac->reg_base + TDNDPR);
	writel(readl(tdmac->reg_base + TDCR) | TDCR_FETCHND,
					tdmac->reg_base + TDCR);
}

static void mmp_tdma_enable_chan(struct mmp_tdma_chan *tdmac)
{
	/* enable irq */
	writel(TDIMR_COMP, tdmac->reg_base + TDIMR);
	/* enable dma chan */
	writel(readl(tdmac->reg_base + TDCR) | TDCR_CHANEN,
					tdmac->reg_base + TDCR);
	tdmac->status = DMA_IN_PROGRESS;
}

static void mmp_tdma_disable_chan(struct mmp_tdma_chan *tdmac)
{
	writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN,
					tdmac->reg_base + TDCR);
	tdmac->status = DMA_SUCCESS;
}

static void mmp_tdma_resume_chan(struct mmp_tdma_chan *tdmac)
{
	writel(readl(tdmac->reg_base + TDCR) | TDCR_CHANEN,
					tdmac->reg_base + TDCR);
	tdmac->status = DMA_IN_PROGRESS;
}

static void mmp_tdma_pause_chan(struct mmp_tdma_chan *tdmac)
{
	writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN,
					tdmac->reg_base + TDCR);
	tdmac->status = DMA_PAUSED;
}

static int mmp_tdma_config_chan(struct mmp_tdma_chan *tdmac)
{
	unsigned int tdcr;

	mmp_tdma_disable_chan(tdmac);

	if (tdmac->dir == DMA_MEM_TO_DEV)
		tdcr = TDCR_DSTDIR_ADDR_HOLD | TDCR_SRCDIR_ADDR_INC;
	else if (tdmac->dir == DMA_DEV_TO_MEM)
		tdcr = TDCR_SRCDIR_ADDR_HOLD | TDCR_DSTDIR_ADDR_INC;

	if (tdmac->type == MMP_AUD_TDMA) {
		tdcr |= TDCR_PACKMOD;

		switch (tdmac->burst_sz) {
		case 4:
			tdcr |= TDCR_BURSTSZ_4B;
			break;
		case 8:
			tdcr |= TDCR_BURSTSZ_8B;
			break;
		case 16:
			tdcr |= TDCR_BURSTSZ_16B;
			break;
		case 32:
			tdcr |= TDCR_BURSTSZ_32B;
			break;
		case 64:
			tdcr |= TDCR_BURSTSZ_64B;
			break;
		case 128:
			tdcr |= TDCR_BURSTSZ_128B;
			break;
		default:
			dev_err(tdmac->dev, "mmp_tdma: unknown burst size.\n");
			return -EINVAL;
		}

		switch (tdmac->buswidth) {
		case DMA_SLAVE_BUSWIDTH_1_BYTE:
			tdcr |= TDCR_SSZ_8_BITS;
			break;
		case DMA_SLAVE_BUSWIDTH_2_BYTES:
			tdcr |= TDCR_SSZ_16_BITS;
			break;
		case DMA_SLAVE_BUSWIDTH_4_BYTES:
			tdcr |= TDCR_SSZ_32_BITS;
			break;
		default:
			dev_err(tdmac->dev, "mmp_tdma: unknown bus size.\n");
			return -EINVAL;
		}
	} else if (tdmac->type == PXA910_SQU) {
		tdcr |= TDCR_BURSTSZ_SQU_32B;
		tdcr |= TDCR_SSPMOD;
	}

	writel(tdcr, tdmac->reg_base + TDCR);
	return 0;
}

static int mmp_tdma_clear_chan_irq(struct mmp_tdma_chan *tdmac)
{
	u32 reg = readl(tdmac->reg_base + TDISR);

	if (reg & TDISR_COMP) {
		/* clear irq */
		reg &= ~TDISR_COMP;
		writel(reg, tdmac->reg_base + TDISR);

		return 0;
	}
	return -EAGAIN;
}

static irqreturn_t mmp_tdma_chan_handler(int irq, void *dev_id)
{
	struct mmp_tdma_chan *tdmac = dev_id;

	if (mmp_tdma_clear_chan_irq(tdmac) == 0) {
		tdmac->pos = (tdmac->pos + tdmac->period_len) % tdmac->buf_len;
		tasklet_schedule(&tdmac->tasklet);
		return IRQ_HANDLED;
	} else
		return IRQ_NONE;
}

static irqreturn_t mmp_tdma_int_handler(int irq, void *dev_id)
{
	struct mmp_tdma_device *tdev = dev_id;
	int i, ret;
	int irq_num = 0;

	for (i = 0; i < TDMA_CHANNEL_NUM; i++) {
		struct mmp_tdma_chan *tdmac = tdev->tdmac[i];

		ret = mmp_tdma_chan_handler(irq, tdmac);
		if (ret == IRQ_HANDLED)
			irq_num++;
	}

	if (irq_num)
		return IRQ_HANDLED;
	else
		return IRQ_NONE;
}

static void dma_do_tasklet(unsigned long data)
{
	struct mmp_tdma_chan *tdmac = (struct mmp_tdma_chan *)data;

	if (tdmac->desc.callback)
		tdmac->desc.callback(tdmac->desc.callback_param);

}

static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac)
{
	struct gen_pool *gpool;
	int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc);

	gpool = sram_get_gpool("asram");
	if (tdmac->desc_arr)
		gen_pool_free(gpool, (unsigned long)tdmac->desc_arr,
				size);
	tdmac->desc_arr = NULL;

	return;
}

static dma_cookie_t mmp_tdma_tx_submit(struct dma_async_tx_descriptor *tx)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(tx->chan);

	mmp_tdma_chan_set_desc(tdmac, tdmac->desc_arr_phys);

	return 0;
}

static int mmp_tdma_alloc_chan_resources(struct dma_chan *chan)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
	int ret;

	dma_async_tx_descriptor_init(&tdmac->desc, chan);
	tdmac->desc.tx_submit = mmp_tdma_tx_submit;

	if (tdmac->irq) {
		ret = devm_request_irq(tdmac->dev, tdmac->irq,
			mmp_tdma_chan_handler, IRQF_DISABLED, "tdma", tdmac);
		if (ret)
			return ret;
	}
	return 1;
}

static void mmp_tdma_free_chan_resources(struct dma_chan *chan)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);

	if (tdmac->irq)
		devm_free_irq(tdmac->dev, tdmac->irq, tdmac);
	mmp_tdma_free_descriptor(tdmac);
	return;
}

struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac)
{
	struct gen_pool *gpool;
	int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc);

	gpool = sram_get_gpool("asram");
	if (!gpool)
		return NULL;

	tdmac->desc_arr = (void *)gen_pool_alloc(gpool, size);
	if (!tdmac->desc_arr)
		return NULL;

	tdmac->desc_arr_phys = gen_pool_virt_to_phys(gpool,
			(unsigned long)tdmac->desc_arr);

	return tdmac->desc_arr;
}

static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic(
		struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
		size_t period_len, enum dma_transfer_direction direction,
		unsigned long flags, void *context)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
	struct mmp_tdma_desc *desc;
	int num_periods = buf_len / period_len;
	int i = 0, buf = 0;

	if (tdmac->status != DMA_SUCCESS)
		return NULL;

	if (period_len > TDMA_MAX_XFER_BYTES) {
		dev_err(tdmac->dev,
				"maximum period size exceeded: %d > %d\n",
				period_len, TDMA_MAX_XFER_BYTES);
		goto err_out;
	}

	tdmac->status = DMA_IN_PROGRESS;
	tdmac->desc_num = num_periods;
	desc = mmp_tdma_alloc_descriptor(tdmac);
	if (!desc)
		goto err_out;

	while (buf < buf_len) {
		desc = &tdmac->desc_arr[i];

		if (i + 1 == num_periods)
			desc->nxt_desc = tdmac->desc_arr_phys;
		else
			desc->nxt_desc = tdmac->desc_arr_phys +
				sizeof(*desc) * (i + 1);

		if (direction == DMA_MEM_TO_DEV) {
			desc->src_addr = dma_addr;
			desc->dst_addr = tdmac->dev_addr;
		} else {
			desc->src_addr = tdmac->dev_addr;
			desc->dst_addr = dma_addr;
		}
		desc->byte_cnt = period_len;
		dma_addr += period_len;
		buf += period_len;
		i++;
	}

	tdmac->buf_len = buf_len;
	tdmac->period_len = period_len;
	tdmac->pos = 0;

	return &tdmac->desc;

err_out:
	tdmac->status = DMA_ERROR;
	return NULL;
}

static int mmp_tdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
		unsigned long arg)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
	struct dma_slave_config *dmaengine_cfg = (void *)arg;
	int ret = 0;

	switch (cmd) {
	case DMA_TERMINATE_ALL:
		mmp_tdma_disable_chan(tdmac);
		break;
	case DMA_PAUSE:
		mmp_tdma_pause_chan(tdmac);
		break;
	case DMA_RESUME:
		mmp_tdma_resume_chan(tdmac);
		break;
	case DMA_SLAVE_CONFIG:
		if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) {
			tdmac->dev_addr = dmaengine_cfg->src_addr;
			tdmac->burst_sz = dmaengine_cfg->src_maxburst;
			tdmac->buswidth = dmaengine_cfg->src_addr_width;
		} else {
			tdmac->dev_addr = dmaengine_cfg->dst_addr;
			tdmac->burst_sz = dmaengine_cfg->dst_maxburst;
			tdmac->buswidth = dmaengine_cfg->dst_addr_width;
		}
		tdmac->dir = dmaengine_cfg->direction;
		return mmp_tdma_config_chan(tdmac);
	default:
		ret = -ENOSYS;
	}

	return ret;
}

static enum dma_status mmp_tdma_tx_status(struct dma_chan *chan,
			dma_cookie_t cookie, struct dma_tx_state *txstate)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);

	dma_set_residue(txstate, tdmac->buf_len - tdmac->pos);

	return tdmac->status;
}

static void mmp_tdma_issue_pending(struct dma_chan *chan)
{
	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);

	mmp_tdma_enable_chan(tdmac);
}

static int mmp_tdma_remove(struct platform_device *pdev)
{
	struct mmp_tdma_device *tdev = platform_get_drvdata(pdev);

	dma_async_device_unregister(&tdev->device);
	return 0;
}

static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev,
						int idx, int irq, int type)
{
	struct mmp_tdma_chan *tdmac;

	if (idx >= TDMA_CHANNEL_NUM) {
		dev_err(tdev->dev, "too many channels for device!\n");
		return -EINVAL;
	}

	/* alloc channel */
	tdmac = devm_kzalloc(tdev->dev, sizeof(*tdmac), GFP_KERNEL);
	if (!tdmac) {
		dev_err(tdev->dev, "no free memory for DMA channels!\n");
		return -ENOMEM;
	}
	if (irq)
		tdmac->irq = irq;
	tdmac->dev	   = tdev->dev;
	tdmac->chan.device = &tdev->device;
	tdmac->idx	   = idx;
	tdmac->type	   = type;
	tdmac->reg_base	   = (unsigned long)tdev->base + idx * 4;
	tdmac->status = DMA_SUCCESS;
	tdev->tdmac[tdmac->idx] = tdmac;
	tasklet_init(&tdmac->tasklet, dma_do_tasklet, (unsigned long)tdmac);

	/* add the channel to tdma_chan list */
	list_add_tail(&tdmac->chan.device_node,
			&tdev->device.channels);
	return 0;
}

static struct of_device_id mmp_tdma_dt_ids[] = {
	{ .compatible = "marvell,adma-1.0", .data = (void *)MMP_AUD_TDMA},
	{ .compatible = "marvell,pxa910-squ", .data = (void *)PXA910_SQU},
	{}
};
MODULE_DEVICE_TABLE(of, mmp_tdma_dt_ids);

static int mmp_tdma_probe(struct platform_device *pdev)
{
	enum mmp_tdma_type type;
	const struct of_device_id *of_id;
	struct mmp_tdma_device *tdev;
	struct resource *iores;
	int i, ret;
	int irq = 0, irq_num = 0;
	int chan_num = TDMA_CHANNEL_NUM;

	of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev);
	if (of_id)
		type = (enum mmp_tdma_type) of_id->data;
	else
		type = platform_get_device_id(pdev)->driver_data;

	/* always have couple channels */
	tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
	if (!tdev)
		return -ENOMEM;

	tdev->dev = &pdev->dev;

	for (i = 0; i < chan_num; i++) {
		if (platform_get_irq(pdev, i) > 0)
			irq_num++;
	}

	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!iores)
		return -EINVAL;

	tdev->base = devm_request_and_ioremap(&pdev->dev, iores);
	if (!tdev->base)
		return -EADDRNOTAVAIL;

	INIT_LIST_HEAD(&tdev->device.channels);

	if (irq_num != chan_num) {
		irq = platform_get_irq(pdev, 0);
		ret = devm_request_irq(&pdev->dev, irq,
			mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev);
		if (ret)
			return ret;
	}

	/* initialize channel parameters */
	for (i = 0; i < chan_num; i++) {
		irq = (irq_num != chan_num) ? 0 : platform_get_irq(pdev, i);
		ret = mmp_tdma_chan_init(tdev, i, irq, type);
		if (ret)
			return ret;
	}

	dma_cap_set(DMA_SLAVE, tdev->device.cap_mask);
	dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask);
	tdev->device.dev = &pdev->dev;
	tdev->device.device_alloc_chan_resources =
					mmp_tdma_alloc_chan_resources;
	tdev->device.device_free_chan_resources =
					mmp_tdma_free_chan_resources;
	tdev->device.device_prep_dma_cyclic = mmp_tdma_prep_dma_cyclic;
	tdev->device.device_tx_status = mmp_tdma_tx_status;
	tdev->device.device_issue_pending = mmp_tdma_issue_pending;
	tdev->device.device_control = mmp_tdma_control;
	tdev->device.copy_align = TDMA_ALIGNMENT;

	dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
	platform_set_drvdata(pdev, tdev);

	ret = dma_async_device_register(&tdev->device);
	if (ret) {
		dev_err(tdev->device.dev, "unable to register\n");
		return ret;
	}

	dev_info(tdev->device.dev, "initialized\n");
	return 0;
}

static const struct platform_device_id mmp_tdma_id_table[] = {
	{ "mmp-adma",	MMP_AUD_TDMA },
	{ "pxa910-squ",	PXA910_SQU },
	{ },
};

static struct platform_driver mmp_tdma_driver = {
	.driver		= {
		.name	= "mmp-tdma",
		.owner  = THIS_MODULE,
		.of_match_table = mmp_tdma_dt_ids,
	},
	.id_table	= mmp_tdma_id_table,
	.probe		= mmp_tdma_probe,
	.remove		= mmp_tdma_remove,
};

module_platform_driver(mmp_tdma_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MMP Two-Channel DMA Driver");
MODULE_ALIAS("platform:mmp-tdma");
MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
MODULE_AUTHOR("Zhangfei Gao <zhangfei.gao@marvell.com>");
