amcc_s5933_58.h revision a2279ae5b58edb7cbe2196d08572fcf59f292354
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
223						       device_id);
224int i_find_free_pci_card_by_position(unsigned short vendor_id,
225				     unsigned short device_id,
226				     unsigned short pci_bus,
227				     unsigned short pci_slot,
228				     struct pcilst_struct **card);
229struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
230						    unsigned short device_id,
231						    unsigned short pci_bus,
232						    unsigned short pci_slot);
233
234int i_pci_card_alloc(struct pcilst_struct *amcc);
235int i_pci_card_free(struct pcilst_struct *amcc);
236void v_pci_card_list_display(void);
237int i_pci_card_data(struct pcilst_struct *amcc,
238		    unsigned char *pci_bus, unsigned char *pci_slot,
239		    unsigned char *pci_func, unsigned short *io_addr,
240		    unsigned short *irq, unsigned short *master);
241
242/****************************************************************************/
243
244/* build list of amcc cards in this system */
245void v_pci_card_list_init(unsigned short pci_vendor, char display)
246{
247	struct pci_dev *pcidev;
248	struct pcilst_struct *amcc, *last;
249	int i;
250
251	amcc_devices = NULL;
252	last = NULL;
253
254	pci_for_each_dev(pcidev) {
255		if (pcidev->vendor == pci_vendor) {
256			amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
257			if (amcc == NULL)
258				continue;
259
260			memset(amcc, 0, sizeof(*amcc));
261
262			amcc->pcidev = pcidev;
263			if (last) {
264				last->next = amcc;
265			} else {
266				amcc_devices = amcc;
267			}
268			last = amcc;
269
270			amcc->vendor = pcidev->vendor;
271			amcc->device = pcidev->device;
272#if 0
273			amcc->master = pcidev->master;	/*  how get this information under 2.4 kernels? */
274#endif
275			amcc->pci_bus = pcidev->bus->number;
276			amcc->pci_slot = PCI_SLOT(pcidev->devfn);
277			amcc->pci_func = PCI_FUNC(pcidev->devfn);
278			for (i = 0; i < 5; i++)
279				amcc->io_addr[i] =
280				    pcidev->resource[i].start & ~3UL;
281			amcc->irq = pcidev->irq;
282		}
283	}
284
285	if (display)
286		v_pci_card_list_display();
287}
288
289/****************************************************************************/
290/* free up list of amcc cards in this system */
291void v_pci_card_list_cleanup(unsigned short pci_vendor)
292{
293	struct pcilst_struct *amcc, *next;
294
295	for (amcc = amcc_devices; amcc; amcc = next) {
296		next = amcc->next;
297		kfree(amcc);
298	}
299
300	amcc_devices = NULL;
301}
302
303/****************************************************************************/
304/* find first unused card with this device_id */
305struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
306						       unsigned short device_id)
307{
308	struct pcilst_struct *amcc, *next;
309
310	for (amcc = amcc_devices; amcc; amcc = next) {
311		next = amcc->next;
312		if ((!amcc->used) && (amcc->device == device_id)
313		    && (amcc->vendor == vendor_id))
314			return amcc;
315
316	}
317
318	return NULL;
319}
320
321/****************************************************************************/
322/* find card on requested position */
323int i_find_free_pci_card_by_position(unsigned short vendor_id,
324				     unsigned short device_id,
325				     unsigned short pci_bus,
326				     unsigned short pci_slot,
327				     struct pcilst_struct **card)
328{
329	struct pcilst_struct *amcc, *next;
330
331	*card = NULL;
332	for (amcc = amcc_devices; amcc; amcc = next) {
333		next = amcc->next;
334		if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
335		    && (amcc->pci_bus == pci_bus)
336		    && (amcc->pci_slot == pci_slot)) {
337			if (!(amcc->used)) {
338				*card = amcc;
339				return 0;	/*  ok, card is found */
340			} else {
341				printk
342				    (" - \nCard on requested position is used b:s %d:%d!\n",
343				     pci_bus, pci_slot);
344				return 2;	/*  card exist but is used */
345			}
346		}
347	}
348
349	return 1;		/*  no card found */
350}
351
352/****************************************************************************/
353/* mark card as used */
354int i_pci_card_alloc(struct pcilst_struct *amcc)
355{
356	if (!amcc)
357		return -1;
358
359	if (amcc->used)
360		return 1;
361	amcc->used = 1;
362	return 0;
363}
364
365/****************************************************************************/
366/* mark card as free */
367int i_pci_card_free(struct pcilst_struct *amcc)
368{
369	if (!amcc)
370		return -1;
371
372	if (!amcc->used)
373		return 1;
374	amcc->used = 0;
375	return 0;
376}
377
378/****************************************************************************/
379/* display list of found cards */
380void v_pci_card_list_display(void)
381{
382	struct pcilst_struct *amcc, *next;
383
384	printk("List of pci cards\n");
385	printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
386
387	for (amcc = amcc_devices; amcc; amcc = next) {
388		next = amcc->next;
389		printk
390		    ("%2d   %2d   %2d  0x%4x 0x%4x   %3s   0x%4x 0x%4x  %2d  %2d\n",
391		     amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
392		     amcc->vendor, amcc->device, amcc->master ? "yes" : "no",
393		     amcc->io_addr[0], amcc->io_addr[2], amcc->irq, amcc->used);
394
395	}
396}
397
398/****************************************************************************/
399/* return all card information for driver */
400int i_pci_card_data(struct pcilst_struct *amcc,
401		    unsigned char *pci_bus, unsigned char *pci_slot,
402		    unsigned char *pci_func, unsigned short *io_addr,
403		    unsigned short *irq, unsigned short *master)
404{
405	int i;
406
407	if (!amcc)
408		return -1;
409	*pci_bus = amcc->pci_bus;
410	*pci_slot = amcc->pci_slot;
411	*pci_func = amcc->pci_func;
412	for (i = 0; i < 5; i++)
413		io_addr[i] = amcc->io_addr[i];
414	*irq = amcc->irq;
415	*master = amcc->master;
416	return 0;
417}
418
419/****************************************************************************/
420/* select and alloc card */
421struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
422						    unsigned short device_id,
423						    unsigned short pci_bus,
424						    unsigned short pci_slot)
425{
426	struct pcilst_struct *card;
427
428	if ((pci_bus < 1) & (pci_slot < 1)) {	/*  use autodetection */
429		card = ptr_find_free_pci_card_by_device(vendor_id, device_id);
430		if (card == NULL) {
431			printk(" - Unused card not found in system!\n");
432			return NULL;
433		}
434	} else {
435		switch (i_find_free_pci_card_by_position(vendor_id, device_id,
436							 pci_bus, pci_slot,
437							 &card)) {
438		case 1:
439			printk
440			    (" - Card not found on requested position b:s %d:%d!\n",
441			     pci_bus, pci_slot);
442			return NULL;
443		case 2:
444			printk
445			    (" - Card on requested position is used b:s %d:%d!\n",
446			     pci_bus, pci_slot);
447			return NULL;
448		}
449	}
450
451	if (i_pci_card_alloc(card) != 0) {
452		printk(" - Can't allocate card!\n");
453		return NULL;
454	}
455
456	return card;
457}
458
459#endif
460