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 dma_ops pvr2_dma_ops = { 68 .request = pvr2_request_dma, 69 .get_residue = pvr2_get_dma_residue, 70 .xfer = pvr2_xfer_dma, 71 }; 72 73 static 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 80 static 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 90 static 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 97 subsys_initcall(pvr2_dma_init); 98 module_exit(pvr2_dma_exit); 99 100 MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); 101 MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver"); 102 MODULE_LICENSE("GPL v2"); 103