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 1 23 24 25 #include "exec/memory.h" 26 #include "hw/irq.h" 27 28 struct soc_dma_s; 29 struct soc_dma_ch_s; 30 typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len); 31 typedef void (*soc_dma_transfer_t)(struct soc_dma_ch_s *ch); 32 33 enum soc_dma_port_type { 34 soc_dma_port_mem, 35 soc_dma_port_fifo, 36 soc_dma_port_other, 37 }; 38 39 enum soc_dma_access_type { 40 soc_dma_access_const, 41 soc_dma_access_linear, 42 soc_dma_access_other, 43 }; 44 45 struct soc_dma_ch_s { 46 /* Private */ 47 struct soc_dma_s *dma; 48 int num; 49 QEMUTimer *timer; 50 51 /* Set by soc_dma.c */ 52 int enable; 53 int update; 54 55 /* This should be set by dma->setup_fn(). */ 56 int bytes; 57 /* Initialised by the DMA module, call soc_dma_ch_update after writing. */ 58 enum soc_dma_access_type type[2]; 59 hwaddr vaddr[2]; /* Updated by .transfer_fn(). */ 60 /* Private */ 61 void *paddr[2]; 62 soc_dma_io_t io_fn[2]; 63 void *io_opaque[2]; 64 65 int running; 66 soc_dma_transfer_t transfer_fn; 67 68 /* Set and used by the DMA module. */ 69 void *opaque; 70 }; 71 72 struct soc_dma_s { 73 /* Following fields are set by the SoC DMA module and can be used 74 * by anybody. */ 75 uint64_t drqbmp; /* Is zeroed by soc_dma_reset() */ 76 qemu_irq *drq; 77 void *opaque; 78 int64_t freq; 79 soc_dma_transfer_t transfer_fn; 80 soc_dma_transfer_t setup_fn; 81 /* Set by soc_dma_init() for use by the DMA module. */ 82 struct soc_dma_ch_s *ch; 83 }; 84 85 /* Call to activate or stop a DMA channel. */ 86 void soc_dma_set_request(struct soc_dma_ch_s *ch, int level); 87 /* Call after every write to one of the following fields and before 88 * calling soc_dma_set_request(ch, 1): 89 * ch->type[0...1], 90 * ch->vaddr[0...1], 91 * ch->paddr[0...1], 92 * or after a soc_dma_port_add_fifo() or soc_dma_port_add_mem(). */ 93 void soc_dma_ch_update(struct soc_dma_ch_s *ch); 94 95 /* The SoC should call this when the DMA module is being reset. */ 96 void soc_dma_reset(struct soc_dma_s *s); 97 struct soc_dma_s *soc_dma_init(int n); 98 99 void soc_dma_port_add_fifo(struct soc_dma_s *dma, hwaddr virt_base, 100 soc_dma_io_t fn, void *opaque, int out); 101 void soc_dma_port_add_mem(struct soc_dma_s *dma, uint8_t *phys_base, 102 hwaddr virt_base, size_t size); 103 104 static inline void soc_dma_port_add_fifo_in(struct soc_dma_s *dma, 105 hwaddr virt_base, soc_dma_io_t fn, void *opaque) 106 { 107 return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 0); 108 } 109 110 static inline void soc_dma_port_add_fifo_out(struct soc_dma_s *dma, 111 hwaddr virt_base, soc_dma_io_t fn, void *opaque) 112 { 113 return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 1); 114 } 115 116 #endif 117