/*
 *
 * BRIEF MODULE DESCRIPTION
 *      A DMA channel allocator for Au1x00. API is modeled loosely off of
 *      linux/kernel/dma.c.
 *
 * Copyright 2000, 2008 MontaVista Software Inc.
 * Author: MontaVista Software, Inc. <source@mvista.com>
 * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <linux/init.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>

#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h>

/*
 * A note on resource allocation:
 *
 * All drivers needing DMA channels, should allocate and release them
 * through the public routines `request_dma()' and `free_dma()'.
 *
 * In order to avoid problems, all processes should allocate resources in
 * the same sequence and release them in the reverse order.
 *
 * So, when allocating DMAs and IRQs, first allocate the DMA, then the IRQ.
 * When releasing them, first release the IRQ, then release the DMA. The
 * main reason for this order is that, if you are requesting the DMA buffer
 * done interrupt, you won't know the irq number until the DMA channel is
 * returned from request_dma.
 */

/* DMA Channel register block spacing */
#define DMA_CHANNEL_LEN		0x00000100

DEFINE_SPINLOCK(au1000_dma_spin_lock);

struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
      {.dev_id = -1,},
      {.dev_id = -1,},
      {.dev_id = -1,},
      {.dev_id = -1,},
      {.dev_id = -1,},
      {.dev_id = -1,},
      {.dev_id = -1,},
      {.dev_id = -1,}
};
EXPORT_SYMBOL(au1000_dma_table);

/* Device FIFO addresses and default DMA modes */
static const struct dma_dev {
	unsigned int fifo_addr;
	unsigned int dma_mode;
} dma_dev_table[DMA_NUM_DEV] = {
	{ AU1000_UART0_PHYS_ADDR + 0x04, DMA_DW8 },		/* UART0_TX */
	{ AU1000_UART0_PHYS_ADDR + 0x00, DMA_DW8 | DMA_DR },	/* UART0_RX */
	{ 0, 0 },	/* DMA_REQ0 */
	{ 0, 0 },	/* DMA_REQ1 */
	{ AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 },		/* AC97 TX c */
	{ AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR },	/* AC97 RX c */
	{ AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC },	/* UART3_TX */
	{ AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */
	{ AU1000_USB_UDC_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */
	{ AU1000_USB_UDC_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */
	{ AU1000_USB_UDC_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */
	{ AU1000_USB_UDC_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */
	{ AU1000_USB_UDC_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */
	{ AU1000_USB_UDC_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */
	/* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */
	{ AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC},	/* I2S TX */
	{ AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */
};

int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
			 int length, int *eof, void *data)
{
	int i, len = 0;
	struct dma_chan *chan;

	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) {
		chan = get_dma_chan(i);
		if (chan != NULL)
			len += sprintf(buf + len, "%2d: %s\n",
				       i, chan->dev_str);
	}

	if (fpos >= len) {
		*start = buf;
		*eof = 1;
		return 0;
	}
	*start = buf + fpos;
	len -= fpos;
	if (len > length)
		return length;
	*eof = 1;
	return len;
}

/* Device FIFO addresses and default DMA modes - 2nd bank */
static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
	{ AU1100_SD0_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 },		/* coherent */
	{ AU1100_SD0_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR },	/* coherent */
	{ AU1100_SD1_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 },		/* coherent */
	{ AU1100_SD1_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR }	/* coherent */
};

/*
 * Finds a free channel, and binds the requested device to it.
 * Returns the allocated channel number, or negative on error.
 * Requests the DMA done IRQ if irqhandler != NULL.
 */
int request_au1000_dma(int dev_id, const char *dev_str,
		       irq_handler_t irqhandler,
		       unsigned long irqflags,
		       void *irq_dev_id)
{
	struct dma_chan *chan;
	const struct dma_dev *dev;
	int i, ret;

	if (alchemy_get_cputype() == ALCHEMY_CPU_AU1100) {
		if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
			return -EINVAL;
	} else {
		if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
			return -EINVAL;
	}

	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
		if (au1000_dma_table[i].dev_id < 0)
			break;

	if (i == NUM_AU1000_DMA_CHANNELS)
		return -ENODEV;

	chan = &au1000_dma_table[i];

	if (dev_id >= DMA_NUM_DEV) {
		dev_id -= DMA_NUM_DEV;
		dev = &dma_dev_table_bank2[dev_id];
	} else
		dev = &dma_dev_table[dev_id];

	if (irqhandler) {
		chan->irq_dev = irq_dev_id;
		ret = request_irq(chan->irq, irqhandler, irqflags, dev_str,
				  chan->irq_dev);
		if (ret) {
			chan->irq_dev = NULL;
			return ret;
		}
	} else {
		chan->irq_dev = NULL;
	}

	/* fill it in */
	chan->io = (void __iomem *)(KSEG1ADDR(AU1000_DMA_PHYS_ADDR) +
			i * DMA_CHANNEL_LEN);
	chan->dev_id = dev_id;
	chan->dev_str = dev_str;
	chan->fifo_addr = dev->fifo_addr;
	chan->mode = dev->dma_mode;

	/* initialize the channel before returning */
	init_dma(i);

	return i;
}
EXPORT_SYMBOL(request_au1000_dma);

void free_au1000_dma(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);

	if (!chan) {
		printk(KERN_ERR "Error trying to free DMA%d\n", dmanr);
		return;
	}

	disable_dma(dmanr);
	if (chan->irq_dev)
		free_irq(chan->irq, chan->irq_dev);

	chan->irq_dev = NULL;
	chan->dev_id = -1;
}
EXPORT_SYMBOL(free_au1000_dma);

static int __init au1000_dma_init(void)
{
	int base, i;

	switch (alchemy_get_cputype()) {
	case ALCHEMY_CPU_AU1000:
		base = AU1000_DMA_INT_BASE;
		break;
	case ALCHEMY_CPU_AU1500:
		base = AU1500_DMA_INT_BASE;
		break;
	case ALCHEMY_CPU_AU1100:
		base = AU1100_DMA_INT_BASE;
		break;
	default:
		goto out;
	}

	for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
		au1000_dma_table[i].irq = base + i;

	printk(KERN_INFO "Alchemy DMA initialized\n");

out:
	return 0;
}
arch_initcall(au1000_dma_init);
