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