| /* | 
 |  * On-chip DMA controller framework. | 
 |  * | 
 |  * Copyright (C) 2008 Nokia Corporation | 
 |  * Written by Andrzej Zaborowski <andrew@openedhand.com> | 
 |  * | 
 |  * This program is free software; you can redistribute it and/or | 
 |  * modify it under the terms of the GNU General Public License as | 
 |  * published by the Free Software Foundation; either version 2 or | 
 |  * (at your option) version 3 of the License. | 
 |  * | 
 |  * This program is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |  * GNU General Public License for more details. | 
 |  * | 
 |  * You should have received a copy of the GNU General Public License along | 
 |  * with this program; if not, see <http://www.gnu.org/licenses/>. | 
 |  */ | 
 |  | 
 | struct soc_dma_s; | 
 | struct soc_dma_ch_s; | 
 | typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len); | 
 | typedef void (*soc_dma_transfer_t)(struct soc_dma_ch_s *ch); | 
 |  | 
 | enum soc_dma_port_type { | 
 |     soc_dma_port_mem, | 
 |     soc_dma_port_fifo, | 
 |     soc_dma_port_other, | 
 | }; | 
 |  | 
 | enum soc_dma_access_type { | 
 |     soc_dma_access_const, | 
 |     soc_dma_access_linear, | 
 |     soc_dma_access_other, | 
 | }; | 
 |  | 
 | struct soc_dma_ch_s { | 
 |     /* Private */ | 
 |     struct soc_dma_s *dma; | 
 |     int num; | 
 |     QEMUTimer *timer; | 
 |  | 
 |     /* Set by soc_dma.c */ | 
 |     int enable; | 
 |     int update; | 
 |  | 
 |     /* This should be set by dma->setup_fn().  */ | 
 |     int bytes; | 
 |     /* Initialised by the DMA module, call soc_dma_ch_update after writing.  */ | 
 |     enum soc_dma_access_type type[2]; | 
 |     target_phys_addr_t vaddr[2];	/* Updated by .transfer_fn().  */ | 
 |     /* Private */ | 
 |     void *paddr[2]; | 
 |     soc_dma_io_t io_fn[2]; | 
 |     void *io_opaque[2]; | 
 |  | 
 |     int running; | 
 |     soc_dma_transfer_t transfer_fn; | 
 |  | 
 |     /* Set and used by the DMA module.  */ | 
 |     void *opaque; | 
 | }; | 
 |  | 
 | struct soc_dma_s { | 
 |     /* Following fields are set by the SoC DMA module and can be used | 
 |      * by anybody.  */ | 
 |     uint64_t drqbmp;	/* Is zeroed by soc_dma_reset() */ | 
 |     qemu_irq *drq; | 
 |     void *opaque; | 
 |     int64_t freq; | 
 |     soc_dma_transfer_t transfer_fn; | 
 |     soc_dma_transfer_t setup_fn; | 
 |     /* Set by soc_dma_init() for use by the DMA module.  */ | 
 |     struct soc_dma_ch_s *ch; | 
 | }; | 
 |  | 
 | /* Call to activate or stop a DMA channel.  */ | 
 | void soc_dma_set_request(struct soc_dma_ch_s *ch, int level); | 
 | /* Call after every write to one of the following fields and before | 
 |  * calling soc_dma_set_request(ch, 1): | 
 |  *   ch->type[0...1], | 
 |  *   ch->vaddr[0...1], | 
 |  *   ch->paddr[0...1], | 
 |  * or after a soc_dma_port_add_fifo() or soc_dma_port_add_mem().  */ | 
 | void soc_dma_ch_update(struct soc_dma_ch_s *ch); | 
 |  | 
 | /* The SoC should call this when the DMA module is being reset.  */ | 
 | void soc_dma_reset(struct soc_dma_s *s); | 
 | struct soc_dma_s *soc_dma_init(int n); | 
 |  | 
 | void soc_dma_port_add_fifo(struct soc_dma_s *dma, target_phys_addr_t virt_base, | 
 |                 soc_dma_io_t fn, void *opaque, int out); | 
 | void soc_dma_port_add_mem(struct soc_dma_s *dma, uint8_t *phys_base, | 
 |                 target_phys_addr_t virt_base, size_t size); | 
 |  | 
 | static inline void soc_dma_port_add_fifo_in(struct soc_dma_s *dma, | 
 |                 target_phys_addr_t virt_base, soc_dma_io_t fn, void *opaque) | 
 | { | 
 |     return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 0); | 
 | } | 
 |  | 
 | static inline void soc_dma_port_add_fifo_out(struct soc_dma_s *dma, | 
 |                 target_phys_addr_t virt_base, soc_dma_io_t fn, void *opaque) | 
 | { | 
 |     return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 1); | 
 | } | 
 |  | 
 | static inline void soc_dma_port_add_mem_ram(struct soc_dma_s *dma, | 
 |                 ram_addr_t offset, target_phys_addr_t virt_base, size_t size) | 
 | { | 
 |     return soc_dma_port_add_mem(dma, qemu_get_ram_ptr(offset), virt_base, size); | 
 | } |