1 /****************************************************************************** 2 * * 3 * License Agreement * 4 * * 5 * Copyright (c) 2011 Altera Corporation, San Jose, California, USA. * 6 * All rights reserved. * 7 * * 8 * Permission is hereby granted, free of charge, to any person obtaining a * 9 * copy of this software and associated documentation files (the "Software"), * 10 * to deal in the Software without restriction, including without limitation * 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 12 * and/or sell copies of the Software, and to permit persons to whom the * 13 * Software is furnished to do so, subject to the following conditions: * 14 * * 15 * The above copyright notice and this permission notice shall be included in * 16 * all copies or substantial portions of the Software. * 17 * * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * 24 * DEALINGS IN THE SOFTWARE. * 25 * * 26 * * 27 ******************************************************************************/ 28 29 #ifndef __ALTERA_AVALON_SGDMA_H__ 30 #define __ALTERA_AVALON_SGDMA_H__ 31 32 #include <stddef.h> 33 #include <errno.h> 34 35 #include "sys/alt_dev.h" 36 #include "alt_types.h" 37 #include "altera_avalon_sgdma_descriptor.h" 38 39 #ifdef __cplusplus 40 extern "C" 41 { 42 #endif /* __cplusplus */ 43 44 /* 45 * The function alt_find_dev() is used to search the device list "list" to 46 * locate a device named "name". If a match is found, then a pointer to the 47 * device is returned, otherwise NULL is returned. 48 */ 49 extern alt_dev* alt_find_dev (const char* name, alt_llist* list); 50 51 /* Callback routine type definition */ 52 typedef void (*alt_avalon_sgdma_callback)(void *context); 53 54 /* SGDMA Device Structure */ 55 typedef struct alt_sgdma_dev 56 { 57 alt_llist llist; // Device linked-list entry 58 const char *name; // Name of SGDMA in SOPC System 59 void *base; // Base address of SGDMA 60 alt_u32 *descriptor_base; // reserved 61 alt_u32 next_index; // reserved 62 alt_u32 num_descriptors; // reserved 63 alt_sgdma_descriptor *current_descriptor; // reserved 64 alt_sgdma_descriptor *next_descriptor; // reserved 65 alt_avalon_sgdma_callback callback; // Callback routine pointer 66 void *callback_context; // Callback context pointer 67 alt_u32 chain_control; // Value OR'd into control reg 68 } alt_sgdma_dev; 69 70 71 /******************************************************************************* 72 * Public API 73 ******************************************************************************/ 74 75 /* API for "application managed" operation */ 76 int alt_avalon_sgdma_do_async_transfer( 77 alt_sgdma_dev *dev, 78 alt_sgdma_descriptor *desc); 79 80 alt_u8 alt_avalon_sgdma_do_sync_transfer( 81 alt_sgdma_dev *dev, 82 alt_sgdma_descriptor *desc); 83 84 void alt_avalon_sgdma_construct_mem_to_mem_desc( 85 alt_sgdma_descriptor *desc, 86 alt_sgdma_descriptor *next, 87 alt_u32 *read_addr, 88 alt_u32 *write_addr, 89 alt_u16 length, 90 int read_fixed, 91 int write_fixed); 92 93 void alt_avalon_sgdma_construct_mem_to_mem_desc_burst( 94 alt_sgdma_descriptor *desc, 95 alt_sgdma_descriptor *next, 96 alt_u32 *read_addr, 97 alt_u32 *write_addr, 98 alt_u16 length, 99 int read_fixed, 100 int write_fixed, 101 int read_burst, 102 int write_burst); 103 104 void alt_avalon_sgdma_construct_stream_to_mem_desc( 105 alt_sgdma_descriptor *desc, 106 alt_sgdma_descriptor *next, 107 alt_u32 *write_addr, 108 alt_u16 length_or_eop, 109 int write_fixed); 110 111 void alt_avalon_sgdma_construct_stream_to_mem_desc_burst( 112 alt_sgdma_descriptor *desc, 113 alt_sgdma_descriptor *next, 114 alt_u32 *write_addr, 115 alt_u16 length_or_eop, 116 int write_fixed, 117 int write_burst); 118 119 void alt_avalon_sgdma_construct_mem_to_stream_desc( 120 alt_sgdma_descriptor *desc, 121 alt_sgdma_descriptor *next, 122 alt_u32 *read_addr, 123 alt_u16 length, 124 int read_fixed, 125 int generate_sop, 126 int generate_eop, 127 alt_u8 atlantic_channel); 128 129 void alt_avalon_sgdma_construct_mem_to_stream_desc_burst( 130 alt_sgdma_descriptor *desc, 131 alt_sgdma_descriptor *next, 132 alt_u32 *read_addr, 133 alt_u16 length, 134 int read_fixed, 135 int generate_sop, 136 int generate_eop, 137 int read_burst, 138 alt_u8 atlantic_channel); 139 140 void alt_avalon_sgdma_register_callback( 141 alt_sgdma_dev *dev, 142 alt_avalon_sgdma_callback callback, 143 alt_u32 chain_control, 144 void *context); 145 146 void alt_avalon_sgdma_start(alt_sgdma_dev *dev); 147 148 void alt_avalon_sgdma_stop(alt_sgdma_dev *dev); 149 150 int alt_avalon_sgdma_check_descriptor_status(alt_sgdma_descriptor *desc); 151 152 alt_sgdma_dev* alt_avalon_sgdma_open (const char* name); 153 154 void alt_avalon_sgdma_enable_desc_poll(alt_sgdma_dev *dev, alt_u32 frequency); 155 156 void alt_avalon_sgdma_disable_desc_poll(alt_sgdma_dev *dev); 157 158 /* Private API */ 159 void alt_avalon_sgdma_construct_descriptor( 160 alt_sgdma_descriptor *desc, 161 alt_sgdma_descriptor *next, 162 alt_u32 *read_addr, 163 alt_u32 *write_addr, 164 alt_u16 length_or_eop, 165 int generate_eop, 166 int read_fixed, 167 int write_fixed_or_sop, 168 alt_u8 atlantic_channel); 169 170 /* Private API */ 171 void alt_avalon_sgdma_construct_descriptor_burst( 172 alt_sgdma_descriptor *desc, 173 alt_sgdma_descriptor *next, 174 alt_u32 *read_addr, 175 alt_u32 *write_addr, 176 alt_u16 length_or_eop, 177 int generate_eop, 178 int read_fixed, 179 int write_fixed_or_sop, 180 int read_burst, 181 int write_burst, 182 alt_u8 atlantic_channel); 183 184 void alt_avalon_sgdma_init (alt_sgdma_dev *dev, alt_u32 ic_id, alt_u32 irq); 185 186 /* HAL initialization macros */ 187 188 /* 189 * ALTERA_AVALON_SGDMA_INSTANCE is the macro used by alt_sys_init() to 190 * allocate any per device memory that may be required. 191 */ 192 #define ALTERA_AVALON_SGDMA_INSTANCE(name, dev) \ 193 static alt_sgdma_dev dev = \ 194 { \ 195 ALT_LLIST_ENTRY, \ 196 name##_NAME, \ 197 ((void *)(name##_BASE)), \ 198 ((alt_u32 *) 0x0), \ 199 ((alt_u32) 0x0), \ 200 ((alt_u32) 0x0), \ 201 ((alt_sgdma_descriptor *) 0x0), \ 202 ((alt_sgdma_descriptor *) 0x0), \ 203 ((void *) 0x0), \ 204 ((void *) 0x0), \ 205 ((alt_u16) 0x0) \ 206 }; 207 208 /* 209 * The macro ALTERA_AVALON_SGDMA_INIT is called by the auto-generated function 210 * alt_sys_init() to initialize a given device instance. 211 */ 212 #define ALTERA_AVALON_SGDMA_INIT(name, dev) \ 213 if (name##_IRQ == ALT_IRQ_NOT_CONNECTED) \ 214 { \ 215 ALT_LINK_ERROR ("Error: Interrupt not connected for " #dev ". " \ 216 "The Altera Avalon Scatter-Gather DMA driver requires " \ 217 "that an interrupt is connected. Please select an IRQ " \ 218 "for this device in SOPC builder."); \ 219 } \ 220 else \ 221 { \ 222 alt_avalon_sgdma_init(&dev, name##_IRQ_INTERRUPT_CONTROLLER_ID, \ 223 name##_IRQ); \ 224 } 225 226 #ifdef __cplusplus 227 } 228 #endif /* __cplusplus */ 229 230 #endif /* __ALTERA_AVALON_SGDMA_H__ */ 231