amcc_s5933_58.h revision c995fe9475e062bab6f5a45ed28cd2d3d955ef43
1/*
2	Modified by umesh on 16th may 2001
3	Modified by sarath on 22nd may 2001
4*/
5
6/*
7    comedi/drivers/amcc_s5933_v_58.h
8
9    Stuff for AMCC S5933 PCI Controller
10
11    Author: Michal Dobes <majkl@tesnet.cz>
12
13    Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
14    made by Andrea Cisternino  <acister@pcape1.pi.infn.it>
15    and as result of espionage from MITE code made by David A. Schleef.
16    Thanks to AMCC for their on-line documentation and bus master DMA
17    example.
18*/
19
20#ifndef _AMCC_S5933_H_
21#define _AMCC_S5933_H_
22
23#include <linux/pci.h>
24#include "../../comedidev.h"
25
26#ifdef PCI_SUPPORT_VER1
27#error    Sorry, no support for 2.1.55 and older! :-((((
28#endif
29
30/***********Added by sarath for compatibility with APCI3120
31
32*************************/
33
34#define FIFO_ADVANCE_ON_BYTE_2     0x20000000	// written on base0
35
36#define AMWEN_ENABLE                     0x02	// added for step 6 dma written on base2
37#define A2P_FIFO_WRITE_ENABLE            0x01
38
39#define AGCSTS_TC_ENABLE		   0x10000000	// Added for transfer count enable bit
40
41//  ADDON RELATED ADDITIONS
42// Constant
43#define     APCI3120_ENABLE_TRANSFER_ADD_ON_LOW       0x00
44#define     APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH      0x1200
45#define     APCI3120_A2P_FIFO_MANAGEMENT              0x04000400L
46#define     APCI3120_AMWEN_ENABLE                     0x02
47#define     APCI3120_A2P_FIFO_WRITE_ENABLE            0x01
48#define     APCI3120_FIFO_ADVANCE_ON_BYTE_2           0x20000000L
49#define     APCI3120_ENABLE_WRITE_TC_INT              0x00004000L
50#define     APCI3120_CLEAR_WRITE_TC_INT               0x00040000L
51#define     APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
52#define     APCI3120_DISABLE_BUS_MASTER_ADD_ON        0x0
53#define     APCI3120_DISABLE_BUS_MASTER_PCI           0x0
54
55 // ADD_ON ::: this needed since apci supports 16 bit interface to add on
56#define     APCI3120_ADD_ON_AGCSTS_LOW       0x3C
57#define     APCI3120_ADD_ON_AGCSTS_HIGH      APCI3120_ADD_ON_AGCSTS_LOW + 2
58#define     APCI3120_ADD_ON_MWAR_LOW         0x24
59#define     APCI3120_ADD_ON_MWAR_HIGH        APCI3120_ADD_ON_MWAR_LOW + 2
60#define     APCI3120_ADD_ON_MWTC_LOW         0x058
61#define     APCI3120_ADD_ON_MWTC_HIGH        APCI3120_ADD_ON_MWTC_LOW + 2
62
63// AMCC
64#define     APCI3120_AMCC_OP_MCSR            0x3C
65#define     APCI3120_AMCC_OP_REG_INTCSR      0x38
66
67/*******from here all upward definitions are added by sarath */
68
69/****************************************************************************/
70/* AMCC Operation Register Offsets - PCI                                    */
71/****************************************************************************/
72
73#define AMCC_OP_REG_OMB1         0x00
74#define AMCC_OP_REG_OMB2         0x04
75#define AMCC_OP_REG_OMB3         0x08
76#define AMCC_OP_REG_OMB4         0x0c
77#define AMCC_OP_REG_IMB1         0x10
78#define AMCC_OP_REG_IMB2         0x14
79#define AMCC_OP_REG_IMB3         0x18
80#define AMCC_OP_REG_IMB4         0x1c
81#define AMCC_OP_REG_FIFO         0x20
82#define AMCC_OP_REG_MWAR         0x24
83#define AMCC_OP_REG_MWTC         0x28
84#define AMCC_OP_REG_MRAR         0x2c
85#define AMCC_OP_REG_MRTC         0x30
86#define AMCC_OP_REG_MBEF         0x34
87#define AMCC_OP_REG_INTCSR       0x38
88#define  AMCC_OP_REG_INTCSR_SRC  (AMCC_OP_REG_INTCSR + 2)	/* INT source */
89#define  AMCC_OP_REG_INTCSR_FEC  (AMCC_OP_REG_INTCSR + 3)	/* FIFO ctrl */
90#define AMCC_OP_REG_MCSR         0x3c
91#define  AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2)	/* Data in byte 2 */
92#define  AMCC_OP_REG_MCSR_NVCMD  (AMCC_OP_REG_MCSR + 3)	/* Command in byte 3 */
93
94#define AMCC_FIFO_DEPTH_DWORD	8
95#define AMCC_FIFO_DEPTH_BYTES	(8 * sizeof (u32))
96
97/****************************************************************************/
98/* AMCC Operation Registers Size - PCI                                      */
99/****************************************************************************/
100
101#define AMCC_OP_REG_SIZE	 64	/* in bytes */
102
103/****************************************************************************/
104/* AMCC Operation Register Offsets - Add-on                                 */
105/****************************************************************************/
106
107#define AMCC_OP_REG_AIMB1         0x00
108#define AMCC_OP_REG_AIMB2         0x04
109#define AMCC_OP_REG_AIMB3         0x08
110#define AMCC_OP_REG_AIMB4         0x0c
111#define AMCC_OP_REG_AOMB1         0x10
112#define AMCC_OP_REG_AOMB2         0x14
113#define AMCC_OP_REG_AOMB3         0x18
114#define AMCC_OP_REG_AOMB4         0x1c
115#define AMCC_OP_REG_AFIFO         0x20
116#define AMCC_OP_REG_AMWAR         0x24
117#define AMCC_OP_REG_APTA          0x28
118#define AMCC_OP_REG_APTD          0x2c
119#define AMCC_OP_REG_AMRAR         0x30
120#define AMCC_OP_REG_AMBEF         0x34
121#define AMCC_OP_REG_AINT          0x38
122#define AMCC_OP_REG_AGCSTS        0x3c
123#define AMCC_OP_REG_AMWTC         0x58
124#define AMCC_OP_REG_AMRTC         0x5c
125
126/****************************************************************************/
127/* AMCC - Add-on General Control/Status Register                            */
128/****************************************************************************/
129
130#define AGCSTS_CONTROL_MASK	0xfffff000
131#define  AGCSTS_NV_ACC_MASK	0xe0000000
132#define  AGCSTS_RESET_MASK	0x0e000000
133#define  AGCSTS_NV_DA_MASK	0x00ff0000
134#define  AGCSTS_BIST_MASK	0x0000f000
135#define AGCSTS_STATUS_MASK	0x000000ff
136#define  AGCSTS_TCZERO_MASK	0x000000c0
137#define  AGCSTS_FIFO_ST_MASK	0x0000003f
138
139#define AGCSTS_RESET_MBFLAGS	0x08000000
140#define AGCSTS_RESET_P2A_FIFO	0x04000000
141#define AGCSTS_RESET_A2P_FIFO	0x02000000
142#define AGCSTS_RESET_FIFOS	(AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
143
144#define AGCSTS_A2P_TCOUNT	0x00000080
145#define AGCSTS_P2A_TCOUNT	0x00000040
146
147#define AGCSTS_FS_P2A_EMPTY	0x00000020
148#define AGCSTS_FS_P2A_HALF	0x00000010
149#define AGCSTS_FS_P2A_FULL	0x00000008
150
151#define AGCSTS_FS_A2P_EMPTY	0x00000004
152#define AGCSTS_FS_A2P_HALF	0x00000002
153#define AGCSTS_FS_A2P_FULL	0x00000001
154
155/****************************************************************************/
156/* AMCC - Add-on Interrupt Control/Status Register                            */
157/****************************************************************************/
158
159#define AINT_INT_MASK		0x00ff0000
160#define AINT_SEL_MASK		0x0000ffff
161#define  AINT_IS_ENSEL_MASK	0x00001f1f
162
163#define AINT_INT_ASSERTED	0x00800000
164#define AINT_BM_ERROR		0x00200000
165#define AINT_BIST_INT		0x00100000
166
167#define AINT_RT_COMPLETE	0x00080000
168#define AINT_WT_COMPLETE	0x00040000
169
170#define AINT_OUT_MB_INT		0x00020000
171#define AINT_IN_MB_INT		0x00010000
172
173#define AINT_READ_COMPL		0x00008000
174#define AINT_WRITE_COMPL	0x00004000
175
176#define AINT_OMB_ENABLE 	0x00001000
177#define AINT_OMB_SELECT 	0x00000c00
178#define AINT_OMB_BYTE		0x00000300
179
180#define AINT_IMB_ENABLE 	0x00000010
181#define AINT_IMB_SELECT 	0x0000000c
182#define AINT_IMB_BYTE		0x00000003
183
184/* Enable Bus Mastering */
185#define EN_A2P_TRANSFERS	0x00000400
186/* FIFO Flag Reset */
187#define RESET_A2P_FLAGS		0x04000000L
188/* FIFO Relative Priority */
189#define A2P_HI_PRIORITY		0x00000100L
190/* Identify Interrupt Sources */
191#define ANY_S593X_INT		0x00800000L
192#define READ_TC_INT		0x00080000L
193#define WRITE_TC_INT		0x00040000L
194#define IN_MB_INT		0x00020000L
195#define MASTER_ABORT_INT	0x00100000L
196#define TARGET_ABORT_INT	0x00200000L
197#define BUS_MASTER_INT		0x00200000L
198
199/****************************************************************************/
200
201struct pcilst_struct {
202	struct pcilst_struct *next;
203	int used;
204	struct pci_dev *pcidev;
205	unsigned short vendor;
206	unsigned short device;
207	unsigned int master;
208	unsigned char pci_bus;
209	unsigned char pci_slot;
210	unsigned char pci_func;
211	unsigned int io_addr[5];
212	unsigned int irq;
213};
214
215struct pcilst_struct *amcc_devices;	// ptr to root list of all amcc devices
216
217/****************************************************************************/
218
219void v_pci_card_list_init(unsigned short pci_vendor, char display);
220void v_pci_card_list_cleanup(unsigned short pci_vendor);
221struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
222	unsigned short device_id);
223int i_find_free_pci_card_by_position(unsigned short vendor_id,
224	unsigned short device_id, unsigned short pci_bus,
225	unsigned short pci_slot, struct pcilst_struct **card);
226struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
227	unsigned short device_id, unsigned short pci_bus,
228	unsigned short pci_slot);
229
230int i_pci_card_alloc(struct pcilst_struct *amcc);
231int i_pci_card_free(struct pcilst_struct *amcc);
232void v_pci_card_list_display(void);
233int i_pci_card_data(struct pcilst_struct *amcc,
234	unsigned char *pci_bus, unsigned char *pci_slot,
235	unsigned char *pci_func, unsigned short *io_addr, unsigned short *irq,
236	unsigned short *master);
237
238/****************************************************************************/
239
240/* build list of amcc cards in this system */
241void v_pci_card_list_init(unsigned short pci_vendor, char display)
242{
243	struct pci_dev *pcidev;
244	struct pcilst_struct *amcc, *last;
245	int i;
246
247	amcc_devices = NULL;
248	last = NULL;
249
250#if LINUX_VERSION_CODE < 0x020300
251	for (pcidev = pci_devices; pcidev; pcidev = pcidev->next) {
252#else
253	pci_for_each_dev(pcidev) {
254#endif
255		if (pcidev->vendor == pci_vendor) {
256			amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
257			memset(amcc, 0, sizeof(*amcc));
258
259			amcc->pcidev = pcidev;
260			if (last) {
261				last->next = amcc;
262			} else {
263				amcc_devices = amcc;
264			}
265			last = amcc;
266
267#if LINUX_VERSION_CODE < 0x020300
268			amcc->vendor = pcidev->vendor;
269			amcc->device = pcidev->device;
270			amcc->master = pcidev->master;
271			amcc->pci_bus = pcidev->bus->number;
272			amcc->pci_slot = PCI_SLOT(pcidev->devfn);
273			amcc->pci_func = PCI_FUNC(pcidev->devfn);
274			for (i = 0; i < 5; i++)
275				amcc->io_addr[i] =
276					pcidev->base_address[i] & ~3UL;
277			amcc->irq = pcidev->irq;
278#else
279			amcc->vendor = pcidev->vendor;
280			amcc->device = pcidev->device;
281#if 0
282			amcc->master = pcidev->master;	// how get this information under 2.4 kernels?
283#endif
284			amcc->pci_bus = pcidev->bus->number;
285			amcc->pci_slot = PCI_SLOT(pcidev->devfn);
286			amcc->pci_func = PCI_FUNC(pcidev->devfn);
287			for (i = 0; i < 5; i++)
288				amcc->io_addr[i] =
289					pcidev->resource[i].start & ~3UL;
290			amcc->irq = pcidev->irq;
291#endif
292
293		}
294	}
295
296	if (display)
297		v_pci_card_list_display();
298}
299
300/****************************************************************************/
301/* free up list of amcc cards in this system */
302void v_pci_card_list_cleanup(unsigned short pci_vendor)
303{
304	struct pcilst_struct *amcc, *next;
305
306	for (amcc = amcc_devices; amcc; amcc = next) {
307		next = amcc->next;
308		kfree(amcc);
309	}
310
311	amcc_devices = NULL;
312}
313
314/****************************************************************************/
315/* find first unused card with this device_id */
316struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
317	unsigned short device_id)
318{
319	struct pcilst_struct *amcc, *next;
320
321	for (amcc = amcc_devices; amcc; amcc = next) {
322		next = amcc->next;
323		if ((!amcc->used) && (amcc->device == device_id)
324			&& (amcc->vendor == vendor_id))
325			return amcc;
326
327	}
328
329	return NULL;
330}
331
332/****************************************************************************/
333/* find card on requested position */
334int i_find_free_pci_card_by_position(unsigned short vendor_id,
335	unsigned short device_id, unsigned short pci_bus,
336	unsigned short pci_slot, struct pcilst_struct **card)
337{
338	struct pcilst_struct *amcc, *next;
339
340	*card = NULL;
341	for (amcc = amcc_devices; amcc; amcc = next) {
342		next = amcc->next;
343		if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
344			&& (amcc->pci_bus == pci_bus)
345			&& (amcc->pci_slot == pci_slot)) {
346			if (!(amcc->used)) {
347				*card = amcc;
348				return 0;	// ok, card is found
349			} else {
350				rt_printk
351					(" - \nCard on requested position is used b:s %d:%d!\n",
352					pci_bus, pci_slot);
353				return 2;	// card exist but is used
354			}
355		}
356	}
357
358	return 1;		// no card found
359}
360
361/****************************************************************************/
362/* mark card as used */
363int i_pci_card_alloc(struct pcilst_struct *amcc)
364{
365	if (!amcc)
366		return -1;
367
368	if (amcc->used)
369		return 1;
370	amcc->used = 1;
371	return 0;
372}
373
374/****************************************************************************/
375/* mark card as free */
376int i_pci_card_free(struct pcilst_struct *amcc)
377{
378	if (!amcc)
379		return -1;
380
381	if (!amcc->used)
382		return 1;
383	amcc->used = 0;
384	return 0;
385}
386
387/****************************************************************************/
388/* display list of found cards */
389void v_pci_card_list_display(void)
390{
391	struct pcilst_struct *amcc, *next;
392
393	printk("List of pci cards\n");
394	printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
395
396	for (amcc = amcc_devices; amcc; amcc = next) {
397		next = amcc->next;
398		printk("%2d   %2d   %2d  0x%4x 0x%4x   %3s   0x%4x 0x%4x  %2d  %2d\n", amcc->pci_bus, amcc->pci_slot, amcc->pci_func, amcc->vendor, amcc->device, amcc->master ? "yes" : "no", amcc->io_addr[0], amcc->io_addr[2], amcc->irq, amcc->used);
399
400	}
401}
402
403/****************************************************************************/
404/* return all card information for driver */
405int i_pci_card_data(struct pcilst_struct *amcc,
406	unsigned char *pci_bus, unsigned char *pci_slot,
407	unsigned char *pci_func, unsigned short *io_addr, unsigned short *irq,
408	unsigned short *master)
409{
410	int i;
411
412	if (!amcc)
413		return -1;
414	*pci_bus = amcc->pci_bus;
415	*pci_slot = amcc->pci_slot;
416	*pci_func = amcc->pci_func;
417	for (i = 0; i < 5; i++)
418		io_addr[i] = amcc->io_addr[i];
419	*irq = amcc->irq;
420	*master = amcc->master;
421	return 0;
422}
423
424/****************************************************************************/
425/* select and alloc card */
426struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
427	unsigned short device_id, unsigned short pci_bus,
428	unsigned short pci_slot)
429{
430	struct pcilst_struct *card;
431
432	if ((pci_bus < 1) & (pci_slot < 1)) {	// use autodetection
433		if ((card = ptr_find_free_pci_card_by_device(vendor_id,
434					device_id)) == NULL) {
435			rt_printk(" - Unused card not found in system!\n");
436			return NULL;
437		}
438	} else {
439		switch (i_find_free_pci_card_by_position(vendor_id, device_id,
440				pci_bus, pci_slot, &card)) {
441		case 1:
442			rt_printk
443				(" - Card not found on requested position b:s %d:%d!\n",
444				pci_bus, pci_slot);
445			return NULL;
446		case 2:
447			rt_printk
448				(" - Card on requested position is used b:s %d:%d!\n",
449				pci_bus, pci_slot);
450			return NULL;
451		}
452	}
453
454	if (i_pci_card_alloc(card) != 0) {
455		rt_printk(" - Can't allocate card!\n");
456		return NULL;
457	}
458
459	return card;
460}
461
462#endif
463