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 18 static unsigned int xfer_complete; 19 static int count; 20 21 static 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 38 static 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 48 static int pvr2_get_dma_residue(struct dma_channel *chan) 49 { 50 return xfer_complete == 0; 51 } 52 53 static 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 67 static struct irqaction pvr2_dma_irq = { 68 .name = "pvr2 DMA handler", 69 .handler = pvr2_dma_interrupt, 70 }; 71 72 static struct dma_ops pvr2_dma_ops = { 73 .request = pvr2_request_dma, 74 .get_residue = pvr2_get_dma_residue, 75 .xfer = pvr2_xfer_dma, 76 }; 77 78 static struct dma_info pvr2_dma_info = { 79 .name = "pvr2_dmac", 80 .nr_channels = 1, 81 .ops = &pvr2_dma_ops, 82 .flags = DMAC_CHANNELS_TEI_CAPABLE, 83 }; 84 85 static int __init pvr2_dma_init(void) 86 { 87 setup_irq(HW_EVENT_PVR2_DMA, &pvr2_dma_irq); 88 request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade"); 89 90 return register_dmac(&pvr2_dma_info); 91 } 92 93 static void __exit pvr2_dma_exit(void) 94 { 95 free_dma(PVR2_CASCADE_CHAN); 96 free_irq(HW_EVENT_PVR2_DMA, 0); 97 unregister_dmac(&pvr2_dma_info); 98 } 99 100 subsys_initcall(pvr2_dma_init); 101 module_exit(pvr2_dma_exit); 102 103 MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); 104 MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver"); 105 MODULE_LICENSE("GPL v2"); 106