summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/dma_i8237A.h
blob: 12efd264f8ddf33bf8a1f653f6a018df116df247 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_DMA_I8237A_H
#define	_SYS_DMA_I8237A_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef	__cplusplus
extern "C" {
#endif

/*	Copyright (c) 1990, 1991 UNIX System Laboratories, Inc.	*/
/*	Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T	*/
/*	All Rights Reserved	*/

#define	D37A_MAX_CHAN   8
#define	D37A_DFR_ALIGN  0xf
#define	D37A_MIN_CHAN   0x0

/*
 * Defines for PC AT DMA controllers.
 */

/*
 * The PC/AT has two Intel 8237A-5 DMA controllers that provide 8 channels
 */
#define	DMA_0WCNT	0x01	/* Channel  word count */
#define	DMA_1WCNT	0x03	/* Channel  word count */
#define	DMA_2WCNT	0x05	/* Channel  word count */
#define	DMA_3WCNT	0x07	/* Channel  word count */
#define	DMA_4WCNT	0xC2	/* (RESERVED) Channel  word count */
#define	DMA_5WCNT	0xC6	/* Channel  word count */
#define	DMA_6WCNT	0xCA	/* Channel  word count */
#define	DMA_7WCNT	0xCE	/* Channel  word count */

#define	DMA_0ADR	0x00	/* Channel  address register */
#define	DMA_1ADR	0x02	/* Channel  address register */
#define	DMA_2ADR	0x04	/* Channel  address register */
#define	DMA_3ADR	0x06	/* Channel  address register */
#define	DMA_4ADR	0xC0	/* (RESERVED) Channel  address register */
#define	DMA_5ADR	0xC4	/* Channel  address register */
#define	DMA_6ADR	0xC8	/* Channel  address register */
#define	DMA_7ADR	0xCC	/* Channel  address register */

/*
 * The Intel DMA controllers are augmented with 8-bit page registers
 * for each channel, allowing access to a 16MB address space.
 */
#define	DMA_0PAGE	0x87	/* Channel 0 address extension reg */
#define	DMA_1PAGE	0x83	/* Channel 1 address extension reg */
#define	DMA_2PAGE	0x81	/* Channel 2 address extension reg */
#define	DMA_3PAGE	0x82	/* Channel 3 address extension reg */
#define	DMA_4PAGE	0	/* dummy address for dma chan. 4 page reg. */
#define	DMA_5PAGE	0x8B	/* Channel 5 address extension reg */
#define	DMA_6PAGE	0x89	/* Channel 6 address extension reg */
#define	DMA_7PAGE	0x8A	/* Channel 7 address extension reg */

/*
 * The EISA has an 8-bit high-page register for each channel
 * for access to a 32-bit address space.
 */
#define	DMA_0HPG	0x487   /* port address for dma channel 0 */
				/* high page reg */
#define	DMA_1HPG	0x483   /* port address for dma channel 1 */
				/* high page reg */
#define	DMA_2HPG	0x481   /* port address for dma channel 2 */
				/* high page reg */
#define	DMA_3HPG	0x482   /* port address for dma channel 3 */
				/* high page reg */
#define	DMA_4HPG	0	/* dummy address for dma channel 4 */
				/* high page reg */
#define	DMA_5HPG	0x48B   /* port address for dma channel 5 */
				/* high page reg */
#define	DMA_6HPG	0x489   /* port address for dma channel 6 */
				/* high page reg */
#define	DMA_7HPG	0x48A   /* port address for dma channel 7 */
				/* high page reg */

/*
 * The EISA has an 8-bit high-count register for each channel
 * for xfer sizes up to 16MB.
 */
#define	DMA_0XCNT	0x401   /* chan. 0 base and current count high */
#define	DMA_1XCNT	0x403   /* chan. 1 base and current count high */
#define	DMA_2XCNT	0x405   /* chan. 2 base and current count high */
#define	DMA_3XCNT	0x407   /* chan. 3 base and current count high */
#define	DMA_4XCNT	0	/* dummy chan. 4 base and current count high */
#define	DMA_5XCNT	0x4C6   /* chan. 5 base and current count high */
#define	DMA_6XCNT	0x4CA   /* chan. 6 base and current count high */
#define	DMA_7XCNT	0x4CE   /* chan. 7 base and current count high */

/*
 * I/O port addresses for controller 1
 */
#define	DMAC1_CMD	0x08	/* Command reg */
#define	DMAC1_REQ	0x09	/* request reg */
#define	DMAC1_STAT	0x08	/* Status reg */
#define	DMAC1_MASK	0x0A	/* Mask set/reset register */
#define	DMAC1_MODE	0x0B	/* Mode reg */
#define	DMAC1_CLFF	0x0C	/* Clear byte pointer first/last flip-flop */
#define	DMA1RTRWMC	0x0D	/* read temp reg/write master clear */
#define	DMA1CMR		0x0E	/* clear mask register */
#define	DMAC1_ALLMASK	0x0F	/* Mask all registers */
#define	DMAC1_SCM	0x40A   /* set chain mode */
#define	DMAC1_EWM	0x40B	/* extended write mode */

/*
 * I/O port addresses for controller 2
 */
#define	DMAC2_CMD	0xD0	/* Command reg */
#define	DMAC2_STAT	0xD0	/* Status reg */
#define	DMAC2_REQ	0xD2	/* request reg */
#define	DMAC2_MASK	0xD4	/* Mask set/reset register */
#define	DMAC2_MODE	0xD6	/* Mode reg */
#define	DMAC2_CLFF	0xD8	/* Clear byte pointer first/last flip-flop */
#define	DMA2RTRWMC	0xDA	/* read temp reg/write master clear */
#define	DMA2CMR		0xDC	/* clear mask register */
#define	DMAC2_ALLMASK	0xDE	/* Mask all registers */
#define	DMAC2_SCM	0x4D4   /* set chain mode */
#define	DMAC2_EWM	0x4D6   /* extended write mode */

/*
 * Write-only Command register definitions.
 */
#define	DMACMD_MEM_TO_MEM	0x01	/* memory-to-memory copy (1=enable) */
#define	DMACMD_CHAN_HOLD	0x02	/* Channel 0 address hold (1=enable) */
#define	DMACMD_CTLR_ENABLE	0x04	/* Controller disable (0=enabled) */
#define	DMACMD_TIMING		0x08	/* normal/compressed timing (0=nrml) */
#define	DMACMD_FIX_PRIO		0x10	/* fixed/rotating priority (0=fixed) */
#define	DMACMD_WRT_SELECT	0x20	/* late/ext write selection (1=ext) */
#define	DMACMD_DREQ_LEVEL	0x40	/* DREQ sense active (0=actv. high) */
#define	DMACMD_DACK_LEVEL	0x80	/* DACK sense active (0=actv. low) */

/*
 * Initialization value for DMA controller.
 */
#define	DMA_CTLR_INIT	~(DMACMD_MEM_TO_MEM | DMACMD_CHAN_HOLD | \
			DMACMD_CTLR_ENABLE | DMACMD_TIMING | \
			DMACMD_FIX_PRIO	| DMACMD_WRT_SELECT | \
			DMACMD_DREQ_LEVEL | DMACMD_DACK_LEVEL)

/*
 * Write-only Mode register.  There is actually a 6-bit Mode register
 * associated with each channel.  These are written one at a time, with
 * the channel number indicated by the low-order 2 bits.
 */

#define	DMAMODE_CHAN	0x03	/* Mask for the "channel select" bits. */
				/* These indicate channel 0-3 */
#define	DMAMODE_VERF	0x00	/* Verify Transfer */
#define	DMAMODE_READ	0x04	/* Read Transfer */
#define	DMAMODE_WRITE   0x08	/* Write Transfer */
				/* Note: Above settings for bits 2-3 are */
				/* "don't care" if bits 6-7 indicate */
				/* cascade mode */
#define	DMAMODE_AUTO	0x10	/* enable Autoinitialization on completion */
#define	DMAMODE_DECR	0x20	/* Address Decrement.  If 0, address incr */
#define	DMAMODE_DEMAND  0x00	/* Select Demand mode */
				/* Each DREQ causes transfers at full speed */
				/* until DREQ goes inactive (after which it */
				/* can be resumed) or either terminal-count */
				/* happens or EOP is asserted */
#define	DMAMODE_SINGLE  0x40	/* Select Single mode */
				/* Each DREQ causes a single byte/word xfer */
#define	DMAMODE_BLOCK   0x80	/* Select Block mode */
				/* Each DREQ causes transfers at full speed */
				/* until terminal count or EOP */
#define	DMAMODE_CASC	0xC0	/* Select Cascade mode.  On the PC-AT, this */
				/* should be set for DMA 2 channel 0 ONLY */


#define	EISA_DMAIS	0x40a   /* interrupt status register */

#define	DMA_MSK		0x0A	/* Mask, enable disk, disable others */
#define	DMA_CLEAR	0x1A	/* Master clear */
#define	IOCR		0x56	/* IO controller */

/*
 * DMA Channels. d_chan field of dmareq.
 */

/* 8 bit channels */
#define	DMAE_CH0	0	/* Channel 0 */
#define	DMAE_CH1	1	/* Channel 1 */
#define	DMAE_CH2	2	/* Channel 2 */
#define	DMAE_CH3	3	/* Channel 3 */
#define	DMAE_CH4	4	/* Channel 4 */
/* 16 bit channels */
#define	DMAE_CH5	5	/* Channel 5 */
#define	DMAE_CH6	6	/* Channel 6 */
#define	DMAE_CH7	7	/* Channel 7 */

/*
 * DMA Masks.
 */
#define	DMA_SETMSK	4	/* Set mask bit */
#define	DMA_CLRMSK	0	/* Clear mask bit */

/* dma_alloc modes */
#define	DMA_BLOCK	0	/* blocking task time allocation */
#define	DMA_NBLOCK	1	/* non-blocking task time allocation */

#define	EISA_DMA_8	0	/* 8-bit data path */
#define	EISA_DMA_16	1<<2	/* 16-bit data path, word count */
#define	EISA_DMA_32	2<<2	/* 32-bit data path */
#define	EISA_DMA_16B	3<<2	/* 16-bit data path, byte count */

#define	EISA_ENCM	4	/* enable chaining mode */
#define	EISA_CMOK	8	/* chaining mode completed (OK) */


/*
 * Channel Address Array - makes life much easier
 */
struct d37A_chan_reg_addr {
	uchar_t	addr_reg;	/* address register */
	uchar_t	cnt_reg;	/* count register */
	uchar_t	page_reg;	/* page register */
	uchar_t	ff_reg;		/* first-last flipflop */
	uchar_t	cmd_reg;	/* command register */
	uchar_t	mode_reg;	/* mode register */
	uchar_t	mask_reg;	/* mask register */
	uchar_t	stat_reg;	/* status register */
	uchar_t	reqt_reg;	/* request register */
	ushort_t hpage_reg;	/* high page register */
	ushort_t hcnt_reg;	/* high count register */
	ushort_t emode_reg;	/* extended mode register */
	ushort_t scm_reg;	/* set chaining mode register */
};

/*
 * macro to initialize array of d37A_chan_reg_addr structures
 */
#define	D37A_BASE_REGS_VALUES \
	{DMA_0ADR, DMA_0WCNT, DMA_0PAGE, DMAC1_CLFF, \
	    DMAC1_CMD, DMAC1_MODE, DMAC1_MASK, DMAC1_STAT, DMAC1_REQ, \
	    DMA_0HPG, DMA_0XCNT, DMAC1_EWM, DMAC1_SCM}, \
	{DMA_1ADR, DMA_1WCNT, DMA_1PAGE, DMAC1_CLFF, \
	    DMAC1_CMD, DMAC1_MODE, DMAC1_MASK, DMAC1_STAT, DMAC1_REQ, \
	    DMA_1HPG, DMA_1XCNT, DMAC1_EWM, DMAC1_SCM}, \
	{DMA_2ADR, DMA_2WCNT, DMA_2PAGE, DMAC1_CLFF, \
	    DMAC1_CMD, DMAC1_MODE, DMAC1_MASK, DMAC1_STAT, DMAC1_REQ, \
	    DMA_2HPG, DMA_2XCNT, DMAC1_EWM, DMAC1_SCM}, \
	{DMA_3ADR, DMA_3WCNT, DMA_3PAGE, DMAC1_CLFF, \
	    DMAC1_CMD, DMAC1_MODE, DMAC1_MASK, DMAC1_STAT, DMAC1_REQ, \
	    DMA_3HPG, DMA_3XCNT, DMAC1_EWM, DMAC1_SCM}, \
	{DMA_4ADR, DMA_4WCNT, DMA_4PAGE, DMAC2_CLFF, \
	    DMAC2_CMD, DMAC2_MODE, DMAC2_MASK, DMAC2_STAT, DMAC2_REQ, \
	    DMA_4HPG, DMA_4XCNT, DMAC2_EWM, DMAC2_SCM}, \
	{DMA_5ADR, DMA_5WCNT, DMA_5PAGE, DMAC2_CLFF, \
	    DMAC2_CMD, DMAC2_MODE, DMAC2_MASK, DMAC2_STAT, DMAC2_REQ, \
	    DMA_5HPG, DMA_5XCNT, DMAC2_EWM, DMAC2_SCM}, \
	{DMA_6ADR, DMA_6WCNT, DMA_6PAGE, DMAC2_CLFF, \
	    DMAC2_CMD, DMAC2_MODE, DMAC2_MASK, DMAC2_STAT, DMAC2_REQ, \
	    DMA_6HPG, DMA_6XCNT, DMAC2_EWM, DMAC2_SCM}, \
	{DMA_7ADR, DMA_7WCNT, DMA_7PAGE, DMAC2_CLFF, \
	    DMAC2_CMD, DMAC2_MODE, DMAC2_MASK, DMAC2_STAT, DMAC2_REQ, \
	    DMA_7HPG, DMA_7XCNT, DMAC2_EWM, DMAC2_SCM}

extern int d37A_init(dev_info_t *);
extern void d37A_dma_disable(int);
extern void d37A_dma_enable(int);
extern void d37A_dma_swstart(int);
extern void d37A_dma_stop(int);
extern void d37A_get_chan_stat(int, ulong_t *, int *);
extern int d37A_dma_valid(int);
extern void d37A_dma_release(int);

/* The following 3 routines are intel specific : man page ddi_dmae_req(9S) */
#if defined(__i386) || defined(__amd64)
extern uchar_t d37A_get_best_mode(struct ddi_dmae_req *);
extern int d37A_prog_chan(struct ddi_dmae_req *, ddi_dma_cookie_t *, int);
extern int d37A_dma_swsetup(struct ddi_dmae_req *, ddi_dma_cookie_t *, int);
#endif

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_DMA_I8237A_H */