/*
 *
 * BRIEF MODULE DESCRIPTION
 *      A DMA channel allocator for Au1000. API is modeled loosely off of
 *      linux/kernel/dma.c.
 *
 * Copyright 2000 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *         	stevel@mvista.com or 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/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/system.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h>

#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1100)
/*
 * 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.
 */


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] = {
	{UART0_ADDR + UART_TX, 0},
	{UART0_ADDR + UART_RX, 0},
	{0, 0},
	{0, 0},
	{AC97C_DATA, DMA_DW16 },          // coherent
	{AC97C_DATA, DMA_DR | DMA_DW16 }, // coherent
	{UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
	{UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
	{USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
	{USBD_EP0WR, DMA_DW8 | DMA_NC},
	{USBD_EP2WR, DMA_DW8 | DMA_NC},
	{USBD_EP3WR, DMA_DW8 | DMA_NC},
	{USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC},
	{USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC},
	{I2S_DATA, DMA_DW32 | DMA_NC},
	{I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC}
};

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++) {
		if ((chan = get_dma_chan(i)) != NULL) {
			len += sprintf(buf + len, "%2d: %s\n",
				       i, chan->dev_str);
		}
	}

	if (fpos >= len) {
		*start = buf;
		*eof = 1;
		return 0;
	}
	*start = buf + fpos;
	if ((len -= fpos) > 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] = {
	{SD0_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
	{SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8},	// coherent
	{SD1_XMIT_FIFO, DMA_DS | DMA_DW8},		// coherent
	{SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8}	// coherent
};

void dump_au1000_dma_channel(unsigned int dmanr)
{
	struct dma_chan *chan;

	if (dmanr >= NUM_AU1000_DMA_CHANNELS)
		return;
	chan = &au1000_dma_table[dmanr];

	printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr);
	printk(KERN_INFO "  mode = 0x%08x\n",
	       au_readl(chan->io + DMA_MODE_SET));
	printk(KERN_INFO "  addr = 0x%08x\n",
	       au_readl(chan->io + DMA_PERIPHERAL_ADDR));
	printk(KERN_INFO "  start0 = 0x%08x\n",
	       au_readl(chan->io + DMA_BUFFER0_START));
	printk(KERN_INFO "  start1 = 0x%08x\n",
	       au_readl(chan->io + DMA_BUFFER1_START));
	printk(KERN_INFO "  count0 = 0x%08x\n",
	       au_readl(chan->io + DMA_BUFFER0_COUNT));
	printk(KERN_INFO "  count1 = 0x%08x\n",
	       au_readl(chan->io + DMA_BUFFER1_COUNT));
}


/*
 * 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,
		       irqreturn_t (*irqhandler)(int, void *, struct pt_regs *),
		       unsigned long irqflags,
		       void *irq_dev_id)
{
	struct dma_chan *chan;
	const struct dma_dev *dev;
	int i, ret;

#if defined(CONFIG_SOC_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;
#endif

	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 = AU1000_DMA_INT_BASE + i;
		chan->irq_dev = irq_dev_id;
		if ((ret = request_irq(chan->irq, irqhandler, irqflags,
				       dev_str, chan->irq_dev))) {
			chan->irq = 0;
			chan->irq_dev = NULL;
			return ret;
		}
	} else {
		chan->irq = 0;
		chan->irq_dev = NULL;
	}

	// fill it in
	chan->io = DMA_CHANNEL_BASE + 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("Trying to free DMA%d\n", dmanr);
		return;
	}

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

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

#endif // AU1000 AU1500 AU1100
