Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:53

0001 /**
0002  *  @file
0003  *
0004  *  @ingroup shared_vmedma
0005  *
0006  *  @brief Public interface of DMA routines
0007  */
0008 
0009 #ifndef BSP_VME_DMA_H
0010 #define BSP_VME_DMA_H
0011 
0012 /*
0013  * Authorship
0014  * ----------
0015  * This software was created by
0016  *     Till Straumann <strauman@slac.stanford.edu>, 2006, 2007
0017  *     Stanford Linear Accelerator Center, Stanford University.
0018  *
0019  * Acknowledgement of sponsorship
0020  * ------------------------------
0021  * This software was produced by
0022  *     the Stanford Linear Accelerator Center, Stanford University,
0023  *     under Contract DE-AC03-76SFO0515 with the Department of Energy.
0024  *
0025  * Government disclaimer of liability
0026  * ----------------------------------
0027  * Neither the United States nor the United States Department of Energy,
0028  * nor any of their employees, makes any warranty, express or implied, or
0029  * assumes any legal liability or responsibility for the accuracy,
0030  * completeness, or usefulness of any data, apparatus, product, or process
0031  * disclosed, or represents that its use would not infringe privately owned
0032  * rights.
0033  *
0034  * Stanford disclaimer of liability
0035  * --------------------------------
0036  * Stanford University makes no representations or warranties, express or
0037  * implied, nor assumes any liability for the use of this software.
0038  *
0039  * Stanford disclaimer of copyright
0040  * --------------------------------
0041  * Stanford University, owner of the copyright, hereby disclaims its
0042  * copyright and all other rights in this software.  Hence, anyone may
0043  * freely use it for any purpose without restriction.
0044  *
0045  * Maintenance of notices
0046  * ----------------------
0047  * In the interest of clarity regarding the origin and status of this
0048  * SLAC software, this and all the preceding Stanford University notices
0049  * are to remain affixed to any copy or derivative of this software made
0050  * or distributed by the recipient and are to be affixed to any copy of
0051  * software made or distributed by the recipient that contains a copy or
0052  * derivative of this software.
0053  *
0054  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
0055  */
0056 
0057 #include <stdint.h>
0058 
0059 #ifdef __cplusplus
0060 extern "C" {
0061 #endif
0062 
0063 /**
0064  *  @defgroup shared_vmedma VMEDMA Support
0065  *
0066  *  @ingroup shared_vmeuniverse
0067  *
0068  *  @brief VMEDMA Support Package
0069  */
0070 
0071 
0072 /* NOTE: Access to DMA Channels is *not* protected / thread-safe.
0073  *       It is the responsability of the user to provide appropriate
0074  *       locking/serialization.
0075  */
0076 
0077 /* Simple abstraction of DMA controller setup / bus utilization:  */
0078 
0079 /* Since VME is the bottleneck, the settings for PCI are always
0080  * chosen aggressively.
0081  */
0082 
0083 
0084 /* Optimize for throughput; accept longer latencies:
0085  * Choose a large block size (1k) and immediately re-request
0086  * the bus at block boundaries.
0087  */
0088 #define BSP_VMEDMA_OPT_THROUGHPUT   1
0089 /* Optimize for latency, accept throughput penalty:
0090  * Choose a small block size (32b) and immediately re-request
0091  * the bus at block boundaries.
0092  */
0093 #define BSP_VMEDMA_OPT_LOWLATENCY   2
0094 
0095 /* Optimize for bus sharing with other devices:
0096  * Choose relatively small block size (128) and back off for 64us
0097  * at each block boundary.
0098  */
0099 #define BSP_VMEDMA_OPT_SHAREDBUS    3
0100 
0101 /* Choose bridge default/reset configuration:
0102  * (see manual)
0103  */
0104 #define BSP_VMEDMA_OPT_DEFAULT      4
0105 
0106 /* Provide custom configuration pass pointer to array
0107  * with as many 32-bit words the particular bridge chip
0108  * expects.
0109  */
0110 #define BSP_VMEDMA_OPT_CUSTOM       5
0111 
0112 /* VME Transfer modes */
0113 
0114 /* Bitwise OR of the VME address-modifier/transfer-type
0115  * with driver specific (no standard AM code for 2eVME and
0116  * 2eSST defined) and optional special flags (see below)
0117  */
0118 
0119 /* Additional qualifiers: */
0120 
0121 /* Don't increment VME address */
0122 #define BSP_VMEDMA_MODE_NOINC_VME   (1<<20)
0123 /* Don't increment PCI address */
0124 #define BSP_VMEDMA_MODE_NOINC_PCI   (1<<21)
0125 
0126 /* Direction */
0127 #define BSP_VMEDMA_MODE_PCI2VME     (1<<31)
0128 
0129 typedef void *BSP_VMEDmaListDescriptor;
0130 
0131 /* Program the device for the selected mode;
0132  *
0133  *  'bus_mode': one of the ...VMEDMA_OPT... choices
0134  *              listed above.
0135  * 'xfer_mode': VME address-modifier optionally ORed with
0136  *              ...VMEDMA_MODE... bits listed above.
0137  *    'custom': (only used if bus_mode is VMEDMA_OPT_CUSTOM)
0138  *              pointer to a list of setup parameters (chip-driver
0139  *              specific).
0140  *
0141  * RETURNS: 0 on success, nonzero on error (mode or channel
0142  *          unsupported).
0143  *
0144  * NOTES:   The setup is preserved across multiple DMA transfers.
0145  *          It is the responsibility of the driver to reprogram
0146  *          the setup if the hardware does not preserve it.
0147  *          However - in linked list mode, some fields may be
0148  *          read from the list descriptors.
0149  *
0150  *          Usually this routine must be used even in linked-list
0151  *          mode to program the 'bus_mode'.
0152  *
0153  *          Direction of transfer is specified by a bit in the
0154  *          'xfer_mode' (BSP_VMEDMA_MODE_PCI2VME).
0155  */
0156 int
0157 BSP_VMEDmaSetup(int channel, uint32_t bus_mode, uint32_t xfer_mode, void *custom_setup);
0158 
0159 /* Start direct (not linked-list) transfer.
0160  *
0161  * RETURNS: 0 on success, nonzero on failure
0162  */
0163 int
0164 BSP_VMEDmaStart(int channel, uint32_t pci_addr, uint32_t vme_addr, uint32_t n_bytes);
0165 
0166 /* Transfer status/result */
0167 #define BSP_VMEDMA_STATUS_OK        0
0168 /* Unsupported channel */
0169 #define BSP_VMEDMA_STATUS_UNSUP     (-1)
0170 /* Bus error on VME */
0171 #define BSP_VMEDMA_STATUS_BERR_VME  1
0172 /* Bus error on PCI */
0173 #define BSP_VMEDMA_STATUS_BERR_PCI  2
0174 /* Channel busy        */
0175 #define BSP_VMEDMA_STATUS_BUSY      3
0176 /* Setup/programming error */
0177 #define BSP_VMEDMA_STATUS_PERR      4
0178 /* Other/unspecified error */
0179 #define BSP_VMEDMA_STATUS_OERR      5
0180 
0181 /* Retrieve status of last transfer.
0182  *
0183  * RETURNS: 0 if the transfer was successful,
0184  *          nonzero on error (e.g., one of the
0185  *          values defined above).
0186  *
0187  *    NOTE: Driver is allowed to pass other,
0188  *          device specific codes
0189  */
0190 
0191 uint32_t
0192 BSP_VMEDmaStatus(int channel);
0193 
0194 /*
0195  * Hook a callback (executed from ISR context) to DMA interrupt and
0196  * enable it.
0197  * If called with NULL callback then an existing callback is removed
0198  * and the interrupt disabled.
0199  *
0200  * RETURNS: 0 on success, nonzero on failure (IRQ in use, unsupported
0201  *          channel).
0202  */
0203 typedef void (*BSP_VMEDmaIRQCallback)(void *usr_arg);
0204 
0205 int
0206 BSP_VMEDmaInstallISR(int channel, BSP_VMEDmaIRQCallback cb, void *usr_arg);
0207 
0208 /*
0209  * DMA List operations.
0210  *
0211  * Note that the list is totally unprotected, i.e., the user is
0212  * responsible for maintaining coherency against concurrent
0213  * access by multiple threads or hardware.
0214  * We assume the user builds/updates a list, hands it over to
0215  * the hardware (list start command) and leaves it alone until
0216  * the DMA controller is done with it.
0217  */
0218 
0219 /* Modify a list entry. If the list element pointer is NULL
0220  * then a new list element is allocated.
0221  * Only the fields with its corresponding bit set in the mask
0222  * argument are touched.
0223  *
0224  * RETURNS: 'd' or newly allocated descriptor or NULL (no memory,
0225  *          or invalid setup).
0226  */
0227 #define BSP_VMEDMA_MSK_ATTR     (1<<0)
0228 #define BSP_VMEDMA_MSK_PCIA     (1<<1)
0229 #define BSP_VMEDMA_MSK_VMEA     (1<<2)
0230 #define BSP_VMEDMA_MSK_BCNT     (1<<3)
0231 #define BSP_VMEDMA_MSK_ALL      (0xf)
0232 BSP_VMEDmaListDescriptor
0233 BSP_VMEDmaListDescriptorSetup(
0234         BSP_VMEDmaListDescriptor d,
0235         uint32_t                 attr_mask,
0236         uint32_t                 xfer_mode,
0237         uint32_t                 pci_addr,
0238         uint32_t                 vme_addr,
0239         uint32_t                 n_bytes);
0240 
0241 /* De-allocate a list descriptor previously obtained by
0242  * BSP_VMEDmaListDescriptorSetup(0,...);
0243  *
0244  * RETURNS: 0 on success, nonzero on failure (d currently on a list)
0245  */
0246 int
0247 BSP_VMEDmaListDescriptorDestroy(BSP_VMEDmaListDescriptor d);
0248 
0249 /* Traverse a list of descriptors and destroy all elements */
0250 int
0251 BSP_VMEDmaListDestroy(BSP_VMEDmaListDescriptor anchor);
0252 
0253 /* Enqueue a list descriptor 'd' after 'tail'
0254  *
0255  * If 'tail' is NULL then 'd' is removed from
0256  * the list it is currently on.
0257  *
0258  * RETURNS: 0 on success, nonzero if 'd' is already
0259  *          on a list (enqueue) or if it is not currently
0260  *          on a list (dequeue).
0261  *
0262  * NOTE: it is obviously the user's responsibility to update
0263  *       list queue/tail pointers when changing the
0264  *       structure of the list.
0265  */
0266 int
0267 BSP_VMEDmaListDescriptorEnq(
0268         BSP_VMEDmaListDescriptor tail,
0269         BSP_VMEDmaListDescriptor d);
0270 
0271 /* Obtain next and previous descriptors */
0272 BSP_VMEDmaListDescriptor
0273 BSP_VMEDmaListDescriptorNext(BSP_VMEDmaListDescriptor d);
0274 
0275 BSP_VMEDmaListDescriptor
0276 BSP_VMEDmaListDescriptorPrev(BSP_VMEDmaListDescriptor d);
0277 
0278 /* Set and get a 'usrData' pointer in the descriptor */
0279 void
0280 BSP_VMEDmaListDescriptorSetUsr(BSP_VMEDmaListDescriptor d, void *usrData);
0281 
0282 void *
0283 BSP_VMEDmaListDescriptorGetUsr(BSP_VMEDmaListDescriptor d);
0284 
0285 /* Refresh an entire list. Some DMA controllers modify certain
0286  * fields (e.g., byte count) and this command restores the original
0287  * setup.
0288  */
0289 
0290 int
0291 BSP_VMEDmaListRefresh(BSP_VMEDmaListDescriptor anchor);
0292 
0293 /* Start linked-list operation.
0294  *
0295  * RETURNS: 0 on success, nonzero on failure
0296  */
0297 int
0298 BSP_VMEDmaListStart(int channel, BSP_VMEDmaListDescriptor list);
0299 
0300 #ifdef DEBUG
0301 void
0302 BSP_VMEDmaListDump(BSP_VMEDmaListDescriptor p);
0303 #endif
0304 
0305 #ifdef __cplusplus
0306 }
0307 #endif
0308 
0309 #endif