/*
 * arch/arm/kernel/dma-sa1100.c
 *
 * Support functions for the SA11x0 internal DMA channels.
 *
 * Copyright (C) 2000, 2001 by Nicolas Pitre
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

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

#include <asm/system.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/dma.h>


#undef DEBUG
#ifdef DEBUG
#define DPRINTK( s, arg... )  printk( "dma<%p>: " s, regs , ##arg )
#else
#define DPRINTK( x... )
#endif


typedef struct {
	const char *device_id;		/* device name */
	u_long device;			/* this channel device, 0  if unused*/
	dma_callback_t callback;	/* to call when DMA completes */
	void *data;			/* ... with private data ptr */
} sa1100_dma_t;

static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS];

static spinlock_t dma_list_lock;


static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
	dma_regs_t *dma_regs = dev_id;
	sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7);
	int status = dma_regs->RdDCSR;

	if (status & (DCSR_ERROR)) {
		printk(KERN_CRIT "DMA on \"%s\" caused an error\n", dma->device_id);
		dma_regs->ClrDCSR = DCSR_ERROR;
	}

	dma_regs->ClrDCSR = status & (DCSR_DONEA | DCSR_DONEB);
	if (dma->callback) {
		if (status & DCSR_DONEA)
			dma->callback(dma->data);
		if (status & DCSR_DONEB)
			dma->callback(dma->data);
	}
	return IRQ_HANDLED;
}


/**
 *	sa1100_request_dma - allocate one of the SA11x0's DMA chanels
 *	@device: The SA11x0 peripheral targeted by this request
 *	@device_id: An ascii name for the claiming device
 *	@callback: Function to be called when the DMA completes
 *	@data: A cookie passed back to the callback function
 *	@dma_regs: Pointer to the location of the allocated channel's identifier
 *
 * 	This function will search for a free DMA channel and returns the
 * 	address of the hardware registers for that channel as the channel
 * 	identifier. This identifier is written to the location pointed by
 * 	@dma_regs. The list of possible values for @device are listed into
 * 	linux/include/asm-arm/arch-sa1100/dma.h as a dma_device_t enum.
 *
 * 	Note that reading from a port and writing to the same port are
 * 	actually considered as two different streams requiring separate
 * 	DMA registrations.
 *
 * 	The @callback function is called from interrupt context when one
 * 	of the two possible DMA buffers in flight has terminated. That
 * 	function has to be small and efficient while posponing more complex
 * 	processing to a lower priority execution context.
 *
 * 	If no channels are available, or if the desired @device is already in
 * 	use by another DMA channel, then an error code is returned.  This
 * 	function must be called before any other DMA calls.
 **/

int sa1100_request_dma (dma_device_t device, const char *device_id,
			dma_callback_t callback, void *data,
			dma_regs_t **dma_regs)
{
	sa1100_dma_t *dma = NULL;
	dma_regs_t *regs;
	int i, err;

	*dma_regs = NULL;

	err = 0;
	spin_lock(&dma_list_lock);
	for (i = 0; i < SA1100_DMA_CHANNELS; i++) {
		if (dma_chan[i].device == device) {
			err = -EBUSY;
			break;
		} else if (!dma_chan[i].device && !dma) {
			dma = &dma_chan[i];
		}
	}
	if (!err) {
	       if (dma)
		       dma->device = device;
	       else
		       err = -ENOSR;
	}
	spin_unlock(&dma_list_lock);
	if (err)
		return err;

	i = dma - dma_chan;
	regs = (dma_regs_t *)&DDAR(i);
	err = request_irq(IRQ_DMA0 + i, dma_irq_handler, SA_INTERRUPT,
			  device_id, regs);
	if (err) {
		printk(KERN_ERR
		       "%s: unable to request IRQ %d for %s\n",
		       __FUNCTION__, IRQ_DMA0 + i, device_id);
		dma->device = 0;
		return err;
	}

	*dma_regs = regs;
	dma->device_id = device_id;
	dma->callback = callback;
	dma->data = data;

	regs->ClrDCSR =
		(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
		 DCSR_IE | DCSR_ERROR | DCSR_RUN);
	regs->DDAR = device;

	return 0;
}


/**
 * 	sa1100_free_dma - free a SA11x0 DMA channel
 * 	@regs: identifier for the channel to free
 *
 * 	This clears all activities on a given DMA channel and releases it
 * 	for future requests.  The @regs identifier is provided by a
 * 	successful call to sa1100_request_dma().
 **/

void sa1100_free_dma(dma_regs_t *regs)
{
	int i;

	for (i = 0; i < SA1100_DMA_CHANNELS; i++)
		if (regs == (dma_regs_t *)&DDAR(i))
			break;
	if (i >= SA1100_DMA_CHANNELS) {
		printk(KERN_ERR "%s: bad DMA identifier\n", __FUNCTION__);
		return;
	}

	if (!dma_chan[i].device) {
		printk(KERN_ERR "%s: Trying to free free DMA\n", __FUNCTION__);
		return;
	}

	regs->ClrDCSR =
		(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
		 DCSR_IE | DCSR_ERROR | DCSR_RUN);
	free_irq(IRQ_DMA0 + i, regs);
	dma_chan[i].device = 0;
}


/**
 * 	sa1100_start_dma - submit a data buffer for DMA
 * 	@regs: identifier for the channel to use
 * 	@dma_ptr: buffer physical (or bus) start address
 * 	@size: buffer size
 *
 * 	This function hands the given data buffer to the hardware for DMA
 * 	access. If another buffer is already in flight then this buffer
 * 	will be queued so the DMA engine will switch to it automatically
 * 	when the previous one is done.  The DMA engine is actually toggling
 * 	between two buffers so at most 2 successful calls can be made before
 * 	one of them terminates and the callback function is called.
 *
 * 	The @regs identifier is provided by a successful call to
 * 	sa1100_request_dma().
 *
 * 	The @size must not be larger than %MAX_DMA_SIZE.  If a given buffer
 * 	is larger than that then it's the caller's responsibility to split
 * 	it into smaller chunks and submit them separately. If this is the
 * 	case then a @size of %CUT_DMA_SIZE is recommended to avoid ending
 * 	up with too small chunks. The callback function can be used to chain
 * 	submissions of buffer chunks.
 *
 * 	Error return values:
 * 	%-EOVERFLOW:	Given buffer size is too big.
 * 	%-EBUSY:	Both DMA buffers are already in use.
 * 	%-EAGAIN:	Both buffers were busy but one of them just completed
 * 			but the interrupt handler has to execute first.
 *
 * 	This function returs 0 on success.
 **/

int sa1100_start_dma(dma_regs_t *regs, dma_addr_t dma_ptr, u_int size)
{
	unsigned long flags;
	u_long status;
	int ret;

	if (dma_ptr & 3)
		printk(KERN_WARNING "DMA: unaligned start address (0x%08lx)\n",
		       (unsigned long)dma_ptr);

	if (size > MAX_DMA_SIZE)
		return -EOVERFLOW;

	local_irq_save(flags);
	status = regs->RdDCSR;

	/* If both DMA buffers are started, there's nothing else we can do. */
	if ((status & (DCSR_STRTA | DCSR_STRTB)) == (DCSR_STRTA | DCSR_STRTB)) {
		DPRINTK("start: st %#x busy\n", status);
		ret = -EBUSY;
		goto out;
	}

	if (((status & DCSR_BIU) && (status & DCSR_STRTB)) ||
	    (!(status & DCSR_BIU) && !(status & DCSR_STRTA))) {
		if (status & DCSR_DONEA) {
			/* give a chance for the interrupt to be processed */
			ret = -EAGAIN;
			goto out;
		}
		regs->DBSA = dma_ptr;
		regs->DBTA = size;
		regs->SetDCSR = DCSR_STRTA | DCSR_IE | DCSR_RUN;
		DPRINTK("start a=%#x s=%d on A\n", dma_ptr, size);
	} else {
		if (status & DCSR_DONEB) {
			/* give a chance for the interrupt to be processed */
			ret = -EAGAIN;
			goto out;
		}
		regs->DBSB = dma_ptr;
		regs->DBTB = size;
		regs->SetDCSR = DCSR_STRTB | DCSR_IE | DCSR_RUN;
		DPRINTK("start a=%#x s=%d on B\n", dma_ptr, size);
	}
	ret = 0;

out:
	local_irq_restore(flags);
	return ret;
}


/**
 * 	sa1100_get_dma_pos - return current DMA position
 * 	@regs: identifier for the channel to use
 *
 * 	This function returns the current physical (or bus) address for the
 * 	given DMA channel.  If the channel is running i.e. not in a stopped
 * 	state then the caller must disable interrupts prior calling this
 * 	function and process the returned value before re-enabling them to
 * 	prevent races with the completion interrupt handler and the callback
 * 	function. The validation of the returned value is the caller's
 * 	responsibility as well -- the hardware seems to return out of range
 * 	values when the DMA engine completes a buffer.
 *
 * 	The @regs identifier is provided by a successful call to
 * 	sa1100_request_dma().
 **/

dma_addr_t sa1100_get_dma_pos(dma_regs_t *regs)
{
	int status;

	/*
	 * We must determine whether buffer A or B is active.
	 * Two possibilities: either we are in the middle of
	 * a buffer, or the DMA controller just switched to the
	 * next toggle but the interrupt hasn't been serviced yet.
	 * The former case is straight forward.  In the later case,
	 * we'll do like if DMA is just at the end of the previous
	 * toggle since all registers haven't been reset yet.
	 * This goes around the edge case and since we're always
	 * a little behind anyways it shouldn't make a big difference.
	 * If DMA has been stopped prior calling this then the
	 * position is exact.
	 */
	status = regs->RdDCSR;
	if ((!(status & DCSR_BIU) &&  (status & DCSR_STRTA)) ||
	    ( (status & DCSR_BIU) && !(status & DCSR_STRTB)))
		return regs->DBSA;
	else
		return regs->DBSB;
}


/**
 * 	sa1100_reset_dma - reset a DMA channel
 * 	@regs: identifier for the channel to use
 *
 * 	This function resets and reconfigure the given DMA channel. This is
 * 	particularly useful after a sleep/wakeup event.
 *
 * 	The @regs identifier is provided by a successful call to
 * 	sa1100_request_dma().
 **/

void sa1100_reset_dma(dma_regs_t *regs)
{
	int i;

	for (i = 0; i < SA1100_DMA_CHANNELS; i++)
		if (regs == (dma_regs_t *)&DDAR(i))
			break;
	if (i >= SA1100_DMA_CHANNELS) {
		printk(KERN_ERR "%s: bad DMA identifier\n", __FUNCTION__);
		return;
	}

	regs->ClrDCSR =
		(DCSR_DONEA | DCSR_DONEB | DCSR_STRTA | DCSR_STRTB |
		 DCSR_IE | DCSR_ERROR | DCSR_RUN);
	regs->DDAR = dma_chan[i].device;
}


EXPORT_SYMBOL(sa1100_request_dma);
EXPORT_SYMBOL(sa1100_free_dma);
EXPORT_SYMBOL(sa1100_start_dma);
EXPORT_SYMBOL(sa1100_get_dma_pos);
EXPORT_SYMBOL(sa1100_reset_dma);

