linux/arch/sh/drivers/dma/dma-pvr2.c
<<
>>
Prefs
   1/*
   2 * arch/sh/drivers/dma/dma-pvr2.c
   3 *
   4 * NEC PowerVR 2 (Dreamcast) DMA support
   5 *
   6 * Copyright (C) 2003, 2004  Paul Mundt
   7 *
   8 * This file is subject to the terms and conditions of the GNU General Public
   9 * License.  See the file "COPYING" in the main directory of this archive
  10 * for more details.
  11 */
  12#include <linux/init.h>
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/interrupt.h>
  16#include <mach/sysasic.h>
  17#include <mach/dma.h>
  18#include <asm/dma.h>
  19#include <asm/io.h>
  20
  21static unsigned int xfer_complete;
  22static int count;
  23
  24static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id)
  25{
  26        if (get_dma_residue(PVR2_CASCADE_CHAN)) {
  27                printk(KERN_WARNING "DMA: SH DMAC did not complete transfer "
  28                       "on channel %d, waiting..\n", PVR2_CASCADE_CHAN);
  29                dma_wait_for_completion(PVR2_CASCADE_CHAN);
  30        }
  31
  32        if (count++ < 10)
  33                pr_debug("Got a pvr2 dma interrupt for channel %d\n",
  34                         irq - HW_EVENT_PVR2_DMA);
  35
  36        xfer_complete = 1;
  37
  38        return IRQ_HANDLED;
  39}
  40
  41static int pvr2_request_dma(struct dma_channel *chan)
  42{
  43        if (__raw_readl(PVR2_DMA_MODE) != 0)
  44                return -EBUSY;
  45
  46        __raw_writel(0, PVR2_DMA_LMMODE0);
  47
  48        return 0;
  49}
  50
  51static int pvr2_get_dma_residue(struct dma_channel *chan)
  52{
  53        return xfer_complete == 0;
  54}
  55
  56static int pvr2_xfer_dma(struct dma_channel *chan)
  57{
  58        if (chan->sar || !chan->dar)
  59                return -EINVAL;
  60
  61        xfer_complete = 0;
  62
  63        __raw_writel(chan->dar, PVR2_DMA_ADDR);
  64        __raw_writel(chan->count, PVR2_DMA_COUNT);
  65        __raw_writel(chan->mode & DMA_MODE_MASK, PVR2_DMA_MODE);
  66
  67        return 0;
  68}
  69
  70static struct irqaction pvr2_dma_irq = {
  71        .name           = "pvr2 DMA handler",
  72        .handler        = pvr2_dma_interrupt,
  73};
  74
  75static struct dma_ops pvr2_dma_ops = {
  76        .request        = pvr2_request_dma,
  77        .get_residue    = pvr2_get_dma_residue,
  78        .xfer           = pvr2_xfer_dma,
  79};
  80
  81static struct dma_info pvr2_dma_info = {
  82        .name           = "pvr2_dmac",
  83        .nr_channels    = 1,
  84        .ops            = &pvr2_dma_ops,
  85        .flags          = DMAC_CHANNELS_TEI_CAPABLE,
  86};
  87
  88static int __init pvr2_dma_init(void)
  89{
  90        setup_irq(HW_EVENT_PVR2_DMA, &pvr2_dma_irq);
  91        request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade");
  92
  93        return register_dmac(&pvr2_dma_info);
  94}
  95
  96static void __exit pvr2_dma_exit(void)
  97{
  98        free_dma(PVR2_CASCADE_CHAN);
  99        free_irq(HW_EVENT_PVR2_DMA, 0);
 100        unregister_dmac(&pvr2_dma_info);
 101}
 102
 103subsys_initcall(pvr2_dma_init);
 104module_exit(pvr2_dma_exit);
 105
 106MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
 107MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver");
 108MODULE_LICENSE("GPL");
 109