dma-pvr2.c (2272B)
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");