diff options
Diffstat (limited to 'include/bsp/VMEDMA.h')
-rw-r--r-- | include/bsp/VMEDMA.h | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/include/bsp/VMEDMA.h b/include/bsp/VMEDMA.h new file mode 100644 index 0000000000..636f6d365c --- /dev/null +++ b/include/bsp/VMEDMA.h @@ -0,0 +1,309 @@ +/** + * @file + * + * @ingroup shared_vmedma + * + * @brief Public interface of DMA routines + */ + +#ifndef BSP_VME_DMA_H +#define BSP_VME_DMA_H + +/* + * Authorship + * ---------- + * This software was created by + * Till Straumann <strauman@slac.stanford.edu>, 2006, 2007 + * Stanford Linear Accelerator Center, Stanford University. + * + * Acknowledgement of sponsorship + * ------------------------------ + * This software was produced by + * the Stanford Linear Accelerator Center, Stanford University, + * under Contract DE-AC03-76SFO0515 with the Department of Energy. + * + * Government disclaimer of liability + * ---------------------------------- + * Neither the United States nor the United States Department of Energy, + * nor any of their employees, makes any warranty, express or implied, or + * assumes any legal liability or responsibility for the accuracy, + * completeness, or usefulness of any data, apparatus, product, or process + * disclosed, or represents that its use would not infringe privately owned + * rights. + * + * Stanford disclaimer of liability + * -------------------------------- + * Stanford University makes no representations or warranties, express or + * implied, nor assumes any liability for the use of this software. + * + * Stanford disclaimer of copyright + * -------------------------------- + * Stanford University, owner of the copyright, hereby disclaims its + * copyright and all other rights in this software. Hence, anyone may + * freely use it for any purpose without restriction. + * + * Maintenance of notices + * ---------------------- + * In the interest of clarity regarding the origin and status of this + * SLAC software, this and all the preceding Stanford University notices + * are to remain affixed to any copy or derivative of this software made + * or distributed by the recipient and are to be affixed to any copy of + * software made or distributed by the recipient that contains a copy or + * derivative of this software. + * + * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03 + */ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup shared_vmedma VMEDMA Support + * + * @ingroup shared_vmeuniverse + * + * @brief VMEDMA Support Package + */ + + +/* NOTE: Access to DMA Channels is *not* protected / thread-safe. + * It is the responsability of the user to provide appropriate + * locking/serialization. + */ + +/* Simple abstraction of DMA controller setup / bus utilization: */ + +/* Since VME is the bottleneck, the settings for PCI are always + * chosen aggressively. + */ + + +/* Optimize for throughput; accept longer latencies: + * Choose a large block size (1k) and immediately re-request + * the bus at block boundaries. + */ +#define BSP_VMEDMA_OPT_THROUGHPUT 1 +/* Optimize for latency, accept throughput penalty: + * Choose a small block size (32b) and immediately re-request + * the bus at block boundaries. + */ +#define BSP_VMEDMA_OPT_LOWLATENCY 2 + +/* Optimize for bus sharing with other devices: + * Choose relatively small block size (128) and back off for 64us + * at each block boundary. + */ +#define BSP_VMEDMA_OPT_SHAREDBUS 3 + +/* Choose bridge default/reset configuration: + * (see manual) + */ +#define BSP_VMEDMA_OPT_DEFAULT 4 + +/* Provide custom configuration pass pointer to array + * with as many 32-bit words the particular bridge chip + * expects. + */ +#define BSP_VMEDMA_OPT_CUSTOM 5 + +/* VME Transfer modes */ + +/* Bitwise OR of the VME address-modifier/transfer-type + * with driver specific (no standard AM code for 2eVME and + * 2eSST defined) and optional special flags (see below) + */ + +/* Additional qualifiers: */ + +/* Don't increment VME address */ +#define BSP_VMEDMA_MODE_NOINC_VME (1<<20) +/* Don't increment PCI address */ +#define BSP_VMEDMA_MODE_NOINC_PCI (1<<21) + +/* Direction */ +#define BSP_VMEDMA_MODE_PCI2VME (1<<31) + +typedef void *BSP_VMEDmaListDescriptor; + +/* Program the device for the selected mode; + * + * 'bus_mode': one of the ...VMEDMA_OPT... choices + * listed above. + * 'xfer_mode': VME address-modifier optionally ORed with + * ...VMEDMA_MODE... bits listed above. + * 'custom': (only used if bus_mode is VMEDMA_OPT_CUSTOM) + * pointer to a list of setup parameters (chip-driver + * specific). + * + * RETURNS: 0 on success, nonzero on error (mode or channel + * unsupported). + * + * NOTES: The setup is preserved across multiple DMA transfers. + * It is the responsibility of the driver to reprogram + * the setup if the hardware does not preserve it. + * However - in linked list mode, some fields may be + * read from the list descriptors. + * + * Usually this routine must be used even in linked-list + * mode to program the 'bus_mode'. + * + * Direction of transfer is specified by a bit in the + * 'xfer_mode' (BSP_VMEDMA_MODE_PCI2VME). + */ +int +BSP_VMEDmaSetup(int channel, uint32_t bus_mode, uint32_t xfer_mode, void *custom_setup); + +/* Start direct (not linked-list) transfer. + * + * RETURNS: 0 on success, nonzero on failure + */ +int +BSP_VMEDmaStart(int channel, uint32_t pci_addr, uint32_t vme_addr, uint32_t n_bytes); + +/* Transfer status/result */ +#define BSP_VMEDMA_STATUS_OK 0 +/* Unsupported channel */ +#define BSP_VMEDMA_STATUS_UNSUP (-1) +/* Bus error on VME */ +#define BSP_VMEDMA_STATUS_BERR_VME 1 +/* Bus error on PCI */ +#define BSP_VMEDMA_STATUS_BERR_PCI 2 +/* Channel busy */ +#define BSP_VMEDMA_STATUS_BUSY 3 +/* Setup/programming error */ +#define BSP_VMEDMA_STATUS_PERR 4 +/* Other/unspecified error */ +#define BSP_VMEDMA_STATUS_OERR 5 + +/* Retrieve status of last transfer. + * + * RETURNS: 0 if the transfer was successful, + * nonzero on error (e.g., one of the + * values defined above). + * + * NOTE: Driver is allowed to pass other, + * device specific codes + */ + +uint32_t +BSP_VMEDmaStatus(int channel); + +/* + * Hook a callback (executed from ISR context) to DMA interrupt and + * enable it. + * If called with NULL callback then an existing callback is removed + * and the interrupt disabled. + * + * RETURNS: 0 on success, nonzero on failure (IRQ in use, unsupported + * channel). + */ +typedef void (*BSP_VMEDmaIRQCallback)(void *usr_arg); + +int +BSP_VMEDmaInstallISR(int channel, BSP_VMEDmaIRQCallback cb, void *usr_arg); + +/* + * DMA List operations. + * + * Note that the list is totally unprotected, i.e., the user is + * responsible for maintaining coherency against concurrent + * access by multiple threads or hardware. + * We assume the user builds/updates a list, hands it over to + * the hardware (list start command) and leaves it alone until + * the DMA controller is done with it. + */ + +/* Modify a list entry. If the list element pointer is NULL + * then a new list element is allocated. + * Only the fields with its corresponding bit set in the mask + * argument are touched. + * + * RETURNS: 'd' or newly allocated descriptor or NULL (no memory, + * or invalid setup). + */ +#define BSP_VMEDMA_MSK_ATTR (1<<0) +#define BSP_VMEDMA_MSK_PCIA (1<<1) +#define BSP_VMEDMA_MSK_VMEA (1<<2) +#define BSP_VMEDMA_MSK_BCNT (1<<3) +#define BSP_VMEDMA_MSK_ALL (0xf) +BSP_VMEDmaListDescriptor +BSP_VMEDmaListDescriptorSetup( + BSP_VMEDmaListDescriptor d, + uint32_t attr_mask, + uint32_t xfer_mode, + uint32_t pci_addr, + uint32_t vme_addr, + uint32_t n_bytes); + +/* De-allocate a list descriptor previously obtained by + * BSP_VMEDmaListDescriptorSetup(0,...); + * + * RETURNS: 0 on success, nonzero on failure (d currently on a list) + */ +int +BSP_VMEDmaListDescriptorDestroy(BSP_VMEDmaListDescriptor d); + +/* Traverse a list of descriptors and destroy all elements */ +int +BSP_VMEDmaListDestroy(BSP_VMEDmaListDescriptor anchor); + +/* Enqueue a list descriptor 'd' after 'tail' + * + * If 'tail' is NULL then 'd' is removed from + * the list it is currently on. + * + * RETURNS: 0 on success, nonzero if 'd' is already + * on a list (enqueue) or if it is not currently + * on a list (dequeue). + * + * NOTE: it is obviously the user's responsibility to update + * list queue/tail pointers when changing the + * structure of the list. + */ +int +BSP_VMEDmaListDescriptorEnq( + BSP_VMEDmaListDescriptor tail, + BSP_VMEDmaListDescriptor d); + +/* Obtain next and previous descriptors */ +BSP_VMEDmaListDescriptor +BSP_VMEDmaListDescriptorNext(BSP_VMEDmaListDescriptor d); + +BSP_VMEDmaListDescriptor +BSP_VMEDmaListDescriptorPrev(BSP_VMEDmaListDescriptor d); + +/* Set and get a 'usrData' pointer in the descriptor */ +void +BSP_VMEDmaListDescriptorSetUsr(BSP_VMEDmaListDescriptor d, void *usrData); + +void * +BSP_VMEDmaListDescriptorGetUsr(BSP_VMEDmaListDescriptor d); + +/* Refresh an entire list. Some DMA controllers modify certain + * fields (e.g., byte count) and this command restores the original + * setup. + */ + +int +BSP_VMEDmaListRefresh(BSP_VMEDmaListDescriptor anchor); + +/* Start linked-list operation. + * + * RETURNS: 0 on success, nonzero on failure + */ +int +BSP_VMEDmaListStart(int channel, BSP_VMEDmaListDescriptor list); + +#ifdef DEBUG +void +BSP_VMEDmaListDump(BSP_VMEDmaListDescriptor p); +#endif + +#ifdef __cplusplus +} +#endif + +#endif |