/*
 * BRIEF MODULE DESCRIPTION
 *	Defines for using and allocating dma channels on the Alchemy
 *      Au1000 mips processor.
 *
 * Copyright 2000 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *         	stevel@mvista.com or source@mvista.com
 *
 *  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.
 *
 */
#ifndef __ASM_AU1000_DMA_H
#define __ASM_AU1000_DMA_H

#include <linux/config.h>
#include <asm/io.h>		/* need byte IO */
#include <linux/spinlock.h>	/* And spinlocks */
#include <linux/delay.h>
#include <asm/system.h>

#define NUM_AU1000_DMA_CHANNELS	8

/* DMA Channel Base Addresses */
#define DMA_CHANNEL_BASE	0xB4002000
#define DMA_CHANNEL_LEN		0x00000100

/* DMA Channel Register Offsets */
#define DMA_MODE_SET		0x00000000
#define DMA_MODE_READ		DMA_MODE_SET
#define DMA_MODE_CLEAR		0x00000004
/* DMA Mode register bits follow */
#define DMA_DAH_MASK		(0x0f << 20)
#define DMA_DID_BIT		16
#define DMA_DID_MASK		(0x0f << DMA_DID_BIT)
#define DMA_DS			(1<<15)
#define DMA_BE			(1<<13)
#define DMA_DR			(1<<12)
#define DMA_TS8			(1<<11)
#define DMA_DW_BIT		9
#define DMA_DW_MASK		(0x03 << DMA_DW_BIT)
#define DMA_DW8			(0 << DMA_DW_BIT)
#define DMA_DW16		(1 << DMA_DW_BIT)
#define DMA_DW32		(2 << DMA_DW_BIT)
#define DMA_NC			(1<<8)
#define DMA_IE			(1<<7)
#define DMA_HALT		(1<<6)
#define DMA_GO			(1<<5)
#define DMA_AB			(1<<4)
#define DMA_D1			(1<<3)
#define DMA_BE1			(1<<2)
#define DMA_D0			(1<<1)
#define DMA_BE0			(1<<0)

#define DMA_PERIPHERAL_ADDR       0x00000008
#define DMA_BUFFER0_START         0x0000000C
#define DMA_BUFFER1_START         0x00000014
#define DMA_BUFFER0_COUNT         0x00000010
#define DMA_BUFFER1_COUNT         0x00000018
#define DMA_BAH_BIT 16
#define DMA_BAH_MASK (0x0f << DMA_BAH_BIT)
#define DMA_COUNT_BIT 0
#define DMA_COUNT_MASK (0xffff << DMA_COUNT_BIT)

/* DMA Device ID's follow */
enum {
	DMA_ID_UART0_TX = 0,
	DMA_ID_UART0_RX,
	DMA_ID_GP04,
	DMA_ID_GP05,
	DMA_ID_AC97C_TX,
	DMA_ID_AC97C_RX,
	DMA_ID_UART3_TX,
	DMA_ID_UART3_RX,
	DMA_ID_USBDEV_EP0_RX,
	DMA_ID_USBDEV_EP0_TX,
	DMA_ID_USBDEV_EP2_TX,
	DMA_ID_USBDEV_EP3_TX,
	DMA_ID_USBDEV_EP4_RX,
	DMA_ID_USBDEV_EP5_RX,
	DMA_ID_I2S_TX,
	DMA_ID_I2S_RX,
	DMA_NUM_DEV
};

/* DMA Device ID's for 2nd bank (AU1100) follow */
enum {
	DMA_ID_SD0_TX = 0,
	DMA_ID_SD0_RX,
	DMA_ID_SD1_TX,
	DMA_ID_SD1_RX,
	DMA_NUM_DEV_BANK2
};

struct dma_chan {
	int dev_id;		// this channel is allocated if >=0, free otherwise
	unsigned int io;
	const char *dev_str;
	int irq;
	void *irq_dev;
	unsigned int fifo_addr;
	unsigned int mode;
};

/* These are in arch/mips/au1000/common/dma.c */
extern struct dma_chan au1000_dma_table[];
extern int request_au1000_dma(int dev_id,
			      const char *dev_str,
			      void (*irqhandler)(int, void *,
						 struct pt_regs *),
			      unsigned long irqflags,
			      void *irq_dev_id);
extern void free_au1000_dma(unsigned int dmanr);
extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
				int length, int *eof, void *data);
extern void dump_au1000_dma_channel(unsigned int dmanr);
extern spinlock_t au1000_dma_spin_lock;


static __inline__ struct dma_chan *get_dma_chan(unsigned int dmanr)
{
	if (dmanr >= NUM_AU1000_DMA_CHANNELS
	    || au1000_dma_table[dmanr].dev_id < 0)
		return NULL;
	return &au1000_dma_table[dmanr];
}

static __inline__ unsigned long claim_dma_lock(void)
{
	unsigned long flags;
	spin_lock_irqsave(&au1000_dma_spin_lock, flags);
	return flags;
}

static __inline__ void release_dma_lock(unsigned long flags)
{
	spin_unlock_irqrestore(&au1000_dma_spin_lock, flags);
}

/*
 * Set the DMA buffer enable bits in the mode register.
 */
static __inline__ void enable_dma_buffer0(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	au_writel(DMA_BE0, chan->io + DMA_MODE_SET);
}
static __inline__ void enable_dma_buffer1(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	au_writel(DMA_BE1, chan->io + DMA_MODE_SET);
}
static __inline__ void enable_dma_buffers(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
}

static __inline__ void start_dma(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;

	au_writel(DMA_GO, chan->io + DMA_MODE_SET);
}

#define DMA_HALT_POLL 0x5000

static __inline__ void halt_dma(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	int i;
	if (!chan)
		return;

	au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
	// poll the halt bit
	for (i = 0; i < DMA_HALT_POLL; i++)
		if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
			break;
	if (i == DMA_HALT_POLL)
		printk(KERN_INFO "halt_dma: HALT poll expired!\n");
}


static __inline__ void disable_dma(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;

	halt_dma(dmanr);

	// now we can disable the buffers
	au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
}

static __inline__ int dma_halted(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return 1;
	return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
}

/* initialize a DMA channel */
static __inline__ void init_dma(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	u32 mode;
	if (!chan)
		return;

	disable_dma(dmanr);

	// set device FIFO address
	au_writel(PHYSADDR(chan->fifo_addr),
		  chan->io + DMA_PERIPHERAL_ADDR);

	mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
	if (chan->irq)
		mode |= DMA_IE;

	au_writel(~mode, chan->io + DMA_MODE_CLEAR);
	au_writel(mode, chan->io + DMA_MODE_SET);
}

/*
 * set mode for a specific DMA channel
 */
static __inline__ void set_dma_mode(unsigned int dmanr, unsigned int mode)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	/*
	 * set_dma_mode is only allowed to change endianess, direction,
	 * transfer size, device FIFO width, and coherency settings.
	 * Make sure anything else is masked off.
	 */
	mode &= (DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
	chan->mode &= ~(DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
	chan->mode |= mode;
}

static __inline__ unsigned int get_dma_mode(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return 0;
	return chan->mode;
}

static __inline__ int get_dma_active_buffer(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return -1;
	return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
}


/*
 * set the device FIFO address for a specific DMA channel - only
 * applicable to GPO4 and GPO5. All the other devices have fixed
 * FIFO addresses.
 */
static __inline__ void set_dma_fifo_addr(unsigned int dmanr,
					 unsigned int a)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;

	if (chan->mode & DMA_DS)	/* second bank of device ids */
		return;

	if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05)
		return;

	au_writel(PHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR);
}

/*
 * Clear the DMA buffer done bits in the mode register.
 */
static __inline__ void clear_dma_done0(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR);
}
static __inline__ void clear_dma_done1(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR);
}

/*
 * This does nothing - not applicable to Au1000 DMA.
 */
static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
{
}

/*
 * Set Buffer 0 transfer address for specific DMA channel.
 */
static __inline__ void set_dma_addr0(unsigned int dmanr, unsigned int a)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	au_writel(a, chan->io + DMA_BUFFER0_START);
}

/*
 * Set Buffer 1 transfer address for specific DMA channel.
 */
static __inline__ void set_dma_addr1(unsigned int dmanr, unsigned int a)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	au_writel(a, chan->io + DMA_BUFFER1_START);
}


/*
 * Set Buffer 0 transfer size (max 64k) for a specific DMA channel.
 */
static __inline__ void set_dma_count0(unsigned int dmanr,
				      unsigned int count)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	count &= DMA_COUNT_MASK;
	au_writel(count, chan->io + DMA_BUFFER0_COUNT);
}

/*
 * Set Buffer 1 transfer size (max 64k) for a specific DMA channel.
 */
static __inline__ void set_dma_count1(unsigned int dmanr,
				      unsigned int count)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	count &= DMA_COUNT_MASK;
	au_writel(count, chan->io + DMA_BUFFER1_COUNT);
}

/*
 * Set both buffer transfer sizes (max 64k) for a specific DMA channel.
 */
static __inline__ void set_dma_count(unsigned int dmanr,
				     unsigned int count)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return;
	count &= DMA_COUNT_MASK;
	au_writel(count, chan->io + DMA_BUFFER0_COUNT);
	au_writel(count, chan->io + DMA_BUFFER1_COUNT);
}

/*
 * Returns which buffer has its done bit set in the mode register.
 * Returns -1 if neither or both done bits set.
 */
static __inline__ unsigned int get_dma_buffer_done(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return 0;

    return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
}


/*
 * Returns the DMA channel's Buffer Done IRQ number.
 */
static __inline__ int get_dma_done_irq(unsigned int dmanr)
{
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return -1;

	return chan->irq;
}

/*
 * Get DMA residue count. Returns the number of _bytes_ left to transfer.
 */
static __inline__ int get_dma_residue(unsigned int dmanr)
{
	int curBufCntReg, count;
	struct dma_chan *chan = get_dma_chan(dmanr);
	if (!chan)
		return 0;

	curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ?
	    DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT;

	count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK;

	if ((chan->mode & DMA_DW_MASK) == DMA_DW16)
		count <<= 1;
	else if ((chan->mode & DMA_DW_MASK) == DMA_DW32)
		count <<= 2;

	return count;
}

#endif /* __ASM_AU1000_DMA_H */

