/*
 * arch/sh/drivers/dma/dma-sh.c
 *
 * SuperH On-chip DMAC Support
 *
 * Copyright (C) 2000 Takashi YOSHII
 * Copyright (C) 2003, 2004 Paul Mundt
 * Copyright (C) 2005 Andriy Skulysh
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <mach-dreamcast/mach/dma.h>
#include <asm/dma.h>
#include <asm/io.h>
#include "dma-sh.h"

static int dmte_irq_map[] = {
	DMTE0_IRQ,
	DMTE1_IRQ,
	DMTE2_IRQ,
	DMTE3_IRQ,
#if defined(CONFIG_CPU_SUBTYPE_SH7720)  ||	\
    defined(CONFIG_CPU_SUBTYPE_SH7721)  ||	\
    defined(CONFIG_CPU_SUBTYPE_SH7751R) ||	\
    defined(CONFIG_CPU_SUBTYPE_SH7760)  ||	\
    defined(CONFIG_CPU_SUBTYPE_SH7709)  ||	\
    defined(CONFIG_CPU_SUBTYPE_SH7780)
	DMTE4_IRQ,
	DMTE5_IRQ,
#endif
#if defined(CONFIG_CPU_SUBTYPE_SH7751R) ||	\
    defined(CONFIG_CPU_SUBTYPE_SH7760)  ||	\
    defined(CONFIG_CPU_SUBTYPE_SH7780)
	DMTE6_IRQ,
	DMTE7_IRQ,
#endif
};

static inline unsigned int get_dmte_irq(unsigned int chan)
{
	unsigned int irq = 0;
	if (chan < ARRAY_SIZE(dmte_irq_map))
		irq = dmte_irq_map[chan];
	return irq;
}

/*
 * We determine the correct shift size based off of the CHCR transmit size
 * for the given channel. Since we know that it will take:
 *
 *	info->count >> ts_shift[transmit_size]
 *
 * iterations to complete the transfer.
 */
static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
{
	u32 chcr = ctrl_inl(CHCR[chan->chan]);

	return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT];
}

/*
 * The transfer end interrupt must read the chcr register to end the
 * hardware interrupt active condition.
 * Besides that it needs to waken any waiting process, which should handle
 * setting up the next transfer.
 */
static irqreturn_t dma_tei(int irq, void *dev_id)
{
	struct dma_channel *chan = dev_id;
	u32 chcr;

	chcr = ctrl_inl(CHCR[chan->chan]);

	if (!(chcr & CHCR_TE))
		return IRQ_NONE;

	chcr &= ~(CHCR_IE | CHCR_DE);
	ctrl_outl(chcr, CHCR[chan->chan]);

	wake_up(&chan->wait_queue);

	return IRQ_HANDLED;
}

static int sh_dmac_request_dma(struct dma_channel *chan)
{
	if (unlikely(!(chan->flags & DMA_TEI_CAPABLE)))
		return 0;

	return request_irq(get_dmte_irq(chan->chan), dma_tei,
			   IRQF_DISABLED, chan->dev_id, chan);
}

static void sh_dmac_free_dma(struct dma_channel *chan)
{
	free_irq(get_dmte_irq(chan->chan), chan);
}

static int
sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
{
	if (!chcr)
		chcr = RS_DUAL | CHCR_IE;

	if (chcr & CHCR_IE) {
		chcr &= ~CHCR_IE;
		chan->flags |= DMA_TEI_CAPABLE;
	} else {
		chan->flags &= ~DMA_TEI_CAPABLE;
	}

	ctrl_outl(chcr, CHCR[chan->chan]);

	chan->flags |= DMA_CONFIGURED;
	return 0;
}

static void sh_dmac_enable_dma(struct dma_channel *chan)
{
	int irq;
	u32 chcr;

	chcr = ctrl_inl(CHCR[chan->chan]);
	chcr |= CHCR_DE;

	if (chan->flags & DMA_TEI_CAPABLE)
		chcr |= CHCR_IE;

	ctrl_outl(chcr, CHCR[chan->chan]);

	if (chan->flags & DMA_TEI_CAPABLE) {
		irq = get_dmte_irq(chan->chan);
		enable_irq(irq);
	}
}

static void sh_dmac_disable_dma(struct dma_channel *chan)
{
	int irq;
	u32 chcr;

	if (chan->flags & DMA_TEI_CAPABLE) {
		irq = get_dmte_irq(chan->chan);
		disable_irq(irq);
	}

	chcr = ctrl_inl(CHCR[chan->chan]);
	chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
	ctrl_outl(chcr, CHCR[chan->chan]);
}

static int sh_dmac_xfer_dma(struct dma_channel *chan)
{
	/*
	 * If we haven't pre-configured the channel with special flags, use
	 * the defaults.
	 */
	if (unlikely(!(chan->flags & DMA_CONFIGURED)))
		sh_dmac_configure_channel(chan, 0);

	sh_dmac_disable_dma(chan);

	/*
	 * Single-address mode usage note!
	 *
	 * It's important that we don't accidentally write any value to SAR/DAR
	 * (this includes 0) that hasn't been directly specified by the user if
	 * we're in single-address mode.
	 *
	 * In this case, only one address can be defined, anything else will
	 * result in a DMA address error interrupt (at least on the SH-4),
	 * which will subsequently halt the transfer.
	 *
	 * Channel 2 on the Dreamcast is a special case, as this is used for
	 * cascading to the PVR2 DMAC. In this case, we still need to write
	 * SAR and DAR, regardless of value, in order for cascading to work.
	 */
	if (chan->sar || (mach_is_dreamcast() &&
			  chan->chan == PVR2_CASCADE_CHAN))
		ctrl_outl(chan->sar, SAR[chan->chan]);
	if (chan->dar || (mach_is_dreamcast() &&
			  chan->chan == PVR2_CASCADE_CHAN))
		ctrl_outl(chan->dar, DAR[chan->chan]);

	ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]);

	sh_dmac_enable_dma(chan);

	return 0;
}

static int sh_dmac_get_dma_residue(struct dma_channel *chan)
{
	if (!(ctrl_inl(CHCR[chan->chan]) & CHCR_DE))
		return 0;

	return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan);
}

#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
    defined(CONFIG_CPU_SUBTYPE_SH7780)
#define dmaor_read_reg()	ctrl_inw(DMAOR)
#define dmaor_write_reg(data)	ctrl_outw(data, DMAOR)
#else
#define dmaor_read_reg()	ctrl_inl(DMAOR)
#define dmaor_write_reg(data)	ctrl_outl(data, DMAOR)
#endif

static inline int dmaor_reset(void)
{
	unsigned long dmaor = dmaor_read_reg();

	/* Try to clear the error flags first, incase they are set */
	dmaor &= ~(DMAOR_NMIF | DMAOR_AE);
	dmaor_write_reg(dmaor);

	dmaor |= DMAOR_INIT;
	dmaor_write_reg(dmaor);

	/* See if we got an error again */
	if ((dmaor_read_reg() & (DMAOR_AE | DMAOR_NMIF))) {
		printk(KERN_ERR "dma-sh: Can't initialize DMAOR.\n");
		return -EINVAL;
	}

	return 0;
}

#if defined(CONFIG_CPU_SH4)
static irqreturn_t dma_err(int irq, void *dummy)
{
	dmaor_reset();
	disable_irq(irq);

	return IRQ_HANDLED;
}
#endif

static struct dma_ops sh_dmac_ops = {
	.request	= sh_dmac_request_dma,
	.free		= sh_dmac_free_dma,
	.get_residue	= sh_dmac_get_dma_residue,
	.xfer		= sh_dmac_xfer_dma,
	.configure	= sh_dmac_configure_channel,
};

static struct dma_info sh_dmac_info = {
	.name		= "sh_dmac",
	.nr_channels	= CONFIG_NR_ONCHIP_DMA_CHANNELS,
	.ops		= &sh_dmac_ops,
	.flags		= DMAC_CHANNELS_TEI_CAPABLE,
};

static int __init sh_dmac_init(void)
{
	struct dma_info *info = &sh_dmac_info;
	int i;

#ifdef CONFIG_CPU_SH4
	i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
	if (unlikely(i < 0))
		return i;
#endif

	/*
	 * Initialize DMAOR, and clean up any error flags that may have
	 * been set.
	 */
	i = dmaor_reset();
	if (unlikely(i != 0))
		return i;

	return register_dmac(info);
}

static void __exit sh_dmac_exit(void)
{
#ifdef CONFIG_CPU_SH4
	free_irq(DMAE_IRQ, 0);
#endif
	unregister_dmac(&sh_dmac_info);
}

subsys_initcall(sh_dmac_init);
module_exit(sh_dmac_exit);

MODULE_AUTHOR("Takashi YOSHII, Paul Mundt, Andriy Skulysh");
MODULE_DESCRIPTION("SuperH On-Chip DMAC Support");
MODULE_LICENSE("GPL");
