1 /****************************************************************************** 2 * * 3 * License Agreement * 4 * * 5 * Copyright (c) 2014 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_MSGDMA_H__ 30 #define __ALTERA_MSGDMA_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_msgdma_csr_regs.h" 38 #include "altera_msgdma_descriptor_regs.h" 39 #include "altera_msgdma_response_regs.h" 40 #include "altera_msgdma_prefetcher_regs.h" 41 #include "os/alt_sem.h" 42 #include "os/alt_flag.h" 43 44 #ifdef __cplusplus 45 extern "C" 46 { 47 #endif /* __cplusplus */ 48 49 /* 50 * Helper struct to have easy access to hi/low values from a 64 bit value. 51 * Useful when having to write prefetcher/descriptor 64 bit addresses. 52 */ 53 typedef union { 54 alt_u64 u64; 55 alt_u32 u32[2]; 56 } msgdma_addr64; 57 58 /* 59 * To ensure that a descriptor is created without spaces between the structure 60 * members, we call upon GCC's ability to pack to a byte-aligned boundary. 61 * Additionally, msgdma requires the descriptors to be aligned to a 16 byte 62 * boundary. 63 */ 64 #define alt_msgdma_standard_descriptor_packed \ 65 __attribute__ ((packed, aligned(16))) 66 #define alt_msgdma_extended_descriptor_packed \ 67 __attribute__ ((packed, aligned(32))) 68 #define alt_msgdma_prefetcher_standard_descriptor_packed \ 69 __attribute__ ((packed, aligned(32))) 70 #define alt_msgdma_prefetcher_extended_descriptor_packed \ 71 __attribute__ ((packed, aligned(64))) 72 #define alt_msgdma_response_packed __attribute__ ((packed, aligned(4))) 73 74 /* 75 * The function alt_find_dev() is used to search the device list "list" to 76 * locate a device named "name". If a match is found, then a pointer to the 77 * device is returned, otherwise NULL is returned. 78 */ 79 extern alt_dev* alt_find_dev (const char* name, alt_llist* list); 80 81 /* Callback routine type definition */ 82 typedef void (*alt_msgdma_callback)(void *context); 83 84 /* use this structure if you haven't enabled the enhanced features */ 85 typedef struct { 86 alt_u32 *read_address; 87 alt_u32 *write_address; 88 alt_u32 transfer_length; 89 alt_u32 control; 90 } alt_msgdma_standard_descriptor_packed alt_msgdma_standard_descriptor; 91 92 /* use this structure if you have enabled the enhanced features (only the 93 * elements enabled in hardware will be used) 94 */ 95 typedef struct { 96 alt_u32 *read_address_low; 97 alt_u32 *write_address_low; 98 alt_u32 transfer_length; 99 alt_u16 sequence_number; 100 alt_u8 read_burst_count; 101 alt_u8 write_burst_count; 102 alt_u16 read_stride; 103 alt_u16 write_stride; 104 alt_u32 *read_address_high; 105 alt_u32 *write_address_high; 106 alt_u32 control; 107 } alt_msgdma_extended_descriptor_packed alt_msgdma_extended_descriptor; 108 109 110 /* Prefetcher Descriptors need to be different than standard dispatcher 111 * descriptors use this structure if you haven't enabled the enhanced 112 * features 113 */ 114 typedef struct { 115 alt_u32 read_address; 116 alt_u32 write_address; 117 alt_u32 transfer_length; 118 alt_u32 next_desc_ptr; 119 alt_u32 bytes_transfered; 120 alt_u16 status; 121 alt_u16 _pad1_rsvd; 122 alt_u32 _pad2_rsvd; 123 alt_u32 control; 124 } alt_msgdma_prefetcher_standard_descriptor_packed alt_msgdma_prefetcher_standard_descriptor; 125 126 /* use this structure if you have enabled the enhanced features (only the elements 127 enabled in hardware will be used) */ 128 typedef struct { 129 alt_u32 read_address_low; 130 alt_u32 write_address_low; 131 alt_u32 transfer_length; 132 alt_u32 next_desc_ptr_low; 133 alt_u32 bytes_transfered; 134 alt_u16 status; 135 alt_u16 _pad1_rsvd; 136 alt_u32 _pad2_rsvd; 137 alt_u16 sequence_number; 138 alt_u8 read_burst_count; 139 alt_u8 write_burst_count; 140 alt_u16 read_stride; 141 alt_u16 write_stride; 142 alt_u32 read_address_high; 143 alt_u32 write_address_high; 144 alt_u32 next_desc_ptr_high; 145 alt_u32 _pad3_rsvd[3]; 146 alt_u32 control; 147 } alt_msgdma_prefetcher_extended_descriptor_packed alt_msgdma_prefetcher_extended_descriptor; 148 149 150 /* msgdma device structure */ 151 typedef struct alt_msgdma_dev 152 { 153 /* Device linked-list entry */ 154 alt_llist llist; 155 /* Name of msgdma in Qsys system */ 156 const char *name; 157 /* Base address of control and status register */ 158 alt_u32 *csr_base; 159 /* Base address of the descriptor slave port */ 160 alt_u32 *descriptor_base; 161 /* Base address of the response register */ 162 alt_u32 *response_base; 163 /* Base address of the prefetcher register */ 164 alt_u32 *prefetcher_base; 165 /* device IRQ controller ID */ 166 alt_u32 irq_controller_ID; 167 /* device IRQ ID */ 168 alt_u32 irq_ID; 169 /* FIFO size to store descriptor count, 170 { 8, 16, 32, 64,default:128, 256, 512, 1024 } */ 171 alt_u32 descriptor_fifo_depth; 172 /* FIFO size to store response count */ 173 alt_u32 response_fifo_depth; 174 /* Callback routine pointer */ 175 alt_msgdma_callback callback; 176 /* Callback context pointer */ 177 void *callback_context; 178 /* user define control setting during interrupt registering*/ 179 alt_u32 control; 180 /* Enable burst transfer */ 181 alt_u8 burst_enable; 182 /* Enable burst wrapping */ 183 alt_u8 burst_wrapping_support; 184 /* Depth of the internal data path FIFO*/ 185 alt_u32 data_fifo_depth; 186 /* Data path Width. This parameter affect both read 187 master and write master data width */ 188 alt_u32 data_width; 189 /* Maximum burst count*/ 190 alt_u32 max_burst_count; 191 /* Maximum transfer length*/ 192 alt_u32 max_byte; 193 /* Maximum stride count */ 194 alt_u64 max_stride; 195 /* Enable dynamic burst programming*/ 196 alt_u8 programmable_burst_enable; 197 /* Enable stride addressing */ 198 alt_u8 stride_enable; 199 /* Supported transaction type */ 200 const char *transfer_type; 201 /* Extended feature support enable "1"-enable "0"-disable */ 202 alt_u8 enhanced_features; 203 /* Enable response port "0"-memory-mapped, "1"-streaming, "2"-disable */ 204 alt_u8 response_port; 205 /* Prefetcher enabled "0"-disabled, "1"-enabled*/ 206 alt_u8 prefetcher_enable; 207 /* Semaphore used to control access registers 208 in multi-threaded mode */ 209 ALT_SEM (regs_lock) 210 } alt_msgdma_dev; 211 212 213 214 /******************************************************************************* 215 * Public API 216 ******************************************************************************/ 217 alt_msgdma_dev* alt_msgdma_open (const char* name); 218 219 void alt_msgdma_register_callback( 220 alt_msgdma_dev *dev, 221 alt_msgdma_callback callback, 222 alt_u32 control, 223 void *context); 224 225 int alt_msgdma_standard_descriptor_async_transfer( 226 alt_msgdma_dev *dev, 227 alt_msgdma_standard_descriptor *desc); 228 229 int alt_msgdma_extended_descriptor_async_transfer( 230 alt_msgdma_dev *dev, 231 alt_msgdma_extended_descriptor *desc); 232 233 int alt_msgdma_construct_standard_mm_to_mm_descriptor ( 234 alt_msgdma_dev *dev, 235 alt_msgdma_standard_descriptor *descriptor, 236 alt_u32 *read_address, 237 alt_u32 *write_address, 238 alt_u32 length, 239 alt_u32 control); 240 241 int alt_msgdma_construct_standard_st_to_mm_descriptor ( 242 alt_msgdma_dev *dev, 243 alt_msgdma_standard_descriptor *descriptor, 244 alt_u32 *write_address, 245 alt_u32 length, 246 alt_u32 control); 247 248 int alt_msgdma_construct_standard_mm_to_st_descriptor ( 249 alt_msgdma_dev *dev, 250 alt_msgdma_standard_descriptor *descriptor, 251 alt_u32 *read_address, 252 alt_u32 length, 253 alt_u32 control); 254 255 int alt_msgdma_construct_extended_st_to_mm_descriptor ( 256 alt_msgdma_dev *dev, 257 alt_msgdma_extended_descriptor *descriptor, 258 alt_u32 *write_address, 259 alt_u32 length, 260 alt_u32 control, 261 alt_u16 sequence_number, 262 alt_u8 write_burst_count, 263 alt_u16 write_stride); 264 265 int alt_msgdma_construct_extended_mm_to_st_descriptor ( 266 alt_msgdma_dev *dev, 267 alt_msgdma_extended_descriptor *descriptor, 268 alt_u32 *read_address, 269 alt_u32 length, 270 alt_u32 control, 271 alt_u16 sequence_number, 272 alt_u8 read_burst_count, 273 alt_u16 read_stride); 274 275 int alt_msgdma_construct_extended_mm_to_mm_descriptor ( 276 alt_msgdma_dev *dev, 277 alt_msgdma_extended_descriptor *descriptor, 278 alt_u32 *read_address, 279 alt_u32 *write_address, 280 alt_u32 length, 281 alt_u32 control, 282 alt_u16 sequence_number, 283 alt_u8 read_burst_count, 284 alt_u8 write_burst_count, 285 alt_u16 read_stride, 286 alt_u16 write_stride); 287 288 int alt_msgdma_standard_descriptor_sync_transfer( 289 alt_msgdma_dev *dev, 290 alt_msgdma_standard_descriptor *desc); 291 292 int alt_msgdma_extended_descriptor_sync_transfer( 293 alt_msgdma_dev *dev, 294 alt_msgdma_extended_descriptor *desc); 295 296 int alt_msgdma_standard_descriptor_sync_transfer( 297 alt_msgdma_dev *dev, 298 alt_msgdma_standard_descriptor *desc); 299 300 /***************** MSGDMA PREFETCHER PUBLIC APIs ******************/ 301 int alt_msgdma_construct_prefetcher_standard_mm_to_mm_descriptor ( 302 alt_msgdma_dev *dev, 303 alt_msgdma_prefetcher_standard_descriptor *descriptor, 304 alt_u32 read_address, 305 alt_u32 write_address, 306 alt_u32 length, 307 alt_u32 control); 308 309 int alt_msgdma_construct_prefetcher_standard_st_to_mm_descriptor ( 310 alt_msgdma_dev *dev, 311 alt_msgdma_prefetcher_standard_descriptor *descriptor, 312 alt_u32 write_address, 313 alt_u32 length, 314 alt_u32 control); 315 316 int alt_msgdma_construct_prefetcher_standard_mm_to_st_descriptor ( 317 alt_msgdma_dev *dev, 318 alt_msgdma_prefetcher_standard_descriptor *descriptor, 319 alt_u32 read_address, 320 alt_u32 length, 321 alt_u32 control); 322 323 int alt_msgdma_construct_prefetcher_extended_st_to_mm_descriptor ( 324 alt_msgdma_dev *dev, 325 alt_msgdma_prefetcher_extended_descriptor *descriptor, 326 alt_u32 write_address_high, 327 alt_u32 write_address_low, 328 alt_u32 length, 329 alt_u32 control, 330 alt_u16 sequence_number, 331 alt_u8 write_burst_count, 332 alt_u16 write_stride); 333 334 int alt_msgdma_construct_prefetcher_extended_mm_to_st_descriptor ( 335 alt_msgdma_dev *dev, 336 alt_msgdma_prefetcher_extended_descriptor *descriptor, 337 alt_u32 read_address_high, 338 alt_u32 read_address_low, 339 alt_u32 length, 340 alt_u32 control, 341 alt_u16 sequence_number, 342 alt_u8 read_burst_count, 343 alt_u16 read_stride); 344 345 int alt_msgdma_construct_prefetcher_extended_mm_to_mm_descriptor ( 346 alt_msgdma_dev *dev, 347 alt_msgdma_prefetcher_extended_descriptor *descriptor, 348 alt_u32 read_address_high, 349 alt_u32 read_address_low, 350 alt_u32 write_address_high, 351 alt_u32 write_address_low, 352 alt_u32 length, 353 alt_u32 control, 354 alt_u16 sequence_number, 355 alt_u8 read_burst_count, 356 alt_u8 write_burst_count, 357 alt_u16 read_stride, 358 alt_u16 write_stride); 359 360 int alt_msgdma_prefetcher_add_standard_desc_to_list ( 361 alt_msgdma_prefetcher_standard_descriptor** list, 362 alt_msgdma_prefetcher_standard_descriptor* descriptor); 363 364 int alt_msgdma_prefetcher_add_extended_desc_to_list ( 365 alt_msgdma_prefetcher_extended_descriptor** list, 366 alt_msgdma_prefetcher_extended_descriptor* descriptor); 367 368 int alt_msgdma_start_prefetcher_with_std_desc_list ( 369 alt_msgdma_dev *dev, 370 alt_msgdma_prefetcher_standard_descriptor *list, 371 alt_u8 park_mode_en, 372 alt_u8 poll_en); 373 374 int alt_msgdma_start_prefetcher_with_extd_desc_list ( 375 alt_msgdma_dev *dev, 376 alt_msgdma_prefetcher_extended_descriptor *list, 377 alt_u8 park_mode_en, 378 alt_u8 poll_en); 379 380 int alt_msgdma_prefetcher_set_std_list_own_by_hw_bits ( 381 alt_msgdma_prefetcher_standard_descriptor *list); 382 int alt_msgdma_prefetcher_set_extd_list_own_by_hw_bits ( 383 alt_msgdma_prefetcher_extended_descriptor *list); 384 385 void alt_msgdma_init (alt_msgdma_dev *dev, alt_u32 ic_id, alt_u32 irq); 386 387 /* HAL initialization macros */ 388 389 /*Depth of internal data path FIFO.STRIDE_ENABLE 390 * ALTERA_MSGDMA_INSTANCE is the macro used by alt_sys_init() to 391 * allocate any per device memory that may be required. 392 */ 393 #define ALTERA_MSGDMA_CSR_DESCRIPTOR_SLAVE_RESPONSE_INSTANCE(name, csr_if, desc_if, resp_if, dev) \ 394 static alt_msgdma_dev dev = \ 395 { \ 396 ALT_LLIST_ENTRY, \ 397 name##_CSR_NAME, \ 398 ((alt_u32 *)(csr_if##_BASE)), \ 399 ((alt_u32 *)(desc_if##_BASE)), \ 400 ((alt_u32 *)(resp_if##_BASE)), \ 401 ((alt_u32 *)(0)), \ 402 ((alt_u32 )name##_CSR_IRQ_INTERRUPT_CONTROLLER_ID), \ 403 ((alt_u32 )name##_CSR_IRQ), \ 404 ((alt_u32 )desc_if##_DESCRIPTOR_FIFO_DEPTH), \ 405 ((alt_u32 )resp_if##_DESCRIPTOR_FIFO_DEPTH * 2), \ 406 ((void *) 0x0), \ 407 ((void *) 0x0), \ 408 ((alt_u32) 0x0), \ 409 ((alt_u8) csr_if##_BURST_ENABLE), \ 410 ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT), \ 411 ((alt_u32) csr_if##_DATA_FIFO_DEPTH), \ 412 ((alt_u32) csr_if##_DATA_WIDTH), \ 413 ((alt_u32) csr_if##_MAX_BURST_COUNT), \ 414 ((alt_u32) csr_if##_MAX_BYTE), \ 415 ((alt_u64) csr_if##_MAX_STRIDE), \ 416 ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE), \ 417 ((alt_u8) csr_if##_STRIDE_ENABLE), \ 418 csr_if##_TRANSFER_TYPE, \ 419 ((alt_u8) csr_if##_ENHANCED_FEATURES), \ 420 ((alt_u8) csr_if##_RESPONSE_PORT), \ 421 ((alt_u8) csr_if##_PREFETCHER_ENABLE) \ 422 }; 423 424 #define ALTERA_MSGDMA_CSR_DESCRIPTOR_SLAVE_INSTANCE(name, csr_if, desc_if, dev) \ 425 static alt_msgdma_dev dev = \ 426 { \ 427 ALT_LLIST_ENTRY, \ 428 name##_CSR_NAME, \ 429 ((alt_u32 *)(csr_if##_BASE)), \ 430 ((alt_u32 *)(desc_if##_BASE)), \ 431 ((alt_u32 *)(0)), \ 432 ((alt_u32 *)(0)), \ 433 ((alt_u32 )name##_CSR_IRQ_INTERRUPT_CONTROLLER_ID), \ 434 ((alt_u32 )name##_CSR_IRQ), \ 435 ((alt_u32 )desc_if##_DESCRIPTOR_FIFO_DEPTH), \ 436 ((alt_u32) 0x0), \ 437 ((void *) 0x0), \ 438 ((void *) 0x0), \ 439 ((alt_u32) 0x0), \ 440 ((alt_u8) csr_if##_BURST_ENABLE), \ 441 ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT), \ 442 ((alt_u32) csr_if##_DATA_FIFO_DEPTH), \ 443 ((alt_u32) csr_if##_DATA_WIDTH), \ 444 ((alt_u32) csr_if##_MAX_BURST_COUNT), \ 445 ((alt_u32) csr_if##_MAX_BYTE), \ 446 ((alt_u64) csr_if##_MAX_STRIDE), \ 447 ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE), \ 448 ((alt_u8) csr_if##_STRIDE_ENABLE), \ 449 csr_if##_TRANSFER_TYPE, \ 450 ((alt_u8) csr_if##_ENHANCED_FEATURES), \ 451 ((alt_u8) csr_if##_RESPONSE_PORT), \ 452 ((alt_u8) csr_if##_PREFETCHER_ENABLE) \ 453 }; 454 455 /* 456 * New Interface for Prefetcher 15/6/2015. 457 */ 458 #define ALTERA_MSGDMA_CSR_PREFETCHER_CSR_INSTANCE(name, csr_if, pref_if, dev) \ 459 static alt_msgdma_dev dev = \ 460 { \ 461 ALT_LLIST_ENTRY, \ 462 name##_CSR_NAME, \ 463 ((alt_u32 *)(csr_if##_BASE)), \ 464 ((alt_u32 *)(0)), \ 465 ((alt_u32 *)(0)), \ 466 ((alt_u32 *)(pref_if##_BASE)), \ 467 ((alt_u32 )name##_PREFETCHER_CSR_IRQ_INTERRUPT_CONTROLLER_ID), \ 468 ((alt_u32 )name##_PREFETCHER_CSR_IRQ), \ 469 ((alt_u32 )(0)), \ 470 ((alt_u32) 0x0), \ 471 ((void *) 0x0), \ 472 ((void *) 0x0), \ 473 ((alt_u32) 0x0), \ 474 ((alt_u8) csr_if##_BURST_ENABLE), \ 475 ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT), \ 476 ((alt_u32) csr_if##_DATA_FIFO_DEPTH), \ 477 ((alt_u32) csr_if##_DATA_WIDTH), \ 478 ((alt_u32) csr_if##_MAX_BURST_COUNT), \ 479 ((alt_u32) csr_if##_MAX_BYTE), \ 480 ((alt_u64) csr_if##_MAX_STRIDE), \ 481 ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE), \ 482 ((alt_u8) csr_if##_STRIDE_ENABLE), \ 483 csr_if##_TRANSFER_TYPE, \ 484 ((alt_u8) csr_if##_ENHANCED_FEATURES), \ 485 ((alt_u8) csr_if##_RESPONSE_PORT), \ 486 ((alt_u8) csr_if##_PREFETCHER_ENABLE) \ 487 }; 488 489 490 /* 491 * The macro ALTERA_MSGDMA_INIT is called by the auto-generated function 492 * alt_sys_init() to initialize a given device instance. 493 */ 494 #define ALTERA_MSGDMA_INIT(name, dev) \ 495 alt_msgdma_init(&dev, dev.irq_controller_ID, dev.irq_ID); 496 497 #ifdef __cplusplus 498 } 499 #endif /* __cplusplus */ 500 501 #endif /* __ALTERA_MSGDMA_H__ */ 502