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