]>
Commit | Line | Data |
---|---|---|
bede7290 DS |
1 | /* |
2 | module/mite.h | |
3 | Hardware driver for NI Mite PCI interface chip | |
4 | ||
5 | COMEDI - Linux Control and Measurement Device Interface | |
6 | Copyright (C) 1999 David A. Schleef <ds@schleef.org> | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
21 | ||
22 | */ | |
23 | ||
24 | #ifndef _MITE_H_ | |
25 | #define _MITE_H_ | |
26 | ||
6fd15040 | 27 | #include <linux/pci.h> |
bede7290 | 28 | #include "../comedidev.h" |
bede7290 DS |
29 | |
30 | #define PCI_VENDOR_ID_NATINST 0x1093 | |
31 | ||
b6c77757 | 32 | /* #define DEBUG_MITE */ |
bede7290 DS |
33 | #define PCIMIO_COMPAT |
34 | ||
35 | #ifdef DEBUG_MITE | |
6a98d36e | 36 | #define MDPRINTK(format, args...) printk(format , ## args) |
bede7290 | 37 | #else |
8086fff8 | 38 | #define MDPRINTK(format, args...) |
bede7290 DS |
39 | #endif |
40 | ||
41 | #define MAX_MITE_DMA_CHANNELS 8 | |
42 | ||
43 | struct mite_dma_descriptor { | |
44 | u32 count; | |
45 | u32 addr; | |
46 | u32 next; | |
47 | u32 dar; | |
48 | }; | |
49 | ||
50 | struct mite_dma_descriptor_ring { | |
51 | struct device *hw_dev; | |
52 | unsigned int n_links; | |
53 | struct mite_dma_descriptor *descriptors; | |
54 | dma_addr_t descriptors_dma_addr; | |
55 | }; | |
56 | ||
57 | struct mite_channel { | |
58 | struct mite_struct *mite; | |
59 | unsigned channel; | |
60 | int dir; | |
61 | int done; | |
62 | struct mite_dma_descriptor_ring *ring; | |
63 | }; | |
64 | ||
65 | struct mite_struct { | |
66 | struct mite_struct *next; | |
67 | int used; | |
68 | ||
69 | struct pci_dev *pcidev; | |
70 | resource_size_t mite_phys_addr; | |
71 | void *mite_io_addr; | |
72 | resource_size_t daq_phys_addr; | |
73 | void *daq_io_addr; | |
74 | ||
75 | struct mite_channel channels[MAX_MITE_DMA_CHANNELS]; | |
76 | short channel_allocated[MAX_MITE_DMA_CHANNELS]; | |
77 | int num_channels; | |
78 | unsigned fifo_size; | |
79 | spinlock_t lock; | |
80 | }; | |
81 | ||
82 | static inline struct mite_dma_descriptor_ring *mite_alloc_ring(struct | |
0a85b6f0 MT |
83 | mite_struct |
84 | *mite) | |
bede7290 DS |
85 | { |
86 | struct mite_dma_descriptor_ring *ring = | |
0a85b6f0 | 87 | kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL); |
bede7290 DS |
88 | if (ring == NULL) |
89 | return ring; | |
90 | ring->hw_dev = get_device(&mite->pcidev->dev); | |
91 | if (ring->hw_dev == NULL) { | |
92 | kfree(ring); | |
93 | return NULL; | |
94 | } | |
95 | ring->n_links = 0; | |
96 | ring->descriptors = NULL; | |
97 | ring->descriptors_dma_addr = 0; | |
98 | return ring; | |
99 | }; | |
100 | ||
101 | static inline void mite_free_ring(struct mite_dma_descriptor_ring *ring) | |
102 | { | |
103 | if (ring) { | |
104 | if (ring->descriptors) { | |
105 | dma_free_coherent(ring->hw_dev, | |
0a85b6f0 MT |
106 | ring->n_links * |
107 | sizeof(struct mite_dma_descriptor), | |
108 | ring->descriptors, | |
109 | ring->descriptors_dma_addr); | |
bede7290 DS |
110 | } |
111 | put_device(ring->hw_dev); | |
112 | kfree(ring); | |
113 | } | |
114 | }; | |
115 | ||
116 | extern struct mite_struct *mite_devices; | |
117 | ||
118 | static inline unsigned int mite_irq(struct mite_struct *mite) | |
119 | { | |
120 | return mite->pcidev->irq; | |
121 | }; | |
0a85b6f0 | 122 | |
bede7290 DS |
123 | static inline unsigned int mite_device_id(struct mite_struct *mite) |
124 | { | |
125 | return mite->pcidev->device; | |
126 | }; | |
127 | ||
128 | void mite_init(void); | |
129 | void mite_cleanup(void); | |
130 | int mite_setup(struct mite_struct *mite); | |
131 | int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1); | |
132 | void mite_unsetup(struct mite_struct *mite); | |
133 | void mite_list_devices(void); | |
134 | struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite, | |
0a85b6f0 MT |
135 | struct |
136 | mite_dma_descriptor_ring | |
137 | *ring, unsigned min_channel, | |
138 | unsigned max_channel); | |
bede7290 | 139 | static inline struct mite_channel *mite_request_channel(struct mite_struct |
0a85b6f0 MT |
140 | *mite, |
141 | struct | |
142 | mite_dma_descriptor_ring | |
143 | *ring) | |
bede7290 DS |
144 | { |
145 | return mite_request_channel_in_range(mite, ring, 0, | |
0a85b6f0 | 146 | mite->num_channels - 1); |
bede7290 | 147 | } |
0a85b6f0 | 148 | |
bede7290 DS |
149 | void mite_release_channel(struct mite_channel *mite_chan); |
150 | ||
151 | unsigned mite_dma_tcr(struct mite_channel *mite_chan); | |
152 | void mite_dma_arm(struct mite_channel *mite_chan); | |
153 | void mite_dma_disarm(struct mite_channel *mite_chan); | |
0a85b6f0 MT |
154 | int mite_sync_input_dma(struct mite_channel *mite_chan, |
155 | struct comedi_async *async); | |
156 | int mite_sync_output_dma(struct mite_channel *mite_chan, | |
157 | struct comedi_async *async); | |
bede7290 DS |
158 | u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan); |
159 | u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan); | |
160 | u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan); | |
161 | u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan); | |
162 | u32 mite_bytes_in_transit(struct mite_channel *mite_chan); | |
163 | unsigned mite_get_status(struct mite_channel *mite_chan); | |
164 | int mite_done(struct mite_channel *mite_chan); | |
165 | ||
bede7290 | 166 | void mite_prep_dma(struct mite_channel *mite_chan, |
0a85b6f0 | 167 | unsigned int num_device_bits, unsigned int num_memory_bits); |
bede7290 | 168 | int mite_buf_change(struct mite_dma_descriptor_ring *ring, |
0a85b6f0 | 169 | struct comedi_async *async); |
bede7290 DS |
170 | |
171 | #ifdef DEBUG_MITE | |
172 | void mite_print_chsr(unsigned int chsr); | |
173 | void mite_dump_regs(struct mite_channel *mite_chan); | |
174 | #endif | |
175 | ||
176 | static inline int CHAN_OFFSET(int channel) | |
177 | { | |
178 | return 0x500 + 0x100 * channel; | |
179 | }; | |
180 | ||
181 | enum mite_registers { | |
182 | /* The bits 0x90180700 in MITE_UNKNOWN_DMA_BURST_REG can be | |
183 | written and read back. The bits 0x1f always read as 1. | |
184 | The rest always read as zero. */ | |
185 | MITE_UNKNOWN_DMA_BURST_REG = 0x28, | |
b6c77757 BP |
186 | MITE_IODWBSR = 0xc0, /* IO Device Window Base Size Register */ |
187 | MITE_IODWBSR_1 = 0xc4, /* IO Device Window Base Size Register 1 */ | |
bede7290 DS |
188 | MITE_IODWCR_1 = 0xf4, |
189 | MITE_PCI_CONFIG_OFFSET = 0x300, | |
b6c77757 | 190 | MITE_CSIGR = 0x460 /* chip signature */ |
bede7290 | 191 | }; |
0a85b6f0 MT |
192 | static inline int MITE_CHOR(int channel) |
193 | { /* channel operation */ | |
bede7290 DS |
194 | return CHAN_OFFSET(channel) + 0x0; |
195 | }; | |
0a85b6f0 MT |
196 | |
197 | static inline int MITE_CHCR(int channel) | |
198 | { /* channel control */ | |
bede7290 DS |
199 | return CHAN_OFFSET(channel) + 0x4; |
200 | }; | |
0a85b6f0 MT |
201 | |
202 | static inline int MITE_TCR(int channel) | |
203 | { /* transfer count */ | |
bede7290 DS |
204 | return CHAN_OFFSET(channel) + 0x8; |
205 | }; | |
0a85b6f0 MT |
206 | |
207 | static inline int MITE_MCR(int channel) | |
208 | { /* memory configuration */ | |
bede7290 DS |
209 | return CHAN_OFFSET(channel) + 0xc; |
210 | }; | |
0a85b6f0 MT |
211 | |
212 | static inline int MITE_MAR(int channel) | |
213 | { /* memory address */ | |
bede7290 DS |
214 | return CHAN_OFFSET(channel) + 0x10; |
215 | }; | |
0a85b6f0 MT |
216 | |
217 | static inline int MITE_DCR(int channel) | |
218 | { /* device configuration */ | |
bede7290 DS |
219 | return CHAN_OFFSET(channel) + 0x14; |
220 | }; | |
0a85b6f0 MT |
221 | |
222 | static inline int MITE_DAR(int channel) | |
223 | { /* device address */ | |
bede7290 DS |
224 | return CHAN_OFFSET(channel) + 0x18; |
225 | }; | |
0a85b6f0 MT |
226 | |
227 | static inline int MITE_LKCR(int channel) | |
228 | { /* link configuration */ | |
bede7290 DS |
229 | return CHAN_OFFSET(channel) + 0x1c; |
230 | }; | |
0a85b6f0 MT |
231 | |
232 | static inline int MITE_LKAR(int channel) | |
233 | { /* link address */ | |
bede7290 DS |
234 | return CHAN_OFFSET(channel) + 0x20; |
235 | }; | |
0a85b6f0 MT |
236 | |
237 | static inline int MITE_LLKAR(int channel) | |
238 | { /* see mite section of tnt5002 manual */ | |
bede7290 DS |
239 | return CHAN_OFFSET(channel) + 0x24; |
240 | }; | |
0a85b6f0 MT |
241 | |
242 | static inline int MITE_BAR(int channel) | |
243 | { /* base address */ | |
bede7290 DS |
244 | return CHAN_OFFSET(channel) + 0x28; |
245 | }; | |
0a85b6f0 MT |
246 | |
247 | static inline int MITE_BCR(int channel) | |
248 | { /* base count */ | |
bede7290 DS |
249 | return CHAN_OFFSET(channel) + 0x2c; |
250 | }; | |
0a85b6f0 MT |
251 | |
252 | static inline int MITE_SAR(int channel) | |
253 | { /* ? address */ | |
bede7290 DS |
254 | return CHAN_OFFSET(channel) + 0x30; |
255 | }; | |
0a85b6f0 MT |
256 | |
257 | static inline int MITE_WSCR(int channel) | |
258 | { /* ? */ | |
bede7290 DS |
259 | return CHAN_OFFSET(channel) + 0x34; |
260 | }; | |
0a85b6f0 MT |
261 | |
262 | static inline int MITE_WSER(int channel) | |
263 | { /* ? */ | |
bede7290 DS |
264 | return CHAN_OFFSET(channel) + 0x38; |
265 | }; | |
0a85b6f0 MT |
266 | |
267 | static inline int MITE_CHSR(int channel) | |
268 | { /* channel status */ | |
bede7290 DS |
269 | return CHAN_OFFSET(channel) + 0x3c; |
270 | }; | |
0a85b6f0 MT |
271 | |
272 | static inline int MITE_FCR(int channel) | |
273 | { /* fifo count */ | |
bede7290 DS |
274 | return CHAN_OFFSET(channel) + 0x40; |
275 | }; | |
276 | ||
277 | enum MITE_IODWBSR_bits { | |
b6c77757 | 278 | WENAB = 0x80, /* window enable */ |
bede7290 DS |
279 | }; |
280 | ||
281 | static inline unsigned MITE_IODWBSR_1_WSIZE_bits(unsigned size) | |
282 | { | |
283 | unsigned order = 0; | |
284 | while (size >>= 1) | |
285 | ++order; | |
286 | BUG_ON(order < 1); | |
287 | return (order - 1) & 0x1f; | |
288 | } | |
289 | ||
290 | enum MITE_UNKNOWN_DMA_BURST_bits { | |
291 | UNKNOWN_DMA_BURST_ENABLE_BITS = 0x600 | |
292 | }; | |
293 | ||
294 | static inline int mite_csigr_version(u32 csigr_bits) | |
295 | { | |
296 | return csigr_bits & 0xf; | |
297 | }; | |
0a85b6f0 | 298 | |
bede7290 | 299 | static inline int mite_csigr_type(u32 csigr_bits) |
b6c77757 | 300 | { /* original mite = 0, minimite = 1 */ |
bede7290 DS |
301 | return (csigr_bits >> 4) & 0xf; |
302 | }; | |
0a85b6f0 | 303 | |
bede7290 | 304 | static inline int mite_csigr_mmode(u32 csigr_bits) |
b6c77757 | 305 | { /* mite mode, minimite = 1 */ |
bede7290 DS |
306 | return (csigr_bits >> 8) & 0x3; |
307 | }; | |
0a85b6f0 | 308 | |
bede7290 | 309 | static inline int mite_csigr_imode(u32 csigr_bits) |
b6c77757 | 310 | { /* cpu port interface mode, pci = 0x3 */ |
bede7290 DS |
311 | return (csigr_bits >> 12) & 0x3; |
312 | }; | |
0a85b6f0 | 313 | |
bede7290 | 314 | static inline int mite_csigr_dmac(u32 csigr_bits) |
b6c77757 | 315 | { /* number of dma channels */ |
bede7290 DS |
316 | return (csigr_bits >> 16) & 0xf; |
317 | }; | |
0a85b6f0 | 318 | |
bede7290 | 319 | static inline int mite_csigr_wpdep(u32 csigr_bits) |
b6c77757 | 320 | { /* write post fifo depth */ |
bede7290 DS |
321 | unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7; |
322 | if (wpdep_bits == 0) | |
323 | return 0; | |
324 | else | |
325 | return 1 << (wpdep_bits - 1); | |
326 | }; | |
0a85b6f0 | 327 | |
bede7290 DS |
328 | static inline int mite_csigr_wins(u32 csigr_bits) |
329 | { | |
330 | return (csigr_bits >> 24) & 0x1f; | |
331 | }; | |
0a85b6f0 | 332 | |
bede7290 | 333 | static inline int mite_csigr_iowins(u32 csigr_bits) |
b6c77757 | 334 | { /* number of io windows */ |
bede7290 DS |
335 | return (csigr_bits >> 29) & 0x7; |
336 | }; | |
337 | ||
338 | enum MITE_MCR_bits { | |
339 | MCRPON = 0, | |
340 | }; | |
341 | ||
342 | enum MITE_DCR_bits { | |
343 | DCR_NORMAL = (1 << 29), | |
344 | DCRPON = 0, | |
345 | }; | |
346 | ||
347 | enum MITE_CHOR_bits { | |
348 | CHOR_DMARESET = (1 << 31), | |
349 | CHOR_SET_SEND_TC = (1 << 11), | |
350 | CHOR_CLR_SEND_TC = (1 << 10), | |
351 | CHOR_SET_LPAUSE = (1 << 9), | |
352 | CHOR_CLR_LPAUSE = (1 << 8), | |
353 | CHOR_CLRDONE = (1 << 7), | |
354 | CHOR_CLRRB = (1 << 6), | |
355 | CHOR_CLRLC = (1 << 5), | |
356 | CHOR_FRESET = (1 << 4), | |
357 | CHOR_ABORT = (1 << 3), /* stop without emptying fifo */ | |
358 | CHOR_STOP = (1 << 2), /* stop after emptying fifo */ | |
359 | CHOR_CONT = (1 << 1), | |
360 | CHOR_START = (1 << 0), | |
361 | CHOR_PON = (CHOR_CLR_SEND_TC | CHOR_CLR_LPAUSE), | |
362 | }; | |
363 | ||
364 | enum MITE_CHCR_bits { | |
365 | CHCR_SET_DMA_IE = (1 << 31), | |
366 | CHCR_CLR_DMA_IE = (1 << 30), | |
367 | CHCR_SET_LINKP_IE = (1 << 29), | |
368 | CHCR_CLR_LINKP_IE = (1 << 28), | |
369 | CHCR_SET_SAR_IE = (1 << 27), | |
370 | CHCR_CLR_SAR_IE = (1 << 26), | |
371 | CHCR_SET_DONE_IE = (1 << 25), | |
372 | CHCR_CLR_DONE_IE = (1 << 24), | |
373 | CHCR_SET_MRDY_IE = (1 << 23), | |
374 | CHCR_CLR_MRDY_IE = (1 << 22), | |
375 | CHCR_SET_DRDY_IE = (1 << 21), | |
376 | CHCR_CLR_DRDY_IE = (1 << 20), | |
377 | CHCR_SET_LC_IE = (1 << 19), | |
378 | CHCR_CLR_LC_IE = (1 << 18), | |
379 | CHCR_SET_CONT_RB_IE = (1 << 17), | |
380 | CHCR_CLR_CONT_RB_IE = (1 << 16), | |
381 | CHCR_FIFODIS = (1 << 15), | |
382 | CHCR_FIFO_ON = 0, | |
383 | CHCR_BURSTEN = (1 << 14), | |
384 | CHCR_NO_BURSTEN = 0, | |
385 | CHCR_BYTE_SWAP_DEVICE = (1 << 6), | |
386 | CHCR_BYTE_SWAP_MEMORY = (1 << 4), | |
387 | CHCR_DIR = (1 << 3), | |
388 | CHCR_DEV_TO_MEM = CHCR_DIR, | |
389 | CHCR_MEM_TO_DEV = 0, | |
390 | CHCR_NORMAL = (0 << 0), | |
391 | CHCR_CONTINUE = (1 << 0), | |
392 | CHCR_RINGBUFF = (2 << 0), | |
393 | CHCR_LINKSHORT = (4 << 0), | |
394 | CHCR_LINKLONG = (5 << 0), | |
395 | CHCRPON = | |
0a85b6f0 MT |
396 | (CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE | |
397 | CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE | | |
398 | CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE), | |
bede7290 DS |
399 | }; |
400 | ||
401 | enum ConfigRegister_bits { | |
402 | CR_REQS_MASK = 0x7 << 16, | |
403 | CR_ASEQDONT = 0x0 << 10, | |
404 | CR_ASEQUP = 0x1 << 10, | |
405 | CR_ASEQDOWN = 0x2 << 10, | |
406 | CR_ASEQ_MASK = 0x3 << 10, | |
407 | CR_PSIZE8 = (1 << 8), | |
408 | CR_PSIZE16 = (2 << 8), | |
409 | CR_PSIZE32 = (3 << 8), | |
410 | CR_PORTCPU = (0 << 6), | |
411 | CR_PORTIO = (1 << 6), | |
412 | CR_PORTVXI = (2 << 6), | |
413 | CR_PORTMXI = (3 << 6), | |
414 | CR_AMDEVICE = (1 << 0), | |
415 | }; | |
416 | static inline int CR_REQS(int source) | |
417 | { | |
418 | return (source & 0x7) << 16; | |
419 | }; | |
0a85b6f0 | 420 | |
bede7290 DS |
421 | static inline int CR_REQSDRQ(unsigned drq_line) |
422 | { | |
423 | /* This also works on m-series when | |
424 | using channels (drq_line) 4 or 5. */ | |
425 | return CR_REQS((drq_line & 0x3) | 0x4); | |
426 | } | |
0a85b6f0 | 427 | |
bede7290 DS |
428 | static inline int CR_RL(unsigned int retry_limit) |
429 | { | |
430 | int value = 0; | |
431 | ||
432 | while (retry_limit) { | |
433 | retry_limit >>= 1; | |
434 | value++; | |
435 | } | |
436 | if (value > 0x7) | |
5f74ea14 | 437 | printk("comedi: bug! retry_limit too large\n"); |
bede7290 DS |
438 | return (value & 0x7) << 21; |
439 | } | |
440 | ||
441 | enum CHSR_bits { | |
442 | CHSR_INT = (1 << 31), | |
443 | CHSR_LPAUSES = (1 << 29), | |
444 | CHSR_SARS = (1 << 27), | |
445 | CHSR_DONE = (1 << 25), | |
446 | CHSR_MRDY = (1 << 23), | |
447 | CHSR_DRDY = (1 << 21), | |
448 | CHSR_LINKC = (1 << 19), | |
449 | CHSR_CONTS_RB = (1 << 17), | |
450 | CHSR_ERROR = (1 << 15), | |
451 | CHSR_SABORT = (1 << 14), | |
452 | CHSR_HABORT = (1 << 13), | |
453 | CHSR_STOPS = (1 << 12), | |
454 | CHSR_OPERR_mask = (3 << 10), | |
455 | CHSR_OPERR_NOERROR = (0 << 10), | |
456 | CHSR_OPERR_FIFOERROR = (1 << 10), | |
457 | CHSR_OPERR_LINKERROR = (1 << 10), /* ??? */ | |
458 | CHSR_XFERR = (1 << 9), | |
459 | CHSR_END = (1 << 8), | |
460 | CHSR_DRQ1 = (1 << 7), | |
461 | CHSR_DRQ0 = (1 << 6), | |
462 | CHSR_LxERR_mask = (3 << 4), | |
463 | CHSR_LBERR = (1 << 4), | |
464 | CHSR_LRERR = (2 << 4), | |
465 | CHSR_LOERR = (3 << 4), | |
466 | CHSR_MxERR_mask = (3 << 2), | |
467 | CHSR_MBERR = (1 << 2), | |
468 | CHSR_MRERR = (2 << 2), | |
469 | CHSR_MOERR = (3 << 2), | |
470 | CHSR_DxERR_mask = (3 << 0), | |
471 | CHSR_DBERR = (1 << 0), | |
472 | CHSR_DRERR = (2 << 0), | |
473 | CHSR_DOERR = (3 << 0), | |
474 | }; | |
475 | ||
476 | static inline void mite_dma_reset(struct mite_channel *mite_chan) | |
477 | { | |
478 | writel(CHOR_DMARESET | CHOR_FRESET, | |
0a85b6f0 | 479 | mite_chan->mite->mite_io_addr + MITE_CHOR(mite_chan->channel)); |
bede7290 DS |
480 | }; |
481 | ||
482 | #endif |