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