/*
 * IBM PPC4xx DMA engine scatter/gather library
 *
 * Copyright 2002-2003 MontaVista Software Inc.
 *
 * Cleaned up and converted to new DCR access
 * Matt Porter <mporter@kernel.crashing.org>
 *
 * Original code by Armin Kuster <akuster@mvista.com>
 * and Pete Popov <ppopov@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.
 *
 * 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/kernel.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/ppc4xx_dma.h>

void
ppc4xx_set_sg_addr(int dmanr, phys_addr_t sg_addr)
{
	if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
		printk("ppc4xx_set_sg_addr: bad channel: %d\n", dmanr);
		return;
	}

#ifdef PPC4xx_DMA_64BIT
	mtdcr(DCRN_ASGH0 + (dmanr * 0x8), (u32)(sg_addr >> 32));
#endif
	mtdcr(DCRN_ASG0 + (dmanr * 0x8), (u32)sg_addr);
}

/*
 *   Add a new sgl descriptor to the end of a scatter/gather list
 *   which was created by alloc_dma_handle().
 *
 *   For a memory to memory transfer, both dma addresses must be
 *   valid. For a peripheral to memory transfer, one of the addresses
 *   must be set to NULL, depending on the direction of the transfer:
 *   memory to peripheral: set dst_addr to NULL,
 *   peripheral to memory: set src_addr to NULL.
 */
int
ppc4xx_add_dma_sgl(sgl_handle_t handle, phys_addr_t src_addr, phys_addr_t dst_addr,
		   unsigned int count)
{
	sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
	ppc_dma_ch_t *p_dma_ch;

	if (!handle) {
		printk("ppc4xx_add_dma_sgl: null handle\n");
		return DMA_STATUS_BAD_HANDLE;
	}

	if (psgl->dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
		printk("ppc4xx_add_dma_sgl: bad channel: %d\n", psgl->dmanr);
		return DMA_STATUS_BAD_CHANNEL;
	}

	p_dma_ch = &dma_channels[psgl->dmanr];

#ifdef DEBUG_4xxDMA
	{
		int error = 0;
		unsigned int aligned =
		    (unsigned) src_addr | (unsigned) dst_addr | count;
		switch (p_dma_ch->pwidth) {
		case PW_8:
			break;
		case PW_16:
			if (aligned & 0x1)
				error = 1;
			break;
		case PW_32:
			if (aligned & 0x3)
				error = 1;
			break;
		case PW_64:
			if (aligned & 0x7)
				error = 1;
			break;
		default:
			printk("ppc4xx_add_dma_sgl: invalid bus width: 0x%x\n",
			       p_dma_ch->pwidth);
			return DMA_STATUS_GENERAL_ERROR;
		}
		if (error)
			printk
			    ("Alignment warning: ppc4xx_add_dma_sgl src 0x%x dst 0x%x count 0x%x bus width var %d\n",
			     src_addr, dst_addr, count, p_dma_ch->pwidth);

	}
#endif

	if ((unsigned) (psgl->ptail + 1) >= ((unsigned) psgl + SGL_LIST_SIZE)) {
		printk("sgl handle out of memory \n");
		return DMA_STATUS_OUT_OF_MEMORY;
	}

	if (!psgl->ptail) {
		psgl->phead = (ppc_sgl_t *)
		    ((unsigned) psgl + sizeof (sgl_list_info_t));
		psgl->phead_dma = psgl->dma_addr + sizeof(sgl_list_info_t);
		psgl->ptail = psgl->phead;
		psgl->ptail_dma = psgl->phead_dma;
	} else {
		if(p_dma_ch->int_on_final_sg) {
			/* mask out all dma interrupts, except error, on tail
			before adding new tail. */
			psgl->ptail->control_count &=
				~(SG_TCI_ENABLE | SG_ETI_ENABLE);
		}
		psgl->ptail->next = psgl->ptail_dma + sizeof(ppc_sgl_t);
		psgl->ptail++;
		psgl->ptail_dma += sizeof(ppc_sgl_t);
	}

	psgl->ptail->control = psgl->control;
	psgl->ptail->src_addr = src_addr;
	psgl->ptail->dst_addr = dst_addr;
	psgl->ptail->control_count = (count >> p_dma_ch->shift) |
	    psgl->sgl_control;
	psgl->ptail->next = (uint32_t) NULL;

	return DMA_STATUS_GOOD;
}

/*
 * Enable (start) the DMA described by the sgl handle.
 */
void
ppc4xx_enable_dma_sgl(sgl_handle_t handle)
{
	sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
	ppc_dma_ch_t *p_dma_ch;
	uint32_t sg_command;

	if (!handle) {
		printk("ppc4xx_enable_dma_sgl: null handle\n");
		return;
	} else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
		printk("ppc4xx_enable_dma_sgl: bad channel in handle %d\n",
		       psgl->dmanr);
		return;
	} else if (!psgl->phead) {
		printk("ppc4xx_enable_dma_sgl: sg list empty\n");
		return;
	}

	p_dma_ch = &dma_channels[psgl->dmanr];
	psgl->ptail->control_count &= ~SG_LINK;	/* make this the last dscrptr */
	sg_command = mfdcr(DCRN_ASGC);

	ppc4xx_set_sg_addr(psgl->dmanr, psgl->phead_dma);

	sg_command |= SSG_ENABLE(psgl->dmanr);

	mtdcr(DCRN_ASGC, sg_command);	/* start transfer */
}

/*
 * Halt an active scatter/gather DMA operation.
 */
void
ppc4xx_disable_dma_sgl(sgl_handle_t handle)
{
	sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
	uint32_t sg_command;

	if (!handle) {
		printk("ppc4xx_enable_dma_sgl: null handle\n");
		return;
	} else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
		printk("ppc4xx_enable_dma_sgl: bad channel in handle %d\n",
		       psgl->dmanr);
		return;
	}

	sg_command = mfdcr(DCRN_ASGC);
	sg_command &= ~SSG_ENABLE(psgl->dmanr);
	mtdcr(DCRN_ASGC, sg_command);	/* stop transfer */
}

/*
 *  Returns number of bytes left to be transferred from the entire sgl list.
 *  *src_addr and *dst_addr get set to the source/destination address of
 *  the sgl descriptor where the DMA stopped.
 *
 *  An sgl transfer must NOT be active when this function is called.
 */
int
ppc4xx_get_dma_sgl_residue(sgl_handle_t handle, phys_addr_t * src_addr,
			   phys_addr_t * dst_addr)
{
	sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
	ppc_dma_ch_t *p_dma_ch;
	ppc_sgl_t *pnext, *sgl_addr;
	uint32_t count_left;

	if (!handle) {
		printk("ppc4xx_get_dma_sgl_residue: null handle\n");
		return DMA_STATUS_BAD_HANDLE;
	} else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
		printk("ppc4xx_get_dma_sgl_residue: bad channel in handle %d\n",
		       psgl->dmanr);
		return DMA_STATUS_BAD_CHANNEL;
	}

	sgl_addr = (ppc_sgl_t *) __va(mfdcr(DCRN_ASG0 + (psgl->dmanr * 0x8)));
	count_left = mfdcr(DCRN_DMACT0 + (psgl->dmanr * 0x8)) & SG_COUNT_MASK;

	if (!sgl_addr) {
		printk("ppc4xx_get_dma_sgl_residue: sgl addr register is null\n");
		goto error;
	}

	pnext = psgl->phead;
	while (pnext &&
	       ((unsigned) pnext < ((unsigned) psgl + SGL_LIST_SIZE) &&
		(pnext != sgl_addr))
	    ) {
		pnext++;
	}

	if (pnext == sgl_addr) {	/* found the sgl descriptor */

		*src_addr = pnext->src_addr;
		*dst_addr = pnext->dst_addr;

		/*
		 * Now search the remaining descriptors and add their count.
		 * We already have the remaining count from this descriptor in
		 * count_left.
		 */
		pnext++;

		while ((pnext != psgl->ptail) &&
		       ((unsigned) pnext < ((unsigned) psgl + SGL_LIST_SIZE))
		    ) {
			count_left += pnext->control_count & SG_COUNT_MASK;
		}

		if (pnext != psgl->ptail) {	/* should never happen */
			printk
			    ("ppc4xx_get_dma_sgl_residue error (1) psgl->ptail 0x%x handle 0x%x\n",
			     (unsigned int) psgl->ptail, (unsigned int) handle);
			goto error;
		}

		/* success */
		p_dma_ch = &dma_channels[psgl->dmanr];
		return (count_left << p_dma_ch->shift);	/* count in bytes */

	} else {
		/* this shouldn't happen */
		printk
		    ("get_dma_sgl_residue, unable to match current address 0x%x, handle 0x%x\n",
		     (unsigned int) sgl_addr, (unsigned int) handle);

	}

      error:
	*src_addr = (phys_addr_t) NULL;
	*dst_addr = (phys_addr_t) NULL;
	return 0;
}

/*
 * Returns the address(es) of the buffer(s) contained in the head element of
 * the scatter/gather list.  The element is removed from the scatter/gather
 * list and the next element becomes the head.
 *
 * This function should only be called when the DMA is not active.
 */
int
ppc4xx_delete_dma_sgl_element(sgl_handle_t handle, phys_addr_t * src_dma_addr,
			      phys_addr_t * dst_dma_addr)
{
	sgl_list_info_t *psgl = (sgl_list_info_t *) handle;

	if (!handle) {
		printk("ppc4xx_delete_sgl_element: null handle\n");
		return DMA_STATUS_BAD_HANDLE;
	} else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
		printk("ppc4xx_delete_sgl_element: bad channel in handle %d\n",
		       psgl->dmanr);
		return DMA_STATUS_BAD_CHANNEL;
	}

	if (!psgl->phead) {
		printk("ppc4xx_delete_sgl_element: sgl list empty\n");
		*src_dma_addr = (phys_addr_t) NULL;
		*dst_dma_addr = (phys_addr_t) NULL;
		return DMA_STATUS_SGL_LIST_EMPTY;
	}

	*src_dma_addr = (phys_addr_t) psgl->phead->src_addr;
	*dst_dma_addr = (phys_addr_t) psgl->phead->dst_addr;

	if (psgl->phead == psgl->ptail) {
		/* last descriptor on the list */
		psgl->phead = NULL;
		psgl->ptail = NULL;
	} else {
		psgl->phead++;
		psgl->phead_dma += sizeof(ppc_sgl_t);
	}

	return DMA_STATUS_GOOD;
}


/*
 *   Create a scatter/gather list handle.  This is simply a structure which
 *   describes a scatter/gather list.
 *
 *   A handle is returned in "handle" which the driver should save in order to
 *   be able to access this list later.  A chunk of memory will be allocated
 *   to be used by the API for internal management purposes, including managing
 *   the sg list and allocating memory for the sgl descriptors.  One page should
 *   be more than enough for that purpose.  Perhaps it's a bit wasteful to use
 *   a whole page for a single sg list, but most likely there will be only one
 *   sg list per channel.
 *
 *   Interrupt notes:
 *   Each sgl descriptor has a copy of the DMA control word which the DMA engine
 *   loads in the control register.  The control word has a "global" interrupt
 *   enable bit for that channel. Interrupts are further qualified by a few bits
 *   in the sgl descriptor count register.  In order to setup an sgl, we have to
 *   know ahead of time whether or not interrupts will be enabled at the completion
 *   of the transfers.  Thus, enable_dma_interrupt()/disable_dma_interrupt() MUST
 *   be called before calling alloc_dma_handle().  If the interrupt mode will never
 *   change after powerup, then enable_dma_interrupt()/disable_dma_interrupt()
 *   do not have to be called -- interrupts will be enabled or disabled based
 *   on how the channel was configured after powerup by the hw_init_dma_channel()
 *   function.  Each sgl descriptor will be setup to interrupt if an error occurs;
 *   however, only the last descriptor will be setup to interrupt. Thus, an
 *   interrupt will occur (if interrupts are enabled) only after the complete
 *   sgl transfer is done.
 */
int
ppc4xx_alloc_dma_handle(sgl_handle_t * phandle, unsigned int mode, unsigned int dmanr)
{
	sgl_list_info_t *psgl=NULL;
	dma_addr_t dma_addr;
	ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
	uint32_t sg_command;
	uint32_t ctc_settings;
	void *ret;

	if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
		printk("ppc4xx_alloc_dma_handle: invalid channel 0x%x\n", dmanr);
		return DMA_STATUS_BAD_CHANNEL;
	}

	if (!phandle) {
		printk("ppc4xx_alloc_dma_handle: null handle pointer\n");
		return DMA_STATUS_NULL_POINTER;
	}

	/* Get a page of memory, which is zeroed out by consistent_alloc() */
	ret = dma_alloc_coherent(NULL, DMA_PPC4xx_SIZE, &dma_addr, GFP_KERNEL);
	if (ret != NULL) {
		memset(ret, 0, DMA_PPC4xx_SIZE);
		psgl = (sgl_list_info_t *) ret;
	}

	if (psgl == NULL) {
		*phandle = (sgl_handle_t) NULL;
		return DMA_STATUS_OUT_OF_MEMORY;
	}

	psgl->dma_addr = dma_addr;
	psgl->dmanr = dmanr;

	/*
	 * Modify and save the control word. These words will be
	 * written to each sgl descriptor.  The DMA engine then
	 * loads this control word into the control register
	 * every time it reads a new descriptor.
	 */
	psgl->control = p_dma_ch->control;
	/* Clear all mode bits */
	psgl->control &= ~(DMA_TM_MASK | DMA_TD);
	/* Save control word and mode */
	psgl->control |= (mode | DMA_CE_ENABLE);

	/* In MM mode, we must set ETD/TCE */
	if (mode == DMA_MODE_MM)
		psgl->control |= DMA_ETD_OUTPUT | DMA_TCE_ENABLE;

	if (p_dma_ch->int_enable) {
		/* Enable channel interrupt */
		psgl->control |= DMA_CIE_ENABLE;
	} else {
		psgl->control &= ~DMA_CIE_ENABLE;
	}

	sg_command = mfdcr(DCRN_ASGC);
	sg_command |= SSG_MASK_ENABLE(dmanr);

	/* Enable SGL control access */
	mtdcr(DCRN_ASGC, sg_command);
	psgl->sgl_control = SG_ERI_ENABLE | SG_LINK;

	/* keep control count register settings */
	ctc_settings = mfdcr(DCRN_DMACT0 + (dmanr * 0x8))
		& (DMA_CTC_BSIZ_MSK | DMA_CTC_BTEN); /*burst mode settings*/
	psgl->sgl_control |= ctc_settings;

	if (p_dma_ch->int_enable) {
		if (p_dma_ch->tce_enable)
			psgl->sgl_control |= SG_TCI_ENABLE;
		else
			psgl->sgl_control |= SG_ETI_ENABLE;
	}

	*phandle = (sgl_handle_t) psgl;
	return DMA_STATUS_GOOD;
}

/*
 * Destroy a scatter/gather list handle that was created by alloc_dma_handle().
 * The list must be empty (contain no elements).
 */
void
ppc4xx_free_dma_handle(sgl_handle_t handle)
{
	sgl_list_info_t *psgl = (sgl_list_info_t *) handle;

	if (!handle) {
		printk("ppc4xx_free_dma_handle: got NULL\n");
		return;
	} else if (psgl->phead) {
		printk("ppc4xx_free_dma_handle: list not empty\n");
		return;
	} else if (!psgl->dma_addr) {	/* should never happen */
		printk("ppc4xx_free_dma_handle: no dma address\n");
		return;
	}

	dma_free_coherent(NULL, DMA_PPC4xx_SIZE, (void *) psgl, 0);
}

EXPORT_SYMBOL(ppc4xx_alloc_dma_handle);
EXPORT_SYMBOL(ppc4xx_free_dma_handle);
EXPORT_SYMBOL(ppc4xx_add_dma_sgl);
EXPORT_SYMBOL(ppc4xx_delete_dma_sgl_element);
EXPORT_SYMBOL(ppc4xx_enable_dma_sgl);
EXPORT_SYMBOL(ppc4xx_disable_dma_sgl);
EXPORT_SYMBOL(ppc4xx_get_dma_sgl_residue);
