forked from Imagelibrary/rtems
310 lines
9.0 KiB
C
310 lines
9.0 KiB
C
/**
|
|
* @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
|