1 /* 2 * On-chip DMA controller framework. 3 * 4 * Copyright (C) 2008 Nokia Corporation 5 * Written by Andrzej Zaborowski <andrew@openedhand.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 or 10 * (at your option) version 3 of the License. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef HW_SOC_DMA_H 22 #define HW_SOC_DMA_H 23 24 #include "exec/memory.h" 25 #include "hw/irq.h" 26 27 struct soc_dma_s; 28 struct soc_dma_ch_s; 29 typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len); 30 typedef void (*soc_dma_transfer_t)(struct soc_dma_ch_s *ch); 31 32 enum soc_dma_port_type { 33 soc_dma_port_mem, 34 soc_dma_port_fifo, 35 soc_dma_port_other, 36 }; 37 38 enum soc_dma_access_type { 39 soc_dma_access_const, 40 soc_dma_access_linear, 41 soc_dma_access_other, 42 }; 43 44 struct soc_dma_ch_s { 45 /* Private */ 46 struct soc_dma_s *dma; 47 int num; 48 QEMUTimer *timer; 49 50 /* Set by soc_dma.c */ 51 int enable; 52 int update; 53 54 /* This should be set by dma->setup_fn(). */ 55 int bytes; 56 /* Initialised by the DMA module, call soc_dma_ch_update after writing. */ 57 enum soc_dma_access_type type[2]; 58 hwaddr vaddr[2]; /* Updated by .transfer_fn(). */ 59 /* Private */ 60 void *paddr[2]; 61 soc_dma_io_t io_fn[2]; 62 void *io_opaque[2]; 63 64 int running; 65 soc_dma_transfer_t transfer_fn; 66 67 /* Set and used by the DMA module. */ 68 void *opaque; 69 }; 70 71 struct soc_dma_s { 72 /* Following fields are set by the SoC DMA module and can be used 73 * by anybody. */ 74 uint64_t drqbmp; /* Is zeroed by soc_dma_reset() */ 75 qemu_irq *drq; 76 void *opaque; 77 int64_t freq; 78 soc_dma_transfer_t transfer_fn; 79 soc_dma_transfer_t setup_fn; 80 /* Set by soc_dma_init() for use by the DMA module. */ 81 struct soc_dma_ch_s *ch; 82 }; 83 84 /* Call to activate or stop a DMA channel. */ 85 void soc_dma_set_request(struct soc_dma_ch_s *ch, int level); 86 /* Call after every write to one of the following fields and before 87 * calling soc_dma_set_request(ch, 1): 88 * ch->type[0...1], 89 * ch->vaddr[0...1], 90 * ch->paddr[0...1], 91 * or after a soc_dma_port_add_fifo() or soc_dma_port_add_mem(). */ 92 void soc_dma_ch_update(struct soc_dma_ch_s *ch); 93 94 /* The SoC should call this when the DMA module is being reset. */ 95 void soc_dma_reset(struct soc_dma_s *s); 96 struct soc_dma_s *soc_dma_init(int n); 97 98 void soc_dma_port_add_fifo(struct soc_dma_s *dma, hwaddr virt_base, 99 soc_dma_io_t fn, void *opaque, int out); 100 void soc_dma_port_add_mem(struct soc_dma_s *dma, uint8_t *phys_base, 101 hwaddr virt_base, size_t size); 102 103 static inline void soc_dma_port_add_fifo_in(struct soc_dma_s *dma, 104 hwaddr virt_base, soc_dma_io_t fn, void *opaque) 105 { 106 return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 0); 107 } 108 109 static inline void soc_dma_port_add_fifo_out(struct soc_dma_s *dma, 110 hwaddr virt_base, soc_dma_io_t fn, void *opaque) 111 { 112 return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 1); 113 } 114 115 #endif 116