/*
 * Copyright (C) 2012-2015 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright 2018 NXP
 *
 * 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:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/ipu.h>
#include <linux/genalloc.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/types.h>

#include "vdoa.h"
/* 6band(3field* double buffer) * (width*2) * bandline(8)
	= 6x1024x2x8 = 96k or 72k(1.5byte) */
#define MAX_VDOA_IRAM_SIZE	(1024*96)
#define VDOA_IRAM_SIZE		(1024*72)

#define VDOAC_BAND_HEIGHT_32LINES	(32)
#define VDOAC_BAND_HEIGHT_16LINES	(16)
#define VDOAC_BAND_HEIGHT_8LINES	(8)
#define VDOAC_THREE_FRAMES		(0x1 << 2)
#define VDOAC_SYNC_BAND_MODE		(0x1 << 3)
#define VDOAC_SCAN_ORDER_INTERLACED	(0x1 << 4)
#define VDOAC_PFS_YUYV			(0x1 << 5)
#define VDOAC_IPU_SEL_1			(0x1 << 6)
#define VDOAFP_FH_MASK			(0x1FFF)
#define VDOAFP_FH_SHIFT			(16)
#define VDOAFP_FW_MASK			(0x3FFF)
#define VDOAFP_FW_SHIFT			(0)
#define VDOASL_VSLY_MASK		(0x3FFF)
#define VDOASL_VSLY_SHIFT		(16)
#define VDOASL_ISLY_MASK		(0x7FFF)
#define VDOASL_ISLY_SHIFT		(0)
#define VDOASRR_START_XFER		(0x2)
#define VDOASRR_SWRST			(0x1)
#define VDOAIEIST_TRANSFER_ERR		(0x2)
#define VDOAIEIST_TRANSFER_END		(0x1)

#define	VDOAC		(0x0)	/* Control Register */
#define	VDOASRR		(0x4)	/* Start and Reset Register */
#define	VDOAIE		(0x8)	/* Interrupt Enable Register */
#define	VDOAIST		(0xc)	/* Interrupt Status Register */
#define	VDOAFP		(0x10)	/* Frame Parameters Register */
#define	VDOAIEBA00	(0x14)	/* External Buffer n Frame m Address Register */
#define	VDOAIEBA01	(0x18)	/* External Buffer n Frame m Address Register */
#define	VDOAIEBA02	(0x1c)	/* External Buffer n Frame m Address Register */
#define	VDOAIEBA10	(0x20)	/* External Buffer n Frame m Address Register */
#define	VDOAIEBA11	(0x24)	/* External Buffer n Frame m Address Register */
#define	VDOAIEBA12	(0x28)	/* External Buffer n Frame m Address Register */
#define	VDOASL		(0x2c)	/* IPU Stride Line Register */
#define	VDOAIUBO	(0x30)	/* IPU Chroma Buffer Offset Register */
#define	VDOAVEBA0	(0x34)	/* External Buffer m Address Register */
#define	VDOAVEBA1	(0x38)	/* External Buffer m Address Register */
#define	VDOAVEBA2	(0x3c)	/* External Buffer m Address Register */
#define	VDOAVUBO	(0x40)	/* VPU Chroma Buffer Offset */
#define	VDOASR		(0x44)	/* Status Register */
#define	VDOATD		(0x48)	/* Test Debug Register */


enum {
	VDOA_INIT	= 0x1,
	VDOA_GET	= 0x2,
	VDOA_SETUP	= 0x4,
	VDOA_GET_OBUF	= 0x8,
	VDOA_START	= 0x10,
	VDOA_INIRQ	= 0x20,
	VDOA_STOP	= 0x40,
	VDOA_PUT	= VDOA_INIT,
};

enum {
	VDOA_NULL	= 0,
	VDOA_FRAME	= 1,
	VDOA_PREV_FIELD	= 2,
	VDOA_CURR_FIELD	= 3,
	VDOA_NEXT_FIELD	= 4,
};

#define CHECK_STATE(expect, retcode)					\
do {									\
	if (!((expect) & vdoa->state)) {				\
		dev_err(vdoa->dev, "ERR: %s state:0x%x, expect:0x%x.\n",\
				__func__, vdoa->state, (expect));	\
		retcode;						\
	}								\
} while (0)

#define CHECK_NULL_PTR(ptr)						\
do {									\
	pr_debug("vdoa_ptr:0x%p in %s state:0x%x.\n",			\
			vdoa, __func__, vdoa->state);			\
	if (NULL == (ptr)) {						\
		pr_err("ERR vdoa: %s state:0x%x null ptr.\n",		\
				__func__, vdoa->state);			\
	}								\
} while (0)

struct vdoa_info {
	int		state;
	struct device	*dev;
	struct clk	*vdoa_clk;
	void __iomem	*reg_base;
	struct gen_pool	*iram_pool;
	unsigned long	iram_base;
	unsigned long	iram_paddr;
	int		irq;
	int		field;
	struct completion comp;
};

static struct vdoa_info *g_vdoa;
static unsigned long iram_size;
static DEFINE_MUTEX(vdoa_lock);

static inline void vdoa_read_register(struct vdoa_info *vdoa,
				u32 reg, u32 *val)
{
	*val = ioread32(vdoa->reg_base + reg);
	dev_dbg(vdoa->dev, "read_reg:0x%02x, val:0x%08x.\n", reg, *val);
}

static inline void vdoa_write_register(struct vdoa_info *vdoa,
				u32 reg, u32 val)
{
	iowrite32(val, vdoa->reg_base + reg);
	dev_dbg(vdoa->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n", reg, val);
}

static void dump_registers(struct vdoa_info *vdoa)
{
	int i;
	u32 data;

	for (i = VDOAC; i < VDOATD; i += 4)
		vdoa_read_register(vdoa, i, &data);
}

int vdoa_setup(vdoa_handle_t handle, struct vdoa_params *params)
{
	int	band_size;
	int	total_band_size = 0;
	int	ipu_stride;
	u32	data;
	struct vdoa_info *vdoa = (struct vdoa_info *)handle;

	CHECK_NULL_PTR(vdoa);
	CHECK_STATE(VDOA_GET | VDOA_GET_OBUF | VDOA_STOP, return -EINVAL);
	if (VDOA_GET == vdoa->state) {
		dev_dbg(vdoa->dev, "w:%d, h:%d.\n",
			 params->width, params->height);
		data = (params->band_lines == VDOAC_BAND_HEIGHT_32LINES) ? 2 :
			((params->band_lines == VDOAC_BAND_HEIGHT_16LINES) ?
				 1 : 0);
		data |= params->scan_order ? VDOAC_SCAN_ORDER_INTERLACED : 0;
		data |= params->band_mode ? VDOAC_SYNC_BAND_MODE : 0;
		data |= params->pfs ? VDOAC_PFS_YUYV : 0;
		data |= params->ipu_num ? VDOAC_IPU_SEL_1 : 0;
		vdoa_write_register(vdoa, VDOAC, data);

		data = ((params->width & VDOAFP_FW_MASK) << VDOAFP_FW_SHIFT) |
			((params->height & VDOAFP_FH_MASK) << VDOAFP_FH_SHIFT);
		vdoa_write_register(vdoa, VDOAFP, data);

		ipu_stride = params->pfs ? params->width << 1 : params->width;
		data = ((params->vpu_stride & VDOASL_VSLY_MASK) <<
							VDOASL_VSLY_SHIFT) |
			((ipu_stride & VDOASL_ISLY_MASK) << VDOASL_ISLY_SHIFT);
		vdoa_write_register(vdoa, VDOASL, data);

		dev_dbg(vdoa->dev, "band_mode:%d, band_line:%d, base:0x%lx.\n",
		params->band_mode, params->band_lines, vdoa->iram_paddr);
	}
	/*
	 * band size	= (luma_per_line + chroma_per_line) * bandLines
	 *		= width * (3/2 or 2) * bandLines
	 * double buffer mode used.
	 */
	if (params->pfs)
		band_size = (params->width << 1) * params->band_lines;
	else
		band_size = ((params->width * 3) >> 1) *
						params->band_lines;
	if (params->interlaced) {
		total_band_size = 6 * band_size; /* 3 frames*double buffer */
		if (iram_size < total_band_size) {
			dev_err(vdoa->dev, "iram_size:0x%lx is smaller than "
				"request:0x%x!\n", iram_size, total_band_size);
			return -EINVAL;
		}
		if (params->vfield_buf.prev_veba) {
			if (params->band_mode) {
				vdoa_write_register(vdoa, VDOAIEBA00,
							vdoa->iram_paddr);
				vdoa_write_register(vdoa, VDOAIEBA10,
						 vdoa->iram_paddr + band_size);
			} else
				vdoa_write_register(vdoa, VDOAIEBA00,
							params->ieba0);
			vdoa_write_register(vdoa, VDOAVEBA0,
					params->vfield_buf.prev_veba);
			vdoa->field = VDOA_PREV_FIELD;
		}
		if (params->vfield_buf.cur_veba) {
			if (params->band_mode) {
				vdoa_write_register(vdoa, VDOAIEBA01,
					 vdoa->iram_paddr + band_size * 2);
				vdoa_write_register(vdoa, VDOAIEBA11,
					 vdoa->iram_paddr + band_size * 3);
			} else
				vdoa_write_register(vdoa, VDOAIEBA01,
							params->ieba1);
			vdoa_write_register(vdoa, VDOAVEBA1,
					params->vfield_buf.cur_veba);
			vdoa->field = VDOA_CURR_FIELD;
		}
		if (params->vfield_buf.next_veba) {
			if (params->band_mode) {
				vdoa_write_register(vdoa, VDOAIEBA02,
					 vdoa->iram_paddr + band_size * 4);
				vdoa_write_register(vdoa, VDOAIEBA12,
					 vdoa->iram_paddr + band_size * 5);
			} else
				vdoa_write_register(vdoa, VDOAIEBA02,
							params->ieba2);
			vdoa_write_register(vdoa, VDOAVEBA2,
					params->vfield_buf.next_veba);
			vdoa->field = VDOA_NEXT_FIELD;
			vdoa_read_register(vdoa, VDOAC, &data);
			data |= VDOAC_THREE_FRAMES;
			vdoa_write_register(vdoa, VDOAC, data);
		}

		if (!params->pfs)
			vdoa_write_register(vdoa, VDOAIUBO,
				 params->width * params->band_lines);
		vdoa_write_register(vdoa, VDOAVUBO,
				 params->vfield_buf.vubo);
		dev_dbg(vdoa->dev, "total band_size:0x%x.\n", band_size*6);
	} else if (params->band_mode) {
		/* used for progressive frame resize on PrP channel */
		BUG(); /* currently not support */
		/* progressvie frame: band mode */
		vdoa_write_register(vdoa, VDOAIEBA00, vdoa->iram_paddr);
		vdoa_write_register(vdoa, VDOAIEBA10,
					 vdoa->iram_paddr + band_size);
		if (!params->pfs)
			vdoa_write_register(vdoa, VDOAIUBO,
					params->width * params->band_lines);
		dev_dbg(vdoa->dev, "total band_size:0x%x\n", band_size*2);
	} else {
		/* progressive frame: mem->mem, non-band mode */
		vdoa->field = VDOA_FRAME;
		vdoa_write_register(vdoa, VDOAVEBA0, params->vframe_buf.veba);
		vdoa_write_register(vdoa, VDOAVUBO, params->vframe_buf.vubo);
		vdoa_write_register(vdoa, VDOAIEBA00, params->ieba0);
		if (!params->pfs)
			/* note: iubo is relative value, based on ieba0 */
			vdoa_write_register(vdoa, VDOAIUBO,
					params->width * params->height);
	}
	vdoa->state = VDOA_SETUP;
	return 0;
}

void vdoa_get_output_buf(vdoa_handle_t handle, struct vdoa_ipu_buf *buf)
{
	u32	data;
	struct vdoa_info *vdoa = (struct vdoa_info *)handle;

	CHECK_NULL_PTR(vdoa);
	CHECK_STATE(VDOA_SETUP, return);
	vdoa->state = VDOA_GET_OBUF;
	memset(buf, 0, sizeof(*buf));

	vdoa_read_register(vdoa, VDOAC, &data);
	switch (vdoa->field) {
	case VDOA_FRAME:
	case VDOA_PREV_FIELD:
		vdoa_read_register(vdoa, VDOAIEBA00, &buf->ieba0);
		if (data & VDOAC_SYNC_BAND_MODE)
			vdoa_read_register(vdoa, VDOAIEBA10, &buf->ieba1);
		break;
	case VDOA_CURR_FIELD:
		vdoa_read_register(vdoa, VDOAIEBA01, &buf->ieba0);
		vdoa_read_register(vdoa, VDOAIEBA11, &buf->ieba1);
		break;
	case VDOA_NEXT_FIELD:
		vdoa_read_register(vdoa, VDOAIEBA02, &buf->ieba0);
		vdoa_read_register(vdoa, VDOAIEBA12, &buf->ieba1);
		break;
	default:
		BUG();
		break;
	}
	if (!(data & VDOAC_PFS_YUYV))
		vdoa_read_register(vdoa, VDOAIUBO, &buf->iubo);
}

int vdoa_start(vdoa_handle_t handle, int timeout_ms)
{
	int ret;
	struct vdoa_info *vdoa = (struct vdoa_info *)handle;

	CHECK_NULL_PTR(vdoa);
	CHECK_STATE(VDOA_GET_OBUF, return -EINVAL);
	vdoa->state = VDOA_START;
	init_completion(&vdoa->comp);
	vdoa_write_register(vdoa, VDOAIST,
			VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);
	vdoa_write_register(vdoa, VDOAIE,
			VDOAIEIST_TRANSFER_ERR | VDOAIEIST_TRANSFER_END);

	enable_irq(vdoa->irq);
	vdoa_write_register(vdoa, VDOASRR, VDOASRR_START_XFER);
	dump_registers(vdoa);

	ret = wait_for_completion_timeout(&vdoa->comp,
			msecs_to_jiffies(timeout_ms));

	return ret > 0 ? 0 : -ETIMEDOUT;
}

void vdoa_stop(vdoa_handle_t handle)
{
	struct vdoa_info *vdoa = (struct vdoa_info *)handle;

	CHECK_NULL_PTR(vdoa);
	CHECK_STATE(VDOA_GET | VDOA_START | VDOA_INIRQ, return);
	vdoa->state = VDOA_STOP;

	disable_irq(vdoa->irq);

	vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);
}

void vdoa_get_handle(vdoa_handle_t *handle)
{
	struct vdoa_info *vdoa = g_vdoa;

	CHECK_NULL_PTR(handle);
	*handle = (vdoa_handle_t *)NULL;
	CHECK_STATE(VDOA_INIT, return);
	mutex_lock(&vdoa_lock);
	clk_prepare_enable(vdoa->vdoa_clk);
	vdoa->state = VDOA_GET;
	vdoa->field = VDOA_NULL;
	vdoa_write_register(vdoa, VDOASRR, VDOASRR_SWRST);

	*handle = (vdoa_handle_t *)vdoa;
}

void vdoa_put_handle(vdoa_handle_t *handle)
{
	struct vdoa_info *vdoa = (struct vdoa_info *)(*handle);

	CHECK_NULL_PTR(vdoa);
	CHECK_STATE(VDOA_STOP, return);
	if (vdoa != g_vdoa)
		BUG();

	clk_disable_unprepare(vdoa->vdoa_clk);
	vdoa->state = VDOA_PUT;
	*handle = (vdoa_handle_t *)NULL;
	mutex_unlock(&vdoa_lock);
}

static irqreturn_t vdoa_irq_handler(int irq, void *data)
{
	u32 status, mask, val;
	struct vdoa_info *vdoa = data;

	CHECK_NULL_PTR(vdoa);
	CHECK_STATE(VDOA_START, return IRQ_HANDLED);
	vdoa->state = VDOA_INIRQ;
	vdoa_read_register(vdoa, VDOAIST, &status);
	vdoa_read_register(vdoa, VDOAIE, &mask);
	val = status & mask;
	vdoa_write_register(vdoa, VDOAIST, val);
	if (VDOAIEIST_TRANSFER_ERR & val)
		dev_err(vdoa->dev, "vdoa Transfer err irq!\n");
	if (VDOAIEIST_TRANSFER_END & val)
		dev_dbg(vdoa->dev, "vdoa Transfer end irq!\n");
	if (0 == val) {
		dev_err(vdoa->dev, "vdoa unknown irq!\n");
		BUG();
	}

	complete(&vdoa->comp);
	return IRQ_HANDLED;
}

/* IRAM Size in Kbytes, example:vdoa_iram_size=64, 64KBytes */
static int __init vdoa_iram_size_setup(char *options)
{
	int ret;

	ret = kstrtoul(options, 0, &iram_size);
	if (ret)
		iram_size = 0;
	else
		iram_size *= SZ_1K;

	return 1;
}
__setup("vdoa_iram_size=", vdoa_iram_size_setup);

static const struct of_device_id imx_vdoa_dt_ids[] = {
	{ .compatible = "fsl,imx6q-vdoa", },
	{ /* sentinel */ }
};

static int vdoa_probe(struct platform_device *pdev)
{
	int ret;
	struct vdoa_info *vdoa;
	struct resource *res;
	struct resource *res_irq;
	struct device	*dev = &pdev->dev;
	struct device_node *np = pdev->dev.of_node;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "can't get device resources\n");
		return -ENOENT;
	}

	res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res_irq) {
		dev_err(dev, "failed to get irq resource\n");
		return -ENOENT;
	}

	vdoa = devm_kzalloc(dev, sizeof(struct vdoa_info), GFP_KERNEL);
	if (!vdoa)
		return -ENOMEM;
	vdoa->dev = dev;

	vdoa->reg_base = devm_ioremap_resource(&pdev->dev, res);
	if (!vdoa->reg_base)
		return -EBUSY;

	vdoa->irq = res_irq->start;
	ret = devm_request_irq(dev, vdoa->irq, vdoa_irq_handler, 0,
				"vdoa", vdoa);
	if (ret) {
		dev_err(dev, "can't claim irq %d\n", vdoa->irq);
		return ret;
	}
	disable_irq(vdoa->irq);

	vdoa->vdoa_clk = devm_clk_get(dev, NULL);
	if (IS_ERR(vdoa->vdoa_clk)) {
		dev_err(dev, "failed to get vdoa_clk\n");
		return PTR_ERR(vdoa->vdoa_clk);
	}

	vdoa->iram_pool = of_gen_pool_get(np, "iram", 0);
	if (!vdoa->iram_pool) {
		dev_err(&pdev->dev, "iram pool not available\n");
		return -ENOMEM;
	}

	if ((iram_size == 0) || (iram_size > MAX_VDOA_IRAM_SIZE))
		iram_size = VDOA_IRAM_SIZE;

	vdoa->iram_base = gen_pool_alloc(vdoa->iram_pool, iram_size);
	if (!vdoa->iram_base) {
		dev_err(&pdev->dev, "unable to alloc iram\n");
		return -ENOMEM;
	}

	vdoa->iram_paddr = gen_pool_virt_to_phys(vdoa->iram_pool,
						 vdoa->iram_base);

	dev_dbg(dev, "iram_base:0x%lx,iram_paddr:0x%lx,size:0x%lx\n",
		 vdoa->iram_base, vdoa->iram_paddr, iram_size);

	vdoa->state = VDOA_INIT;
	dev_set_drvdata(dev, vdoa);
	g_vdoa = vdoa;
	dev_info(dev, "i.MX Video Data Order Adapter(VDOA) driver probed\n");
	return 0;
}

static int vdoa_remove(struct platform_device *pdev)
{
	struct vdoa_info *vdoa = dev_get_drvdata(&pdev->dev);

	gen_pool_free(vdoa->iram_pool, vdoa->iram_base, iram_size);
	kfree(vdoa);
	dev_set_drvdata(&pdev->dev, NULL);

	return 0;
}

static struct platform_driver vdoa_driver = {
	.driver = {
		.name = "mxc_vdoa",
		.of_match_table = imx_vdoa_dt_ids,
	},
	.probe = vdoa_probe,
	.remove = vdoa_remove,
};

static int __init vdoa_init(void)
{
	int err;

	err = platform_driver_register(&vdoa_driver);
	if (err) {
		pr_err("vdoa_driver register failed\n");
		return -ENODEV;
	}
	return 0;
}

static void __exit vdoa_cleanup(void)
{
	platform_driver_unregister(&vdoa_driver);
}

subsys_initcall(vdoa_init);
module_exit(vdoa_cleanup);

MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("i.MX Video Data Order Adapter(VDOA) driver");
MODULE_LICENSE("GPL");
