// SPDX-License-Identifier: GPL-2.0-only
/*
 * OMAP1/OMAP7xx - specific DMA driver
 *
 * Copyright (C) 2003 - 2008 Nokia Corporation
 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
 * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
 * Graphics DMA and LCD DMA graphics tranformations
 * by Imre Deak <imre.deak@nokia.com>
 * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
 * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
 *
 * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
 * Converted DMA library into platform driver
 *                   - G, Manjunath Kondaiah <manjugk@ti.com>
 */

#include <linux/err.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/omap-dma.h>
#include <mach/tc.h>

#include "soc.h"

#define OMAP1_DMA_BASE			(0xfffed800)

static u32 enable_1510_mode;

static const struct omap_dma_reg reg_map[] = {
	[GCR]		= { 0x0400, 0x00, OMAP_DMA_REG_16BIT },
	[GSCR]		= { 0x0404, 0x00, OMAP_DMA_REG_16BIT },
	[GRST1]		= { 0x0408, 0x00, OMAP_DMA_REG_16BIT },
	[HW_ID]		= { 0x0442, 0x00, OMAP_DMA_REG_16BIT },
	[PCH2_ID]	= { 0x0444, 0x00, OMAP_DMA_REG_16BIT },
	[PCH0_ID]	= { 0x0446, 0x00, OMAP_DMA_REG_16BIT },
	[PCH1_ID]	= { 0x0448, 0x00, OMAP_DMA_REG_16BIT },
	[PCHG_ID]	= { 0x044a, 0x00, OMAP_DMA_REG_16BIT },
	[PCHD_ID]	= { 0x044c, 0x00, OMAP_DMA_REG_16BIT },
	[CAPS_0]	= { 0x044e, 0x00, OMAP_DMA_REG_2X16BIT },
	[CAPS_1]	= { 0x0452, 0x00, OMAP_DMA_REG_2X16BIT },
	[CAPS_2]	= { 0x0456, 0x00, OMAP_DMA_REG_16BIT },
	[CAPS_3]	= { 0x0458, 0x00, OMAP_DMA_REG_16BIT },
	[CAPS_4]	= { 0x045a, 0x00, OMAP_DMA_REG_16BIT },
	[PCH2_SR]	= { 0x0460, 0x00, OMAP_DMA_REG_16BIT },
	[PCH0_SR]	= { 0x0480, 0x00, OMAP_DMA_REG_16BIT },
	[PCH1_SR]	= { 0x0482, 0x00, OMAP_DMA_REG_16BIT },
	[PCHD_SR]	= { 0x04c0, 0x00, OMAP_DMA_REG_16BIT },

	/* Common Registers */
	[CSDP]		= { 0x0000, 0x40, OMAP_DMA_REG_16BIT },
	[CCR]		= { 0x0002, 0x40, OMAP_DMA_REG_16BIT },
	[CICR]		= { 0x0004, 0x40, OMAP_DMA_REG_16BIT },
	[CSR]		= { 0x0006, 0x40, OMAP_DMA_REG_16BIT },
	[CEN]		= { 0x0010, 0x40, OMAP_DMA_REG_16BIT },
	[CFN]		= { 0x0012, 0x40, OMAP_DMA_REG_16BIT },
	[CSFI]		= { 0x0014, 0x40, OMAP_DMA_REG_16BIT },
	[CSEI]		= { 0x0016, 0x40, OMAP_DMA_REG_16BIT },
	[CPC]		= { 0x0018, 0x40, OMAP_DMA_REG_16BIT },	/* 15xx only */
	[CSAC]		= { 0x0018, 0x40, OMAP_DMA_REG_16BIT },
	[CDAC]		= { 0x001a, 0x40, OMAP_DMA_REG_16BIT },
	[CDEI]		= { 0x001c, 0x40, OMAP_DMA_REG_16BIT },
	[CDFI]		= { 0x001e, 0x40, OMAP_DMA_REG_16BIT },
	[CLNK_CTRL]	= { 0x0028, 0x40, OMAP_DMA_REG_16BIT },

	/* Channel specific register offsets */
	[CSSA]		= { 0x0008, 0x40, OMAP_DMA_REG_2X16BIT },
	[CDSA]		= { 0x000c, 0x40, OMAP_DMA_REG_2X16BIT },
	[COLOR]		= { 0x0020, 0x40, OMAP_DMA_REG_2X16BIT },
	[CCR2]		= { 0x0024, 0x40, OMAP_DMA_REG_16BIT },
	[LCH_CTRL]	= { 0x002a, 0x40, OMAP_DMA_REG_16BIT },
};

static struct resource res[] __initdata = {
	[0] = {
		.start	= OMAP1_DMA_BASE,
		.end	= OMAP1_DMA_BASE + SZ_2K - 1,
		.flags	= IORESOURCE_MEM,
	},
	[1] = {
		.name   = "0",
		.start  = INT_DMA_CH0_6,
		.flags  = IORESOURCE_IRQ,
	},
	[2] = {
		.name   = "1",
		.start  = INT_DMA_CH1_7,
		.flags  = IORESOURCE_IRQ,
	},
	[3] = {
		.name   = "2",
		.start  = INT_DMA_CH2_8,
		.flags  = IORESOURCE_IRQ,
	},
	[4] = {
		.name   = "3",
		.start  = INT_DMA_CH3,
		.flags  = IORESOURCE_IRQ,
	},
	[5] = {
		.name   = "4",
		.start  = INT_DMA_CH4,
		.flags  = IORESOURCE_IRQ,
	},
	[6] = {
		.name   = "5",
		.start  = INT_DMA_CH5,
		.flags  = IORESOURCE_IRQ,
	},
	/* Handled in lcd_dma.c */
	[7] = {
		.name   = "6",
		.start  = INT_1610_DMA_CH6,
		.flags  = IORESOURCE_IRQ,
	},
	/* irq's for omap16xx and omap7xx */
	[8] = {
		.name   = "7",
		.start  = INT_1610_DMA_CH7,
		.flags  = IORESOURCE_IRQ,
	},
	[9] = {
		.name   = "8",
		.start  = INT_1610_DMA_CH8,
		.flags  = IORESOURCE_IRQ,
	},
	[10] = {
		.name  = "9",
		.start = INT_1610_DMA_CH9,
		.flags = IORESOURCE_IRQ,
	},
	[11] = {
		.name  = "10",
		.start = INT_1610_DMA_CH10,
		.flags = IORESOURCE_IRQ,
	},
	[12] = {
		.name  = "11",
		.start = INT_1610_DMA_CH11,
		.flags = IORESOURCE_IRQ,
	},
	[13] = {
		.name  = "12",
		.start = INT_1610_DMA_CH12,
		.flags = IORESOURCE_IRQ,
	},
	[14] = {
		.name  = "13",
		.start = INT_1610_DMA_CH13,
		.flags = IORESOURCE_IRQ,
	},
	[15] = {
		.name  = "14",
		.start = INT_1610_DMA_CH14,
		.flags = IORESOURCE_IRQ,
	},
	[16] = {
		.name  = "15",
		.start = INT_1610_DMA_CH15,
		.flags = IORESOURCE_IRQ,
	},
	[17] = {
		.name  = "16",
		.start = INT_DMA_LCD,
		.flags = IORESOURCE_IRQ,
	},
};

static void __iomem *dma_base;
static inline void dma_write(u32 val, int reg, int lch)
{
	void __iomem *addr = dma_base;

	addr += reg_map[reg].offset;
	addr += reg_map[reg].stride * lch;

	__raw_writew(val, addr);
	if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
		__raw_writew(val >> 16, addr + 2);
}

static inline u32 dma_read(int reg, int lch)
{
	void __iomem *addr = dma_base;
	uint32_t val;

	addr += reg_map[reg].offset;
	addr += reg_map[reg].stride * lch;

	val = __raw_readw(addr);
	if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
		val |= __raw_readw(addr + 2) << 16;

	return val;
}

static void omap1_clear_lch_regs(int lch)
{
	int i;

	for (i = CPC; i <= COLOR; i += 1)
		dma_write(0, i, lch);
}

static void omap1_clear_dma(int lch)
{
	u32 l;

	l = dma_read(CCR, lch);
	l &= ~OMAP_DMA_CCR_EN;
	dma_write(l, CCR, lch);

	/* Clear pending interrupts */
	l = dma_read(CSR, lch);
}

static void omap1_show_dma_caps(void)
{
	if (enable_1510_mode) {
		printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
	} else {
		u16 w;
		printk(KERN_INFO "OMAP DMA hardware version %d\n",
							dma_read(HW_ID, 0));
		printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
			dma_read(CAPS_0, 0), dma_read(CAPS_1, 0),
			dma_read(CAPS_2, 0), dma_read(CAPS_3, 0),
			dma_read(CAPS_4, 0));

		/* Disable OMAP 3.0/3.1 compatibility mode. */
		w = dma_read(GSCR, 0);
		w |= 1 << 3;
		dma_write(w, GSCR, 0);
	}
}

static unsigned configure_dma_errata(void)
{
	unsigned errata = 0;

	/*
	 * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
	 * read before the DMA controller finished disabling the channel.
	 */
	if (!cpu_is_omap15xx())
		SET_DMA_ERRATA(DMA_ERRATA_3_3);

	return errata;
}

static const struct platform_device_info omap_dma_dev_info = {
	.name = "omap-dma-engine",
	.id = -1,
	.dma_mask = DMA_BIT_MASK(32),
	.res = res,
	.num_res = 1,
};

/* OMAP730, OMAP850 */
static const struct dma_slave_map omap7xx_sdma_map[] = {
	{ "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(8) },
	{ "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(9) },
	{ "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(10) },
	{ "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(11) },
	{ "mmci-omap.0", "tx", SDMA_FILTER_PARAM(21) },
	{ "mmci-omap.0", "rx", SDMA_FILTER_PARAM(22) },
	{ "omap_udc", "rx0", SDMA_FILTER_PARAM(26) },
	{ "omap_udc", "rx1", SDMA_FILTER_PARAM(27) },
	{ "omap_udc", "rx2", SDMA_FILTER_PARAM(28) },
	{ "omap_udc", "tx0", SDMA_FILTER_PARAM(29) },
	{ "omap_udc", "tx1", SDMA_FILTER_PARAM(30) },
	{ "omap_udc", "tx2", SDMA_FILTER_PARAM(31) },
};

/* OMAP1510, OMAP1610*/
static const struct dma_slave_map omap1xxx_sdma_map[] = {
	{ "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(8) },
	{ "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(9) },
	{ "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(10) },
	{ "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(11) },
	{ "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(16) },
	{ "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(17) },
	{ "mmci-omap.0", "tx", SDMA_FILTER_PARAM(21) },
	{ "mmci-omap.0", "rx", SDMA_FILTER_PARAM(22) },
	{ "omap_udc", "rx0", SDMA_FILTER_PARAM(26) },
	{ "omap_udc", "rx1", SDMA_FILTER_PARAM(27) },
	{ "omap_udc", "rx2", SDMA_FILTER_PARAM(28) },
	{ "omap_udc", "tx0", SDMA_FILTER_PARAM(29) },
	{ "omap_udc", "tx1", SDMA_FILTER_PARAM(30) },
	{ "omap_udc", "tx2", SDMA_FILTER_PARAM(31) },
	{ "mmci-omap.1", "tx", SDMA_FILTER_PARAM(54) },
	{ "mmci-omap.1", "rx", SDMA_FILTER_PARAM(55) },
};

static struct omap_system_dma_plat_info dma_plat_info __initdata = {
	.reg_map	= reg_map,
	.channel_stride	= 0x40,
	.show_dma_caps	= omap1_show_dma_caps,
	.clear_lch_regs	= omap1_clear_lch_regs,
	.clear_dma	= omap1_clear_dma,
	.dma_write	= dma_write,
	.dma_read	= dma_read,
};

static int __init omap1_system_dma_init(void)
{
	struct omap_system_dma_plat_info	p;
	struct omap_dma_dev_attr		*d;
	struct platform_device			*pdev, *dma_pdev;
	int ret;

	pdev = platform_device_alloc("omap_dma_system", 0);
	if (!pdev) {
		pr_err("%s: Unable to device alloc for dma\n",
			__func__);
		return -ENOMEM;
	}

	dma_base = ioremap(res[0].start, resource_size(&res[0]));
	if (!dma_base) {
		pr_err("%s: Unable to ioremap\n", __func__);
		ret = -ENODEV;
		goto exit_device_put;
	}

	ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
	if (ret) {
		dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
			__func__, pdev->name, pdev->id);
		goto exit_iounmap;
	}

	d = kzalloc(sizeof(*d), GFP_KERNEL);
	if (!d) {
		ret = -ENOMEM;
		goto exit_iounmap;
	}

	/* Valid attributes for omap1 plus processors */
	if (cpu_is_omap15xx())
		d->dev_caps = ENABLE_1510_MODE;
	enable_1510_mode = d->dev_caps & ENABLE_1510_MODE;

	if (cpu_is_omap16xx())
		d->dev_caps = ENABLE_16XX_MODE;

	d->dev_caps		|= SRC_PORT;
	d->dev_caps		|= DST_PORT;
	d->dev_caps		|= SRC_INDEX;
	d->dev_caps		|= DST_INDEX;
	d->dev_caps		|= IS_BURST_ONLY4;
	d->dev_caps		|= CLEAR_CSR_ON_READ;
	d->dev_caps		|= IS_WORD_16;

	/* available logical channels */
	if (cpu_is_omap15xx()) {
		d->lch_count = 9;
	} else {
		if (d->dev_caps & ENABLE_1510_MODE)
			d->lch_count = 9;
		else
			d->lch_count = 16;
	}

	p = dma_plat_info;
	p.dma_attr = d;
	p.errata = configure_dma_errata();

	if (cpu_is_omap7xx()) {
		p.slave_map = omap7xx_sdma_map;
		p.slavecnt = ARRAY_SIZE(omap7xx_sdma_map);
	} else {
		p.slave_map = omap1xxx_sdma_map;
		p.slavecnt = ARRAY_SIZE(omap1xxx_sdma_map);
	}

	ret = platform_device_add_data(pdev, &p, sizeof(p));
	if (ret) {
		dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
			__func__, pdev->name, pdev->id);
		goto exit_release_d;
	}

	ret = platform_device_add(pdev);
	if (ret) {
		dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
			__func__, pdev->name, pdev->id);
		goto exit_release_d;
	}

	dma_pdev = platform_device_register_full(&omap_dma_dev_info);
	if (IS_ERR(dma_pdev)) {
		ret = PTR_ERR(dma_pdev);
		goto exit_release_pdev;
	}

	return ret;

exit_release_pdev:
	platform_device_del(pdev);
exit_release_d:
	kfree(d);
exit_iounmap:
	iounmap(dma_base);
exit_device_put:
	platform_device_put(pdev);

	return ret;
}
arch_initcall(omap1_system_dma_init);
