/****************************************************************************** * * * License Agreement * * * * Copyright (c) 2014 Altera Corporation, San Jose, California, USA. * * All rights reserved. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the "Software"), * * to deal in the Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, distribute, sublicense, * * and/or sell copies of the Software, and to permit persons to whom the * * Software is furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * * DEALINGS IN THE SOFTWARE. * * * * This agreement shall be governed in all respects by the laws of the State * * of California and by the laws of the United States of America. * * * ******************************************************************************/ #ifndef __ALTERA_MSGDMA_H__ #define __ALTERA_MSGDMA_H__ #include #include #include "sys/alt_dev.h" #include "alt_types.h" #include "altera_msgdma_csr_regs.h" #include "altera_msgdma_descriptor_regs.h" #include "altera_msgdma_response_regs.h" #include "altera_msgdma_prefetcher_regs.h" #include "os/alt_sem.h" #include "os/alt_flag.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * Helper struct to have easy access to hi/low values from a 64 bit value. * Useful when having to write prefetcher/descriptor 64 bit addresses. */ typedef union { alt_u64 u64; alt_u32 u32[2]; } msgdma_addr64; /* * To ensure that a descriptor is created without spaces between the structure * members, we call upon GCC's ability to pack to a byte-aligned boundary. * Additionally, msgdma requires the descriptors to be aligned to a 16 byte * boundary. */ #define alt_msgdma_standard_descriptor_packed \ __attribute__ ((packed, aligned(16))) #define alt_msgdma_extended_descriptor_packed \ __attribute__ ((packed, aligned(32))) #define alt_msgdma_prefetcher_standard_descriptor_packed \ __attribute__ ((packed, aligned(32))) #define alt_msgdma_prefetcher_extended_descriptor_packed \ __attribute__ ((packed, aligned(64))) #define alt_msgdma_response_packed __attribute__ ((packed, aligned(4))) /* * The function alt_find_dev() is used to search the device list "list" to * locate a device named "name". If a match is found, then a pointer to the * device is returned, otherwise NULL is returned. */ extern alt_dev* alt_find_dev (const char* name, alt_llist* list); /* Callback routine type definition */ typedef void (*alt_msgdma_callback)(void *context); /* use this structure if you haven't enabled the enhanced features */ typedef struct { alt_u32 *read_address; alt_u32 *write_address; alt_u32 transfer_length; alt_u32 control; } alt_msgdma_standard_descriptor_packed alt_msgdma_standard_descriptor; /* use this structure if you have enabled the enhanced features (only the * elements enabled in hardware will be used) */ typedef struct { alt_u32 *read_address_low; alt_u32 *write_address_low; alt_u32 transfer_length; alt_u16 sequence_number; alt_u8 read_burst_count; alt_u8 write_burst_count; alt_u16 read_stride; alt_u16 write_stride; alt_u32 *read_address_high; alt_u32 *write_address_high; alt_u32 control; } alt_msgdma_extended_descriptor_packed alt_msgdma_extended_descriptor; /* Prefetcher Descriptors need to be different than standard dispatcher * descriptors use this structure if you haven't enabled the enhanced * features */ typedef struct { alt_u32 read_address; alt_u32 write_address; alt_u32 transfer_length; alt_u32 next_desc_ptr; alt_u32 bytes_transfered; alt_u16 status; alt_u16 _pad1_rsvd; alt_u32 _pad2_rsvd; alt_u32 control; } alt_msgdma_prefetcher_standard_descriptor_packed alt_msgdma_prefetcher_standard_descriptor; /* use this structure if you have enabled the enhanced features (only the elements enabled in hardware will be used) */ typedef struct { alt_u32 read_address_low; alt_u32 write_address_low; alt_u32 transfer_length; alt_u32 next_desc_ptr_low; alt_u32 bytes_transfered; alt_u16 status; alt_u16 _pad1_rsvd; alt_u32 _pad2_rsvd; alt_u16 sequence_number; alt_u8 read_burst_count; alt_u8 write_burst_count; alt_u16 read_stride; alt_u16 write_stride; alt_u32 read_address_high; alt_u32 write_address_high; alt_u32 next_desc_ptr_high; alt_u32 _pad3_rsvd[3]; alt_u32 control; } alt_msgdma_prefetcher_extended_descriptor_packed alt_msgdma_prefetcher_extended_descriptor; /* msgdma device structure */ typedef struct alt_msgdma_dev { /* Device linked-list entry */ alt_llist llist; /* Name of msgdma in Qsys system */ const char *name; /* Base address of control and status register */ alt_u32 *csr_base; /* Base address of the descriptor slave port */ alt_u32 *descriptor_base; /* Base address of the response register */ alt_u32 *response_base; /* Base address of the prefetcher register */ alt_u32 *prefetcher_base; /* device IRQ controller ID */ alt_u32 irq_controller_ID; /* device IRQ ID */ alt_u32 irq_ID; /* FIFO size to store descriptor count, { 8, 16, 32, 64,default:128, 256, 512, 1024 } */ alt_u32 descriptor_fifo_depth; /* FIFO size to store response count */ alt_u32 response_fifo_depth; /* Callback routine pointer */ alt_msgdma_callback callback; /* Callback context pointer */ void *callback_context; /* user define control setting during interrupt registering*/ alt_u32 control; /* Enable burst transfer */ alt_u8 burst_enable; /* Enable burst wrapping */ alt_u8 burst_wrapping_support; /* Depth of the internal data path FIFO*/ alt_u32 data_fifo_depth; /* Data path Width. This parameter affect both read master and write master data width */ alt_u32 data_width; /* Maximum burst count*/ alt_u32 max_burst_count; /* Maximum transfer length*/ alt_u32 max_byte; /* Maximum stride count */ alt_u64 max_stride; /* Enable dynamic burst programming*/ alt_u8 programmable_burst_enable; /* Enable stride addressing */ alt_u8 stride_enable; /* Supported transaction type */ const char *transfer_type; /* Extended feature support enable "1"-enable "0"-disable */ alt_u8 enhanced_features; /* Enable response port "0"-memory-mapped, "1"-streaming, "2"-disable */ alt_u8 response_port; /* Prefetcher enabled "0"-disabled, "1"-enabled*/ alt_u8 prefetcher_enable; /* Semaphore used to control access registers in multi-threaded mode */ ALT_SEM (regs_lock) } __attribute__ ((aligned(0x10))) alt_msgdma_dev; /******************************************************************************* * Public API ******************************************************************************/ alt_msgdma_dev* alt_msgdma_open (const char* name); void alt_msgdma_register_callback( alt_msgdma_dev *dev, alt_msgdma_callback callback, alt_u32 control, void *context); int alt_msgdma_standard_descriptor_async_transfer( alt_msgdma_dev *dev, alt_msgdma_standard_descriptor *desc); int alt_msgdma_extended_descriptor_async_transfer( alt_msgdma_dev *dev, alt_msgdma_extended_descriptor *desc); int alt_msgdma_construct_standard_mm_to_mm_descriptor ( alt_msgdma_dev *dev, alt_msgdma_standard_descriptor *descriptor, alt_u32 *read_address, alt_u32 *write_address, alt_u32 length, alt_u32 control); int alt_msgdma_construct_standard_st_to_mm_descriptor ( alt_msgdma_dev *dev, alt_msgdma_standard_descriptor *descriptor, alt_u32 *write_address, alt_u32 length, alt_u32 control); int alt_msgdma_construct_standard_mm_to_st_descriptor ( alt_msgdma_dev *dev, alt_msgdma_standard_descriptor *descriptor, alt_u32 *read_address, alt_u32 length, alt_u32 control); int alt_msgdma_construct_extended_st_to_mm_descriptor ( alt_msgdma_dev *dev, alt_msgdma_extended_descriptor *descriptor, alt_u32 *write_address, alt_u32 length, alt_u32 control, alt_u16 sequence_number, alt_u8 write_burst_count, alt_u16 write_stride); int alt_msgdma_construct_extended_mm_to_st_descriptor ( alt_msgdma_dev *dev, alt_msgdma_extended_descriptor *descriptor, alt_u32 *read_address, alt_u32 length, alt_u32 control, alt_u16 sequence_number, alt_u8 read_burst_count, alt_u16 read_stride); int alt_msgdma_construct_extended_mm_to_mm_descriptor ( alt_msgdma_dev *dev, alt_msgdma_extended_descriptor *descriptor, alt_u32 *read_address, alt_u32 *write_address, alt_u32 length, alt_u32 control, alt_u16 sequence_number, alt_u8 read_burst_count, alt_u8 write_burst_count, alt_u16 read_stride, alt_u16 write_stride); int alt_msgdma_standard_descriptor_sync_transfer( alt_msgdma_dev *dev, alt_msgdma_standard_descriptor *desc); int alt_msgdma_extended_descriptor_sync_transfer( alt_msgdma_dev *dev, alt_msgdma_extended_descriptor *desc); int alt_msgdma_standard_descriptor_sync_transfer( alt_msgdma_dev *dev, alt_msgdma_standard_descriptor *desc); /***************** MSGDMA PREFETCHER PUBLIC APIs ******************/ int alt_msgdma_construct_prefetcher_standard_mm_to_mm_descriptor ( alt_msgdma_dev *dev, alt_msgdma_prefetcher_standard_descriptor *descriptor, alt_u32 read_address, alt_u32 write_address, alt_u32 length, alt_u32 control); int alt_msgdma_construct_prefetcher_standard_st_to_mm_descriptor ( alt_msgdma_dev *dev, alt_msgdma_prefetcher_standard_descriptor *descriptor, alt_u32 write_address, alt_u32 length, alt_u32 control); int alt_msgdma_construct_prefetcher_standard_mm_to_st_descriptor ( alt_msgdma_dev *dev, alt_msgdma_prefetcher_standard_descriptor *descriptor, alt_u32 read_address, alt_u32 length, alt_u32 control); int alt_msgdma_construct_prefetcher_extended_st_to_mm_descriptor ( alt_msgdma_dev *dev, alt_msgdma_prefetcher_extended_descriptor *descriptor, alt_u32 write_address_high, alt_u32 write_address_low, alt_u32 length, alt_u32 control, alt_u16 sequence_number, alt_u8 write_burst_count, alt_u16 write_stride); int alt_msgdma_construct_prefetcher_extended_mm_to_st_descriptor ( alt_msgdma_dev *dev, alt_msgdma_prefetcher_extended_descriptor *descriptor, alt_u32 read_address_high, alt_u32 read_address_low, alt_u32 length, alt_u32 control, alt_u16 sequence_number, alt_u8 read_burst_count, alt_u16 read_stride); int alt_msgdma_construct_prefetcher_extended_mm_to_mm_descriptor ( alt_msgdma_dev *dev, alt_msgdma_prefetcher_extended_descriptor *descriptor, alt_u32 read_address_high, alt_u32 read_address_low, alt_u32 write_address_high, alt_u32 write_address_low, alt_u32 length, alt_u32 control, alt_u16 sequence_number, alt_u8 read_burst_count, alt_u8 write_burst_count, alt_u16 read_stride, alt_u16 write_stride); int alt_msgdma_prefetcher_add_standard_desc_to_list ( alt_msgdma_prefetcher_standard_descriptor** list, alt_msgdma_prefetcher_standard_descriptor* descriptor); int alt_msgdma_prefetcher_add_extended_desc_to_list ( alt_msgdma_prefetcher_extended_descriptor** list, alt_msgdma_prefetcher_extended_descriptor* descriptor); int alt_msgdma_start_prefetcher_with_std_desc_list ( alt_msgdma_dev *dev, alt_msgdma_prefetcher_standard_descriptor *list, alt_u8 park_mode_en, alt_u8 poll_en, alt_u8 last_desc_owned_by_sw, alt_u8 dcache_flush_desc_list); int alt_msgdma_start_prefetcher_with_extd_desc_list ( alt_msgdma_dev *dev, alt_msgdma_prefetcher_extended_descriptor *list, alt_u8 park_mode_en, alt_u8 poll_en, alt_u8 last_desc_owned_by_sw, alt_u8 dcache_flush_desc_list); int alt_msgdma_prefetcher_set_std_list_own_by_hw_bits ( alt_msgdma_prefetcher_standard_descriptor *list, alt_u8 last_desc_owned_by_sw, alt_u8 dcache_flush_desc_list); int alt_msgdma_prefetcher_set_extd_list_own_by_hw_bits ( alt_msgdma_prefetcher_extended_descriptor *list, alt_u8 last_desc_owned_by_sw, alt_u8 dcache_flush_desc_list); void alt_msgdma_init (alt_msgdma_dev *dev, alt_u32 ic_id, alt_u32 irq); /* HAL initialization macros */ /*Depth of internal data path FIFO.STRIDE_ENABLE * ALTERA_MSGDMA_INSTANCE is the macro used by alt_sys_init() to * allocate any per device memory that may be required. */ #define ALTERA_MSGDMA_CSR_DESCRIPTOR_SLAVE_RESPONSE_INSTANCE(name, csr_if, desc_if, resp_if, dev) \ static alt_msgdma_dev dev = \ { \ ALT_LLIST_ENTRY, \ name##_CSR_NAME, \ ((alt_u32 *)(csr_if##_BASE)), \ ((alt_u32 *)(desc_if##_BASE)), \ ((alt_u32 *)(resp_if##_BASE)), \ ((alt_u32 *)(0)), \ ((alt_u32 )name##_CSR_IRQ_INTERRUPT_CONTROLLER_ID), \ ((alt_u32 )name##_CSR_IRQ), \ ((alt_u32 )desc_if##_DESCRIPTOR_FIFO_DEPTH), \ ((alt_u32 )resp_if##_DESCRIPTOR_FIFO_DEPTH * 2), \ ((void *) 0x0), \ ((void *) 0x0), \ ((alt_u32) 0x0), \ ((alt_u8) csr_if##_BURST_ENABLE), \ ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT), \ ((alt_u32) csr_if##_DATA_FIFO_DEPTH), \ ((alt_u32) csr_if##_DATA_WIDTH), \ ((alt_u32) csr_if##_MAX_BURST_COUNT), \ ((alt_u32) csr_if##_MAX_BYTE), \ ((alt_u64) csr_if##_MAX_STRIDE), \ ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE), \ ((alt_u8) csr_if##_STRIDE_ENABLE), \ csr_if##_TRANSFER_TYPE, \ ((alt_u8) csr_if##_ENHANCED_FEATURES), \ ((alt_u8) csr_if##_RESPONSE_PORT), \ ((alt_u8) csr_if##_PREFETCHER_ENABLE) \ }; #define ALTERA_MSGDMA_CSR_DESCRIPTOR_SLAVE_INSTANCE(name, csr_if, desc_if, dev) \ static alt_msgdma_dev dev = \ { \ ALT_LLIST_ENTRY, \ name##_CSR_NAME, \ ((alt_u32 *)(csr_if##_BASE)), \ ((alt_u32 *)(desc_if##_BASE)), \ ((alt_u32 *)(0)), \ ((alt_u32 *)(0)), \ ((alt_u32 )name##_CSR_IRQ_INTERRUPT_CONTROLLER_ID), \ ((alt_u32 )name##_CSR_IRQ), \ ((alt_u32 )desc_if##_DESCRIPTOR_FIFO_DEPTH), \ ((alt_u32) 0x0), \ ((void *) 0x0), \ ((void *) 0x0), \ ((alt_u32) 0x0), \ ((alt_u8) csr_if##_BURST_ENABLE), \ ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT), \ ((alt_u32) csr_if##_DATA_FIFO_DEPTH), \ ((alt_u32) csr_if##_DATA_WIDTH), \ ((alt_u32) csr_if##_MAX_BURST_COUNT), \ ((alt_u32) csr_if##_MAX_BYTE), \ ((alt_u64) csr_if##_MAX_STRIDE), \ ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE), \ ((alt_u8) csr_if##_STRIDE_ENABLE), \ csr_if##_TRANSFER_TYPE, \ ((alt_u8) csr_if##_ENHANCED_FEATURES), \ ((alt_u8) csr_if##_RESPONSE_PORT), \ ((alt_u8) csr_if##_PREFETCHER_ENABLE) \ }; /* * New Interface for Prefetcher 15/6/2015. */ #define ALTERA_MSGDMA_CSR_PREFETCHER_CSR_INSTANCE(name, csr_if, pref_if, dev) \ static alt_msgdma_dev dev = \ { \ ALT_LLIST_ENTRY, \ name##_CSR_NAME, \ ((alt_u32 *)(csr_if##_BASE)), \ ((alt_u32 *)(0)), \ ((alt_u32 *)(0)), \ ((alt_u32 *)(pref_if##_BASE)), \ ((alt_u32 )name##_PREFETCHER_CSR_IRQ_INTERRUPT_CONTROLLER_ID), \ ((alt_u32 )name##_PREFETCHER_CSR_IRQ), \ ((alt_u32 )(0)), \ ((alt_u32) 0x0), \ ((void *) 0x0), \ ((void *) 0x0), \ ((alt_u32) 0x0), \ ((alt_u8) csr_if##_BURST_ENABLE), \ ((alt_u8) csr_if##_BURST_WRAPPING_SUPPORT), \ ((alt_u32) csr_if##_DATA_FIFO_DEPTH), \ ((alt_u32) csr_if##_DATA_WIDTH), \ ((alt_u32) csr_if##_MAX_BURST_COUNT), \ ((alt_u32) csr_if##_MAX_BYTE), \ ((alt_u64) csr_if##_MAX_STRIDE), \ ((alt_u8) csr_if##_PROGRAMMABLE_BURST_ENABLE), \ ((alt_u8) csr_if##_STRIDE_ENABLE), \ csr_if##_TRANSFER_TYPE, \ ((alt_u8) csr_if##_ENHANCED_FEATURES), \ ((alt_u8) csr_if##_RESPONSE_PORT), \ ((alt_u8) csr_if##_PREFETCHER_ENABLE) \ }; /* * The macro ALTERA_MSGDMA_INIT is called by the auto-generated function * alt_sys_init() to initialize a given device instance. */ #define ALTERA_MSGDMA_INIT(name, dev) \ alt_msgdma_init(&dev, dev.irq_controller_ID, dev.irq_ID); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __ALTERA_MSGDMA_H__ */