/*
 * sdma2edma.c
 *
 * SDMA to EDMA3 Wrapper.
 *
 * NOTE: Since we are invoking EDMA API, comments for all APIs in this file
 * are EDMA specific.
 *
 * Copyright (C) 2010-2011 Texas Instruments.
 * Author: Mansoor Ahamed <mansoor.ahamed@ti.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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * 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/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>

#include <asm/system.h>
#include <mach/hardware.h>
#include <plat/dma.h>
#include <plat/tc.h>

/* some edma specific hacks which might change */
#include <asm/hardware/edma.h>

/**
 * omap_request_dma - allocate DMA channel and paired parameter RAM
 * @dev_id: specific channel to allocate; negative for "any unmapped channel"
 * @callback: optional; to be issued on DMA completion or errors
 * @data: passed to callback
 * @dma_ch_out: allocated channel number returned in this variable
 *
 * This allocates a DMA channel and its associated parameter RAM slot.
 * The parameter RAM is initialized to hold a dummy transfer.
 *
 * Normal use is to pass a specific channel number as @channel, to make
 * use of hardware events mapped to that channel.  When the channel will
 * be used only for software triggering or event chaining, channels not
 * mapped to hardware events (or mapped to unused events) are preferable.
 *
 * DMA transfers start from a channel using edma_start(), or by
 * chaining.  When the transfer described in that channel's parameter RAM
 * slot completes, that slot's data may be reloaded through a link.
 *
 * DMA errors are only reported to the @callback associated with the
 * channel driving that transfer, but transfer completion callbacks can
 * be sent to another channel under control of the TCC field in
 * the option word of the transfer's parameter RAM set.  Drivers must not
 * use DMA transfer completion callbacks for channels they did not allocate.
 * (The same applies to TCC codes used in transfer chaining.)
 *
 * TODO: -
 * . In the edma call, last param i.e TC hard coded to EVENTQ_2
 * . The callback's ch_status which should be used in McSPI driver
 *   to stop/clean EDMA is currently ignored in some driver (eg. McSPI)
 */
int omap_request_dma(int dev_id, const char *dev_name,
             void (*callback)(int lch, u16 ch_status, void *data),
             void *data, int *dma_ch_out)
{
	struct edmacc_param p_ram;
	typedef void (*EDMA_CALLBACK)(unsigned, u16, void*);
	EDMA_CALLBACK edma_callback = (EDMA_CALLBACK)(callback);

	*dma_ch_out = edma_alloc_channel(dev_id, edma_callback, data, EVENTQ_2);
	if (*dma_ch_out < 0)
		return (-1);

	/* enable interrupts */
	edma_read_slot(*dma_ch_out, &p_ram);
    p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(*dma_ch_out));
    edma_write_slot(*dma_ch_out, &p_ram);

	return 0;
}
EXPORT_SYMBOL(omap_request_dma);

/**
 * omap_free_dma - deallocate DMA channel
 * @lch: dma channel returned from edma_alloc_channel()
 *
 * This deallocates the DMA channel and associated parameter RAM slot
 * allocated by omap_request_dma().
 *
 * Callers are responsible for ensuring the channel is inactive, and
 * will not be reactivated by linking, chaining, or software calls to
 * omap_start_dma().
 */
void omap_free_dma(int lch)
{
	edma_free_channel((unsigned)lch);
}
EXPORT_SYMBOL(omap_free_dma);

/**
 * omap_start_dma - start dma on a channel
 * @lch: channel being activated
 *
 * Channels with event associations will be triggered by their hardware
 * events, and channels without such associations will be triggered by
 * software.  (At this writing there is no interface for using software
 * triggers except with channels that don't support hardware triggers.)
 *
 */
void omap_start_dma(int lch)
{
	edma_start((unsigned)lch);
}
EXPORT_SYMBOL(omap_start_dma);

/**
 * omap_stop_dma - stops dma on the channel passed
 * @lch: channel being deactivated
 *
 * When @lch is a channel, any active transfer is paused and
 * all pending hardware events are cleared.  The current transfer
 * may not be resumed, and the channel's Parameter RAM should be
 * reinitialized before being reused.
 */
void omap_stop_dma(int lch)
{
	edma_stop((unsigned)lch);
}
EXPORT_SYMBOL(omap_stop_dma);

/**
 * omap_cleanup_dma - Bring back DMA to initial state
 * @lch: channel being cleaned up
 *
 * It cleans ParamEntry and bring back EDMA to initial state if media has
 * been removed before EDMA has finished.It is usedful for removable media.
 *
 *
 * FIXME this should not be needed ... edma_stop() should suffice.
 *
 */
void omap_cleanup_dma(int lch)
{
	edma_clean_channel((unsigned)lch);
}
EXPORT_SYMBOL(omap_cleanup_dma);

/**
 * omap_set_dma_transfer_params - configure DMA transfer parameters
 * @lch: parameter RAM slot being configured
 * @data_type: how many bytes per array (at least one)
 * @elem_count: how many arrays per frame (at least one)
 * @frame_count: how many frames per block (at least one)
 * @sync_mode: ASYNC or ABSYNC
 * @dma_trigger: device id (not used)
 * @src_or_dst_synch: not used
 *
 * See the EDMA3 documentation to understand how to configure and link
 * transfers using the fields in PaRAM slots.  If you are not doing it
 * all at once with edma_write_slot(), you will use this routine
 * plus two calls each for source and destination, setting the initial
 * address and saying how to index that address.
 *
 * An example of an A-Synchronized transfer is a serial link using a
 * single word shift register.  In that case, @acnt would be equal to
 * that word size; the serial controller issues a DMA synchronization
 * event to transfer each word, and memory access by the DMA transfer
 * controller will be word-at-a-time.
 *
 * An example of an AB-Synchronized transfer is a device using a FIFO.
 * In that case, @acnt equals the FIFO width and @bcnt equals its depth.
 * The controller with the FIFO issues DMA synchronization events when
 * the FIFO threshold is reached, and the DMA transfer controller will
 * transfer one frame to (or from) the FIFO.  It will probably use
 * efficient burst modes to access memory.
 *
 * . dma_trigger and channel number, this is ignored for EDMA
 * . Setting bcnt_rld same as bcnt
 * TODO
 * . what is src_or_dst_synch?
 */
void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
                  int frame_count, int sync_mode,
                  int dma_trigger, int src_or_dst_synch)
{
	int d_type[3] = {1, 2, 4};
	if ((enum sync_dimension)sync_mode > ABSYNC) {
		printk("SDMA2EDMA: Line:%d : Param \'sync_mode\' our of range\n",
				__LINE__);
		return;
	}

	/* translate data_type */
	data_type = d_type[data_type];

	edma_set_transfer_params(lch, (u16)data_type, (u16)elem_count,
		(u16)frame_count, (u16)elem_count, (enum sync_dimension)sync_mode);
}
EXPORT_SYMBOL(omap_set_dma_transfer_params);

/**
 * omap_set_dma_dest_params - Set initial DMA destination addr in param RAM slot
 * @lch: parameter RAM slot being configured
 * @dest_port: not used
 * @dest_amode: INCR, except in very rare cases
 * @dest_start: physical address of destination (memory, controller FIFO, etc)
 * @dst_ei: byte offset between destination arrays in a frame
 * @dst_fi: byte offset between destination frames in a block
 *
 * Note that the destination address is modified during the DMA transfer
 * according to edma_set_dest_index().
 *
 * TODO
 * . Not sure about dst_ei and dst_fi
 * . fifo_width for edma is not available in sdma API hence setting it to
 *   W8BIT
 * . dest_port is ignored
 */
void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
                  unsigned long dest_start,
                  int dst_ei, int dst_fi)
{
	if ((enum address_mode)dest_amode > FIFO) {
		printk("SDMA2EDMA: Line:%d : Param \'dest_amode\' our of range\n",
				__LINE__);
		return;
	}

	edma_set_dest((unsigned)lch, (dma_addr_t)dest_start,
					!dest_amode, W32BIT);
	edma_set_dest_index((unsigned)(lch), (s16)dst_ei, (s16)dst_fi);
}
EXPORT_SYMBOL(omap_set_dma_dest_params);

/**
 * omap_set_dma_src_params - Set initial DMA source addr in param RAM slot
 * @lch: parameter RAM slot being configured
 * @src_port: not used
 * @src_amode: INCR, except in very rare cases
 * @src_start: physical address of destination (memory, controller FIFO, etc)
 * @src_ei: byte offset between destination arrays in a frame
 * @src_fi: byte offset between destination frames in a block
 *
 * Note that the source address is modified during the DMA transfer
 * according to edma_set_src_index().
 *
 * TODO
 * . Not sure about src_ei and src_fi
 * . fifo_width for edma is not available in sdma API hence setting it to
 *   W8BIT
 * . src_port is ignored
 */
void omap_set_dma_src_params(int lch, int src_port, int src_amode,
                  unsigned long src_start,
                  int src_ei, int src_fi)
{
	if ((enum address_mode)src_amode > FIFO) {
		printk("SDMA2EDMA: Line:%d : Param \'src_amode\' our of range\n",
				__LINE__);
		return;
	}

	edma_set_src((unsigned)lch, (dma_addr_t)src_start,
					!src_amode, W32BIT);
	edma_set_src_index((unsigned)(lch), (s16)src_ei, (s16)src_fi);
}
EXPORT_SYMBOL(omap_set_dma_src_params);

void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
{
	printk("omap_set_dma_src_burst_mode: un-supported SDMA wrapper\n");
}
EXPORT_SYMBOL(omap_set_dma_src_burst_mode);

void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
{
	printk("omap_set_dma_dest_burst_mode: un-supported SDMA wrapper\n");
}
EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);

dma_addr_t omap_get_dma_dst_pos(int lch)
{
	printk("omap_get_dma_dst_pos: un-supported in SDMA wrapper\n");
	return 0;
}

EXPORT_SYMBOL(omap_get_dma_dst_pos);

int omap_get_dma_active_status(int lch)
{
	printk("omap_get_dma_active_status: un-supported in SDMA wrapper\n");
	return 0;
}
EXPORT_SYMBOL(omap_get_dma_active_status);
