/*
 * drivers/media/platform/omap24xxcam-dma.c
 *
 * Copyright (C) 2004 MontaVista Software, Inc.
 * Copyright (C) 2004 Texas Instruments.
 * Copyright (C) 2007 Nokia Corporation.
 *
 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
 *
 * Based on code from Andy Lowe <source@mvista.com> and
 *                    David Cohen <david.cohen@indt.org.br>.
 *
 * 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.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/scatterlist.h>

#include "omap24xxcam.h"

/*
 *
 * DMA hardware.
 *
 */

/* Ack all interrupt on CSR and IRQSTATUS_L0 */
static void omap24xxcam_dmahw_ack_all(void __iomem *base)
{
	u32 csr;
	int i;

	for (i = 0; i < NUM_CAMDMA_CHANNELS; ++i) {
		csr = omap24xxcam_reg_in(base, CAMDMA_CSR(i));
		/* ack interrupt in CSR */
		omap24xxcam_reg_out(base, CAMDMA_CSR(i), csr);
	}
	omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, 0xf);
}

/* Ack dmach on CSR and IRQSTATUS_L0 */
static u32 omap24xxcam_dmahw_ack_ch(void __iomem *base, int dmach)
{
	u32 csr;

	csr = omap24xxcam_reg_in(base, CAMDMA_CSR(dmach));
	/* ack interrupt in CSR */
	omap24xxcam_reg_out(base, CAMDMA_CSR(dmach), csr);
	/* ack interrupt in IRQSTATUS */
	omap24xxcam_reg_out(base, CAMDMA_IRQSTATUS_L0, (1 << dmach));

	return csr;
}

static int omap24xxcam_dmahw_running(void __iomem *base, int dmach)
{
	return omap24xxcam_reg_in(base, CAMDMA_CCR(dmach)) & CAMDMA_CCR_ENABLE;
}

static void omap24xxcam_dmahw_transfer_setup(void __iomem *base, int dmach,
					     dma_addr_t start, u32 len)
{
	omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
			    CAMDMA_CCR_SEL_SRC_DST_SYNC
			    | CAMDMA_CCR_BS
			    | CAMDMA_CCR_DST_AMODE_POST_INC
			    | CAMDMA_CCR_SRC_AMODE_POST_INC
			    | CAMDMA_CCR_FS
			    | CAMDMA_CCR_WR_ACTIVE
			    | CAMDMA_CCR_RD_ACTIVE
			    | CAMDMA_CCR_SYNCHRO_CAMERA);
	omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CEN(dmach), len);
	omap24xxcam_reg_out(base, CAMDMA_CFN(dmach), 1);
	omap24xxcam_reg_out(base, CAMDMA_CSDP(dmach),
			    CAMDMA_CSDP_WRITE_MODE_POSTED
			    | CAMDMA_CSDP_DST_BURST_EN_32
			    | CAMDMA_CSDP_DST_PACKED
			    | CAMDMA_CSDP_SRC_BURST_EN_32
			    | CAMDMA_CSDP_SRC_PACKED
			    | CAMDMA_CSDP_DATA_TYPE_8BITS);
	omap24xxcam_reg_out(base, CAMDMA_CSSA(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CDSA(dmach), start);
	omap24xxcam_reg_out(base, CAMDMA_CSEI(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CSFI(dmach), DMA_THRESHOLD);
	omap24xxcam_reg_out(base, CAMDMA_CDEI(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CDFI(dmach), 0);
	omap24xxcam_reg_out(base, CAMDMA_CSR(dmach),
			    CAMDMA_CSR_MISALIGNED_ERR
			    | CAMDMA_CSR_SECURE_ERR
			    | CAMDMA_CSR_TRANS_ERR
			    | CAMDMA_CSR_BLOCK
			    | CAMDMA_CSR_DROP);
	omap24xxcam_reg_out(base, CAMDMA_CICR(dmach),
			    CAMDMA_CICR_MISALIGNED_ERR_IE
			    | CAMDMA_CICR_SECURE_ERR_IE
			    | CAMDMA_CICR_TRANS_ERR_IE
			    | CAMDMA_CICR_BLOCK_IE
			    | CAMDMA_CICR_DROP_IE);
}

static void omap24xxcam_dmahw_transfer_start(void __iomem *base, int dmach)
{
	omap24xxcam_reg_out(base, CAMDMA_CCR(dmach),
			    CAMDMA_CCR_SEL_SRC_DST_SYNC
			    | CAMDMA_CCR_BS
			    | CAMDMA_CCR_DST_AMODE_POST_INC
			    | CAMDMA_CCR_SRC_AMODE_POST_INC
			    | CAMDMA_CCR_ENABLE
			    | CAMDMA_CCR_FS
			    | CAMDMA_CCR_SYNCHRO_CAMERA);
}

static void omap24xxcam_dmahw_transfer_chain(void __iomem *base, int dmach,
					     int free_dmach)
{
	int prev_dmach, ch;

	if (dmach == 0)
		prev_dmach = NUM_CAMDMA_CHANNELS - 1;
	else
		prev_dmach = dmach - 1;
	omap24xxcam_reg_out(base, CAMDMA_CLNK_CTRL(prev_dmach),
			    CAMDMA_CLNK_CTRL_ENABLE_LNK | dmach);
	/* Did we chain the DMA transfer before the previous one
	 * finished?
	 */
	ch = (dmach + free_dmach) % NUM_CAMDMA_CHANNELS;
	while (!(omap24xxcam_reg_in(base, CAMDMA_CCR(ch))
		 & CAMDMA_CCR_ENABLE)) {
		if (ch == dmach) {
			/* The previous transfer has ended and this one
			 * hasn't started, so we must not have chained
			 * to the previous one in time.  We'll have to
			 * start it now.
			 */
			omap24xxcam_dmahw_transfer_start(base, dmach);
			break;
		} else
			ch = (ch + 1) % NUM_CAMDMA_CHANNELS;
	}
}

/* Abort all chained DMA transfers. After all transfers have been
 * aborted and the DMA controller is idle, the completion routines for
 * any aborted transfers will be called in sequence. The DMA
 * controller may not be idle after this routine completes, because
 * the completion routines might start new transfers.
 */
static void omap24xxcam_dmahw_abort_ch(void __iomem *base, int dmach)
{
	/* mask all interrupts from this channel */
	omap24xxcam_reg_out(base, CAMDMA_CICR(dmach), 0);
	/* unlink this channel */
	omap24xxcam_reg_merge(base, CAMDMA_CLNK_CTRL(dmach), 0,
			      CAMDMA_CLNK_CTRL_ENABLE_LNK);
	/* disable this channel */
	omap24xxcam_reg_merge(base, CAMDMA_CCR(dmach), 0, CAMDMA_CCR_ENABLE);
}

static void omap24xxcam_dmahw_init(void __iomem *base)
{
	omap24xxcam_reg_out(base, CAMDMA_OCP_SYSCONFIG,
			    CAMDMA_OCP_SYSCONFIG_MIDLEMODE_FSTANDBY
			    | CAMDMA_OCP_SYSCONFIG_SIDLEMODE_FIDLE
			    | CAMDMA_OCP_SYSCONFIG_AUTOIDLE);

	omap24xxcam_reg_merge(base, CAMDMA_GCR, 0x10,
			      CAMDMA_GCR_MAX_CHANNEL_FIFO_DEPTH);

	omap24xxcam_reg_out(base, CAMDMA_IRQENABLE_L0, 0xf);
}

/*
 *
 * Individual DMA channel handling.
 *
 */

/* Start a DMA transfer from the camera to memory.
 * Returns zero if the transfer was successfully started, or non-zero if all
 * DMA channels are already in use or starting is currently inhibited.
 */
static int omap24xxcam_dma_start(struct omap24xxcam_dma *dma, dma_addr_t start,
				 u32 len, dma_callback_t callback, void *arg)
{
	unsigned long flags;
	int dmach;

	spin_lock_irqsave(&dma->lock, flags);

	if (!dma->free_dmach || atomic_read(&dma->dma_stop)) {
		spin_unlock_irqrestore(&dma->lock, flags);
		return -EBUSY;
	}

	dmach = dma->next_dmach;

	dma->ch_state[dmach].callback = callback;
	dma->ch_state[dmach].arg = arg;

	omap24xxcam_dmahw_transfer_setup(dma->base, dmach, start, len);

	/* We're ready to start the DMA transfer. */

	if (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
		/* A transfer is already in progress, so try to chain to it. */
		omap24xxcam_dmahw_transfer_chain(dma->base, dmach,
						 dma->free_dmach);
	} else {
		/* No transfer is in progress, so we'll just start this one
		 * now.
		 */
		omap24xxcam_dmahw_transfer_start(dma->base, dmach);
	}

	dma->next_dmach = (dma->next_dmach + 1) % NUM_CAMDMA_CHANNELS;
	dma->free_dmach--;

	spin_unlock_irqrestore(&dma->lock, flags);

	return 0;
}

/* Abort all chained DMA transfers. After all transfers have been
 * aborted and the DMA controller is idle, the completion routines for
 * any aborted transfers will be called in sequence. The DMA
 * controller may not be idle after this routine completes, because
 * the completion routines might start new transfers.
 */
static void omap24xxcam_dma_abort(struct omap24xxcam_dma *dma, u32 csr)
{
	unsigned long flags;
	int dmach, i, free_dmach;
	dma_callback_t callback;
	void *arg;

	spin_lock_irqsave(&dma->lock, flags);

	/* stop any DMA transfers in progress */
	dmach = (dma->next_dmach + dma->free_dmach) % NUM_CAMDMA_CHANNELS;
	for (i = 0; i < NUM_CAMDMA_CHANNELS; i++) {
		omap24xxcam_dmahw_abort_ch(dma->base, dmach);
		dmach = (dmach + 1) % NUM_CAMDMA_CHANNELS;
	}

	/* We have to be careful here because the callback routine
	 * might start a new DMA transfer, and we only want to abort
	 * transfers that were started before this routine was called.
	 */
	free_dmach = dma->free_dmach;
	while ((dma->free_dmach < NUM_CAMDMA_CHANNELS) &&
	       (free_dmach < NUM_CAMDMA_CHANNELS)) {
		dmach = (dma->next_dmach + dma->free_dmach)
			% NUM_CAMDMA_CHANNELS;
		callback = dma->ch_state[dmach].callback;
		arg = dma->ch_state[dmach].arg;
		dma->free_dmach++;
		free_dmach++;
		if (callback) {
			/* leave interrupts disabled during callback */
			spin_unlock(&dma->lock);
			(*callback) (dma, csr, arg);
			spin_lock(&dma->lock);
		}
	}

	spin_unlock_irqrestore(&dma->lock, flags);
}

/* Abort all chained DMA transfers. After all transfers have been
 * aborted and the DMA controller is idle, the completion routines for
 * any aborted transfers will be called in sequence. If the completion
 * routines attempt to start a new DMA transfer it will fail, so the
 * DMA controller will be idle after this routine completes.
 */
static void omap24xxcam_dma_stop(struct omap24xxcam_dma *dma, u32 csr)
{
	atomic_inc(&dma->dma_stop);
	omap24xxcam_dma_abort(dma, csr);
	atomic_dec(&dma->dma_stop);
}

/* Camera DMA interrupt service routine. */
void omap24xxcam_dma_isr(struct omap24xxcam_dma *dma)
{
	int dmach;
	dma_callback_t callback;
	void *arg;
	u32 csr;
	const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
		| CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
		| CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;

	spin_lock(&dma->lock);

	if (dma->free_dmach == NUM_CAMDMA_CHANNELS) {
		/* A camera DMA interrupt occurred while all channels
		 * are idle, so we'll acknowledge the interrupt in the
		 * IRQSTATUS register and exit.
		 */
		omap24xxcam_dmahw_ack_all(dma->base);
		spin_unlock(&dma->lock);
		return;
	}

	while (dma->free_dmach < NUM_CAMDMA_CHANNELS) {
		dmach = (dma->next_dmach + dma->free_dmach)
			% NUM_CAMDMA_CHANNELS;
		if (omap24xxcam_dmahw_running(dma->base, dmach)) {
			/* This buffer hasn't finished yet, so we're done. */
			break;
		}
		csr = omap24xxcam_dmahw_ack_ch(dma->base, dmach);
		if (csr & csr_error) {
			/* A DMA error occurred, so stop all DMA
			 * transfers in progress.
			 */
			spin_unlock(&dma->lock);
			omap24xxcam_dma_stop(dma, csr);
			return;
		} else {
			callback = dma->ch_state[dmach].callback;
			arg = dma->ch_state[dmach].arg;
			dma->free_dmach++;
			if (callback) {
				spin_unlock(&dma->lock);
				(*callback) (dma, csr, arg);
				spin_lock(&dma->lock);
			}
		}
	}

	spin_unlock(&dma->lock);

	omap24xxcam_sgdma_process(
		container_of(dma, struct omap24xxcam_sgdma, dma));
}

void omap24xxcam_dma_hwinit(struct omap24xxcam_dma *dma)
{
	unsigned long flags;

	spin_lock_irqsave(&dma->lock, flags);

	omap24xxcam_dmahw_init(dma->base);

	spin_unlock_irqrestore(&dma->lock, flags);
}

static void omap24xxcam_dma_init(struct omap24xxcam_dma *dma,
				 void __iomem *base)
{
	int ch;

	/* group all channels on DMA IRQ0 and unmask irq */
	spin_lock_init(&dma->lock);
	dma->base = base;
	dma->free_dmach = NUM_CAMDMA_CHANNELS;
	dma->next_dmach = 0;
	for (ch = 0; ch < NUM_CAMDMA_CHANNELS; ch++) {
		dma->ch_state[ch].callback = NULL;
		dma->ch_state[ch].arg = NULL;
	}
}

/*
 *
 * Scatter-gather DMA.
 *
 * High-level DMA construct for transferring whole picture frames to
 * memory that is discontinuous.
 *
 */

/* DMA completion routine for the scatter-gather DMA fragments. */
static void omap24xxcam_sgdma_callback(struct omap24xxcam_dma *dma, u32 csr,
				       void *arg)
{
	struct omap24xxcam_sgdma *sgdma =
		container_of(dma, struct omap24xxcam_sgdma, dma);
	int sgslot = (int)arg;
	struct sgdma_state *sg_state;
	const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
		| CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
		| CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;

	spin_lock(&sgdma->lock);

	/* We got an interrupt, we can remove the timer */
	del_timer(&sgdma->reset_timer);

	sg_state = sgdma->sg_state + sgslot;
	if (!sg_state->queued_sglist) {
		spin_unlock(&sgdma->lock);
		printk(KERN_ERR "%s: sgdma completed when none queued!\n",
		       __func__);
		return;
	}

	sg_state->csr |= csr;
	if (!--sg_state->queued_sglist) {
		/* Queue for this sglist is empty, so check to see if we're
		 * done.
		 */
		if ((sg_state->next_sglist == sg_state->sglen)
		    || (sg_state->csr & csr_error)) {
			sgdma_callback_t callback = sg_state->callback;
			void *arg = sg_state->arg;
			u32 sg_csr = sg_state->csr;
			/* All done with this sglist */
			sgdma->free_sgdma++;
			if (callback) {
				spin_unlock(&sgdma->lock);
				(*callback) (sgdma, sg_csr, arg);
				return;
			}
		}
	}

	spin_unlock(&sgdma->lock);
}

/* Start queued scatter-gather DMA transfers. */
void omap24xxcam_sgdma_process(struct omap24xxcam_sgdma *sgdma)
{
	unsigned long flags;
	int queued_sgdma, sgslot;
	struct sgdma_state *sg_state;
	const u32 csr_error = CAMDMA_CSR_MISALIGNED_ERR
		| CAMDMA_CSR_SUPERVISOR_ERR | CAMDMA_CSR_SECURE_ERR
		| CAMDMA_CSR_TRANS_ERR | CAMDMA_CSR_DROP;

	spin_lock_irqsave(&sgdma->lock, flags);

	queued_sgdma = NUM_SG_DMA - sgdma->free_sgdma;
	sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
	while (queued_sgdma > 0) {
		sg_state = sgdma->sg_state + sgslot;
		while ((sg_state->next_sglist < sg_state->sglen) &&
		       !(sg_state->csr & csr_error)) {
			const struct scatterlist *sglist;
			unsigned int len;

			sglist = sg_state->sglist + sg_state->next_sglist;
			/* try to start the next DMA transfer */
			if (sg_state->next_sglist + 1 == sg_state->sglen) {
				/*
				 *  On the last sg, we handle the case where
				 *  cam->img.pix.sizeimage % PAGE_ALIGN != 0
				 */
				len = sg_state->len - sg_state->bytes_read;
			} else {
				len = sg_dma_len(sglist);
			}

			if (omap24xxcam_dma_start(&sgdma->dma,
						  sg_dma_address(sglist),
						  len,
						  omap24xxcam_sgdma_callback,
						  (void *)sgslot)) {
				/* DMA start failed */
				spin_unlock_irqrestore(&sgdma->lock, flags);
				return;
			} else {
				unsigned long expires;
				/* DMA start was successful */
				sg_state->next_sglist++;
				sg_state->bytes_read += len;
				sg_state->queued_sglist++;

				/* We start the reset timer */
				expires = jiffies + HZ;
				mod_timer(&sgdma->reset_timer, expires);
			}
		}
		queued_sgdma--;
		sgslot = (sgslot + 1) % NUM_SG_DMA;
	}

	spin_unlock_irqrestore(&sgdma->lock, flags);
}

/*
 * Queue a scatter-gather DMA transfer from the camera to memory.
 * Returns zero if the transfer was successfully queued, or non-zero
 * if all of the scatter-gather slots are already in use.
 */
int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma,
			    const struct scatterlist *sglist, int sglen,
			    int len, sgdma_callback_t callback, void *arg)
{
	unsigned long flags;
	struct sgdma_state *sg_state;

	if ((sglen < 0) || ((sglen > 0) && !sglist))
		return -EINVAL;

	spin_lock_irqsave(&sgdma->lock, flags);

	if (!sgdma->free_sgdma) {
		spin_unlock_irqrestore(&sgdma->lock, flags);
		return -EBUSY;
	}

	sg_state = sgdma->sg_state + sgdma->next_sgdma;

	sg_state->sglist = sglist;
	sg_state->sglen = sglen;
	sg_state->next_sglist = 0;
	sg_state->bytes_read = 0;
	sg_state->len = len;
	sg_state->queued_sglist = 0;
	sg_state->csr = 0;
	sg_state->callback = callback;
	sg_state->arg = arg;

	sgdma->next_sgdma = (sgdma->next_sgdma + 1) % NUM_SG_DMA;
	sgdma->free_sgdma--;

	spin_unlock_irqrestore(&sgdma->lock, flags);

	omap24xxcam_sgdma_process(sgdma);

	return 0;
}

/* Sync scatter-gather DMA by aborting any DMA transfers currently in progress.
 * Any queued scatter-gather DMA transactions that have not yet been started
 * will remain queued.  The DMA controller will be idle after this routine
 * completes.  When the scatter-gather queue is restarted, the next
 * scatter-gather DMA transfer will begin at the start of a new transaction.
 */
void omap24xxcam_sgdma_sync(struct omap24xxcam_sgdma *sgdma)
{
	unsigned long flags;
	int sgslot;
	struct sgdma_state *sg_state;
	u32 csr = CAMDMA_CSR_TRANS_ERR;

	/* stop any DMA transfers in progress */
	omap24xxcam_dma_stop(&sgdma->dma, csr);

	spin_lock_irqsave(&sgdma->lock, flags);

	if (sgdma->free_sgdma < NUM_SG_DMA) {
		sgslot = (sgdma->next_sgdma + sgdma->free_sgdma) % NUM_SG_DMA;
		sg_state = sgdma->sg_state + sgslot;
		if (sg_state->next_sglist != 0) {
			/* This DMA transfer was in progress, so abort it. */
			sgdma_callback_t callback = sg_state->callback;
			void *arg = sg_state->arg;
			sgdma->free_sgdma++;
			if (callback) {
				/* leave interrupts masked */
				spin_unlock(&sgdma->lock);
				(*callback) (sgdma, csr, arg);
				spin_lock(&sgdma->lock);
			}
		}
	}

	spin_unlock_irqrestore(&sgdma->lock, flags);
}

void omap24xxcam_sgdma_init(struct omap24xxcam_sgdma *sgdma,
			    void __iomem *base,
			    void (*reset_callback)(unsigned long data),
			    unsigned long reset_callback_data)
{
	int sg;

	spin_lock_init(&sgdma->lock);
	sgdma->free_sgdma = NUM_SG_DMA;
	sgdma->next_sgdma = 0;
	for (sg = 0; sg < NUM_SG_DMA; sg++) {
		sgdma->sg_state[sg].sglen = 0;
		sgdma->sg_state[sg].next_sglist = 0;
		sgdma->sg_state[sg].bytes_read = 0;
		sgdma->sg_state[sg].queued_sglist = 0;
		sgdma->sg_state[sg].csr = 0;
		sgdma->sg_state[sg].callback = NULL;
		sgdma->sg_state[sg].arg = NULL;
	}

	omap24xxcam_dma_init(&sgdma->dma, base);
	setup_timer(&sgdma->reset_timer, reset_callback, reset_callback_data);
}
