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