1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 
  23 /*
  24  * Copyright 2012 Garrett D'Amore <garrett@damore.org>.  All rights reserved.
  25  */
  26 
  27 /*
  28  * Copyright 1998 Sun Microsystems, Inc.  All rights reserved.
  29  * Use is subject to license terms.
  30  */
  31 
  32 /*      Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
  33 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T       */
  34 /*        All Rights Reserved   */
  35 
  36 /*      Copyright (c) 1988, 1989 Intel Corp.                    */
  37 /*              All Rights Reserved                             */
  38 
  39 #ifndef _SYS_DMAENGINE_H
  40 #define _SYS_DMAENGINE_H
  41 
  42 #include <sys/types.h>
  43 #include <sys/dditypes.h>
  44 
  45 #ifdef  __cplusplus
  46 extern "C" {
  47 #endif
  48 
  49 #define NCHANS  8
  50 
  51 /*
  52  * the DMA Engine Request structure
  53  */
  54 struct ddi_dmae_req {
  55         dev_info_t *der_rdip;   /* original requester's dev_info_t */
  56         uchar_t der_command;    /* Read/Write/Translate/Verify */
  57         uchar_t der_bufprocess; /* NoAuto_init/Chain/Auto_init */
  58         uchar_t der_step;       /* Inc / Dec / Hold */
  59         uchar_t der_trans;      /* Single/Demand/Block/Cascade */
  60         uchar_t der_path;       /* 8/16/32 */
  61         uchar_t der_cycles;     /* 1 or 2 */
  62         uchar_t der_dest;       /* Memory / IO */
  63         uchar_t der_arbus;      /* MicroChannel arbitration reg */
  64         ushort_t der_ioadr;     /* MicroChannel i/o address reg */
  65         ddi_dma_cookie_t *(*proc)(); /* address of application call routine */
  66         void *procparms;        /* parameter buffer for appl call */
  67 };
  68 
  69 #define DMAE_CMD_VRFY    0
  70 #define DMAE_CMD_WRITE   1      /* from memory to device */
  71 #define DMAE_CMD_READ    2      /* from device to memory */
  72 #define DMAE_CMD_TRAN    3
  73 
  74 #define DMAE_BUF_NOAUTO  0      /* default */
  75 #define DMAE_BUF_CHAIN   0x1
  76 #define DMAE_BUF_AUTO    0x2
  77 
  78 #define DMAE_STEP_INC    0      /* default */
  79 #define DMAE_STEP_DEC    1
  80 #define DMAE_STEP_HOLD   2
  81 
  82 #define DMAE_TRANS_SNGL  0      /* default */
  83 #define DMAE_TRANS_BLCK  1
  84 #define DMAE_TRANS_DMND  2
  85 #define DMAE_TRANS_CSCD  3
  86 
  87 
  88 /*
  89  * For the EISA bus
  90  */
  91 #define DMAE_PATH_DEF   0       /* default to ISA xfer width */
  92 #define DMAE_PATH_8     1       /* ISA default for chnl 0..3 */
  93 #define DMAE_PATH_16    2       /* ISA default for chnl 5..7 */
  94 #define DMAE_PATH_32    3
  95 #define DMAE_PATH_64    4
  96 #define DMAE_PATH_16B   5       /* 16-bit path but byte count */
  97 
  98 #define DMAE_CYCLES_1   0       /* Compatible timing */
  99 #define DMAE_CYCLES_2   1       /* Type "A" timing */
 100 #define DMAE_CYCLES_3   2       /* Type "B" timing */
 101 #define DMAE_CYCLES_4   3       /* Burst timing */
 102 
 103 #define DMAE_DEST_IO    0       /* default */
 104 #define DMAE_DEST_MEM   1
 105 
 106 
 107 
 108 /* public function routines */
 109 extern int i_dmae_init(dev_info_t *);
 110 extern ddi_dma_cookie_t *_dmae_nxcookie(int);
 111 extern int i_dmae_acquire(dev_info_t *, int, int (*)(), caddr_t);
 112 extern int i_dmae_free(dev_info_t *, int);
 113 extern int i_dmae_prog(dev_info_t *, struct ddi_dmae_req *,
 114         ddi_dma_cookie_t *, int);
 115 extern int i_dmae_swsetup(dev_info_t *, struct ddi_dmae_req *,
 116         ddi_dma_cookie_t *, int);
 117 extern void i_dmae_swstart(dev_info_t *, int);
 118 extern void i_dmae_stop(dev_info_t *, int);
 119 extern void i_dmae_enable(dev_info_t *, int);
 120 extern void i_dmae_disable(dev_info_t *, int);
 121 extern void i_dmae_get_chan_stat(dev_info_t *dip, int chnl,
 122         ulong_t *addressp, int *countp);
 123 
 124 /*
 125  * the DMA Channel Block structure
 126  */
 127 struct dmae_chnl {
 128         ksema_t dch_lock;               /* semaphore for this channel */
 129         ddi_dma_cookie_t *dch_cookiep;  /* current dma mapping cookie */
 130         ddi_dma_cookie_t *(*proc)();    /* address of application call */
 131                                         /* routine */
 132         void *procparms;                /* parameter buffer for appl call */
 133 };
 134 
 135 
 136 /*
 137  * DMA Engine DDI functions
 138  */
 139 
 140 /*
 141  * Get DMA engine limits
 142  *
 143  * The limits of the DMA engine of the parent bus-nexus are copied into the
 144  * provided structure.  This should be called at driver attach time,
 145  * rather than for each dma setup (breakup).
 146  */
 147 
 148 int ddi_dmae_getlim(dev_info_t *dip, ddi_dma_lim_t *limitsp);
 149 
 150 /*
 151  * Get DMA engine attributes
 152  *
 153  * The attributes of the DMA engine of the parent bus-nexus are copied into
 154  * the provided structure. This should be called at driver attach time,
 155  * rather than for each DMA bind.
 156  */
 157 
 158 int ddi_dmae_getattr(dev_info_t *dip, ddi_dma_attr_t *attrp);
 159 
 160 /*
 161  * DMA channel allocation
 162  *
 163  * The allocation function must be called prior to any other DMA engine
 164  * function on a channel.  The channel should be freed after completion of the
 165  * DMA / device operation if the channel is to be shared.
 166  *
 167  * Specifics of arguments to ddi_dmae_alloc:
 168  *
 169  * dip - dev_info pointer, which identifies the base device that wishes
 170  * to use the DMA channel.
 171  *
 172  * chnl - a DMA channel number.
 173  *
 174  * dmae_waitfp - wait/callback_function pointer, which operates in the same
 175  * manner as in ddi_dma_setup().  The value DDI_DMA_DONTWAIT will cause an
 176  * immediate return if the channel cannot be acquired.  The value
 177  * DDI_DMA_SLEEP will will cause the thread to sleep and not return until
 178  * the channel has been acquired.  Any other value is assumed to be a
 179  * callback function address.
 180  *
 181  * When resources might be available, the callback function is called
 182  * (with the argument specified in arg) from interrupt context.
 183  *
 184  * When the callback function dmae_waitfp() is called, it should attempt to
 185  * allocate the DMA channel again. If it succeeds or does not need the
 186  * channel any more, it must return the value DDI_DMA_CALLBACK_DONE.
 187  * If it does not want to allocate the channel, but instead wishes to be
 188  * called back again later, it must return the value DDI_DMA_CALLBACK_LATER.
 189  * If it tries to allocate the channel, but fails to do so, it must return the
 190  * value DDI_DMA_CALLBACK_RUNOUT.
 191  *
 192  * Failure to observe this protocol will have unpredictable results.
 193  *
 194  * The callback function must provide its own data structure integrity
 195  * when it is invoked.
 196  */
 197 
 198 int ddi_dmae_alloc(dev_info_t *dip, int chnl, int (*dmae_waitfp)(),
 199     caddr_t arg);
 200 
 201 /*
 202  * DMA channel deallocation
 203  *
 204  * The deallocation function should be called after completion of the
 205  * DMA / device operation if the channel is to be shared.
 206  */
 207 
 208 int ddi_dmae_release(dev_info_t *dip, int chnl);
 209 
 210 /*
 211  * DMA channel used in 1st party DMA scheme
 212  *
 213  * The specified channel will be configured to operate in a "slave" mode
 214  * to a first_party DMA engine that also uses the channel.
 215  */
 216 
 217 int ddi_dmae_1stparty(dev_info_t *dip, int chnl);
 218 
 219 /*
 220  * Program DMA channel
 221  *
 222  * The DMA channel is setup for an operation using ddi_dmae_prog().
 223  * This function is implemented to access all capabilities of the DMA engine
 224  * hardware.  This function disables the channel prior to setup, and enables
 225  * the channel before returning.
 226  *
 227  * Specifics of arguments to ddi_dmae_prog:
 228  *
 229  * dmaereqp - pointer to a DMA engine request structure. This structure
 230  * is implementation specific and contains all the info necessary to
 231  * setup the channel, except for the memory address and count.
 232  * This structure is implemented with default values equal to zero,
 233  * so that normally only der_command has to be set with a read or write
 234  * command value.  Once the channel has been setup, subsequent calls to
 235  * ddi_dmae_prog() can have dmaereqp set to NULL if only the address and
 236  * count have to be updated.
 237  *
 238  * cookiep - pointer to a ddi_dma_cookie object which contains address,
 239  * count and intermediate memory mapping information.
 240  */
 241 
 242 int ddi_dmae_prog(dev_info_t *dip, struct ddi_dmae_req *dmaereqp,
 243         ddi_dma_cookie_t *cookiep, int chnl);
 244 
 245 int ddi_dmae_swsetup(dev_info_t *dip, struct ddi_dmae_req *dmaereqp,
 246         ddi_dma_cookie_t *cookiep, int chnl);
 247 
 248 int ddi_dmae_swstart(dev_info_t *dip, int chnl);
 249 
 250 /*
 251  * Stop DMA channel
 252  *
 253  * The DMA channel is disabled and any active operation is terminated.
 254  */
 255 
 256 int ddi_dmae_stop(dev_info_t *dip, int chnl);
 257 
 258 /*
 259  * Enable DMA channel
 260  *
 261  * The DMA channel is enabled for operation.  The channel is also enabled
 262  * after successful setup in ddi_dmae_prog().
 263  */
 264 
 265 int ddi_dmae_enable(dev_info_t *dip, int chnl);
 266 
 267 /*
 268  * Disable DMA channel
 269  *
 270  * The DMA channel is disabled so that transfers cannot continue.
 271  */
 272 
 273 int ddi_dmae_disable(dev_info_t *dip, int chnl);
 274 
 275 /*
 276  * Get remaining xfer count
 277  *
 278  * The count register of the DMA channel is read.  The channel is assumed
 279  * to be stopped.
 280  */
 281 
 282 int ddi_dmae_getcnt(dev_info_t *dip, int chnl, int *count);
 283 
 284 #ifdef  __cplusplus
 285 }
 286 #endif
 287 
 288 #endif  /* !_SYS_DMAENGINE_H */