xref: /openbsd/sys/dev/pci/cy_pci.c (revision 7a52a123)
1*7a52a123Sderaadt /*	$OpenBSD: cy_pci.c,v 1.5 2000/12/10 11:12:07 deraadt Exp $	*/
2ded20a09Sderaadt 
3ded20a09Sderaadt /*
4ded20a09Sderaadt  * cy.c
5ded20a09Sderaadt  *
6ded20a09Sderaadt  * Driver for Cyclades Cyclom-8/16/32 multiport serial cards
7ded20a09Sderaadt  * (currently not tested with Cyclom-32 cards)
8ded20a09Sderaadt  *
9ded20a09Sderaadt  * Timo Rossi, 1996
10ded20a09Sderaadt  *
11ded20a09Sderaadt  * Supports both ISA and PCI Cyclom cards
12ded20a09Sderaadt  *
13ded20a09Sderaadt  * Uses CD1400 automatic CTS flow control, and
14ded20a09Sderaadt  * if CY_HW_RTS is defined, uses CD1400 automatic input flow control.
15ded20a09Sderaadt  * This requires a special cable that exchanges the RTS and DTR lines.
16ded20a09Sderaadt  *
17ded20a09Sderaadt  * Lots of debug output can be enabled by defining CY_DEBUG
18ded20a09Sderaadt  * Some debugging counters (number of receive/transmit interrupts etc.)
19ded20a09Sderaadt  * can be enabled by defining CY_DEBUG1
20ded20a09Sderaadt  *
21ded20a09Sderaadt  * This version uses the bus_mem/io_??() stuff
22ded20a09Sderaadt  *
23ded20a09Sderaadt  * NOT TESTED !!!
24ded20a09Sderaadt  *
25ded20a09Sderaadt  */
26ded20a09Sderaadt 
27ded20a09Sderaadt #undef CY_DEBUG
28ded20a09Sderaadt #undef CY_DEBUG1
29ded20a09Sderaadt 
30ded20a09Sderaadt #include <sys/types.h>
31ded20a09Sderaadt #include <sys/param.h>
32ded20a09Sderaadt #include <sys/ioctl.h>
33ded20a09Sderaadt #include <sys/syslog.h>
34ded20a09Sderaadt #include <sys/fcntl.h>
35ded20a09Sderaadt #include <sys/tty.h>
36ded20a09Sderaadt #include <sys/proc.h>
37ded20a09Sderaadt #include <sys/conf.h>
38ded20a09Sderaadt #include <sys/user.h>
39ded20a09Sderaadt #include <sys/ioctl.h>
40ded20a09Sderaadt #include <sys/select.h>
41ded20a09Sderaadt #include <sys/device.h>
42ded20a09Sderaadt #include <sys/malloc.h>
43ded20a09Sderaadt #include <sys/systm.h>
44c0981ad2Sniklas #include <machine/bus.h>
45ded20a09Sderaadt #include <dev/pci/pcivar.h>
46ded20a09Sderaadt #include <dev/pci/pcireg.h>
47ded20a09Sderaadt #include <dev/pci/pcidevs.h>
48ded20a09Sderaadt 
49ded20a09Sderaadt #include <dev/ic/cd1400reg.h>
50ded20a09Sderaadt #include <dev/ic/cyreg.h>
51ded20a09Sderaadt 
52ded20a09Sderaadt /* Macros to clear/set/test flags. */
53ded20a09Sderaadt #define	SET(t, f)	(t) |= (f)
54ded20a09Sderaadt #define	CLR(t, f)	(t) &= ~(f)
55ded20a09Sderaadt #define	ISSET(t, f)	((t) & (f))
56ded20a09Sderaadt 
57ded20a09Sderaadt int cy_probe_pci __P((struct device *, void *, void *));
58c0981ad2Sniklas int cy_probe_common __P((int card, bus_space_tag_t,
59c0981ad2Sniklas 			 bus_space_handle_t, int bustype));
60ded20a09Sderaadt 
61ded20a09Sderaadt void cyattach __P((struct device *, struct device *, void *));
62ded20a09Sderaadt 
63ded20a09Sderaadt struct cfattach cy_pci_ca = {
64ded20a09Sderaadt   sizeof(struct cy_softc), cy_probe_pci, cyattach
65ded20a09Sderaadt };
66ded20a09Sderaadt 
67ded20a09Sderaadt /*
68ded20a09Sderaadt  * PCI probe
69ded20a09Sderaadt  */
70ded20a09Sderaadt int
71ded20a09Sderaadt cy_probe_pci(parent, match, aux)
72ded20a09Sderaadt      struct device *parent;
73ded20a09Sderaadt      void *match, *aux;
74ded20a09Sderaadt {
75ded20a09Sderaadt   int card = ((struct device *)match)->dv_unit;
76ded20a09Sderaadt   struct pci_attach_args *pa = aux;
77c0981ad2Sniklas   bus_space_tag_t memt;
78c0981ad2Sniklas   bus_space_handle_t memh;
79c0981ad2Sniklas   bus_addr_t memaddr;
80c0981ad2Sniklas   bus_size_t memsize;
81c0981ad2Sniklas   bus_space_tag_t iot;
82c0981ad2Sniklas   bus_space_handle_t ioh;
83c0981ad2Sniklas   bus_addr_t iobase;
84c0981ad2Sniklas   bus_size_t iosize;
85ded20a09Sderaadt   int cacheable;
86*7a52a123Sderaadt   int plx_ver;
87ded20a09Sderaadt 
88ded20a09Sderaadt   if(!(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_CYCLADES &&
89ded20a09Sderaadt        (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CYCLADES_CYCLOMY_1 ||
90ded20a09Sderaadt 	PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CYCLADES_CYCLOMY_2)))
91ded20a09Sderaadt     return 0;
92ded20a09Sderaadt 
93ded20a09Sderaadt #ifdef CY_DEBUG
94ded20a09Sderaadt   printf("cy: Found Cyclades PCI device, id = 0x%x\n", pa->pa_id);
95ded20a09Sderaadt #endif
96ded20a09Sderaadt 
97c0981ad2Sniklas   memt = pa->pa_memt;
98c0981ad2Sniklas   iot = pa->pa_iot;
99ded20a09Sderaadt 
100ded20a09Sderaadt   if(pci_mem_find(pa->pa_pc, pa->pa_tag, 0x18,
101ded20a09Sderaadt 		  &memaddr, &memsize, &cacheable) != 0) {
102ded20a09Sderaadt     printf("cy%d: can't find PCI card memory", card);
103ded20a09Sderaadt     return 0;
104ded20a09Sderaadt   }
105ded20a09Sderaadt 
106ded20a09Sderaadt   /* map the memory (non-cacheable) */
107c0981ad2Sniklas   if(bus_space_map(memt, memaddr, memsize, 0, &memh) != 0) {
108ded20a09Sderaadt     printf("cy%d: couldn't map PCI memory region\n", card);
109ded20a09Sderaadt     return 0;
110ded20a09Sderaadt   }
111ded20a09Sderaadt 
112ded20a09Sderaadt   /* the PCI Cyclom IO space is only used for enabling interrupts */
113ded20a09Sderaadt   if(pci_io_find(pa->pa_pc, pa->pa_tag, 0x14, &iobase, &iosize) != 0) {
114c0981ad2Sniklas     bus_space_unmap(memt, memh, memsize);
115ded20a09Sderaadt     printf("cy%d: couldn't find PCI io region\n", card);
116ded20a09Sderaadt     return 0;
117ded20a09Sderaadt   }
118ded20a09Sderaadt 
119562a9f8eSniklas   if(bus_space_map(iot, iobase, iosize, 0, &ioh) != 0) {
120c0981ad2Sniklas     bus_space_unmap(memt, memh, memsize);
121ded20a09Sderaadt     printf("cy%d: couldn't map PCI io region\n", card);
122ded20a09Sderaadt     return 0;
123ded20a09Sderaadt   }
124ded20a09Sderaadt 
125ded20a09Sderaadt #ifdef CY_DEBUG
126ded20a09Sderaadt   printf("cy%d: pci mapped mem 0x%lx (size %d), io 0x%x (size %d)\n",
127ded20a09Sderaadt 	 card, memaddr, memsize, iobase, iosize);
128ded20a09Sderaadt #endif
129ded20a09Sderaadt 
130c0981ad2Sniklas   if(cy_probe_common(card, memt, memh, CY_BUSTYPE_PCI) == 0) {
131c0981ad2Sniklas     bus_space_unmap(memt, memh, memsize);
132c0981ad2Sniklas     bus_space_unmap(iot, ioh, iosize);
133ded20a09Sderaadt     printf("cy%d: PCI Cyclom card with no CD1400s!?\n", card);
134ded20a09Sderaadt     return 0;
135ded20a09Sderaadt   }
136ded20a09Sderaadt 
137*7a52a123Sderaadt   /* Get PLX version */
138*7a52a123Sderaadt   plx_ver = bus_space_read_1(memt, memh, CY_PLX_VER) & 0x0f;
139*7a52a123Sderaadt 
140ded20a09Sderaadt   /* Enable PCI card interrupts */
141*7a52a123Sderaadt   switch (plx_ver) {
142*7a52a123Sderaadt   case CY_PLX_9050:
143*7a52a123Sderaadt           bus_space_write_2(iot, ioh, CY_PCI_INTENA_9050,
144*7a52a123Sderaadt               bus_space_read_2(iot, ioh, CY_PCI_INTENA_9050) | 0x40);
145*7a52a123Sderaadt           break;
146*7a52a123Sderaadt   case CY_PLX_9060:
147*7a52a123Sderaadt   case CY_PLX_9080:
148*7a52a123Sderaadt   default:
149c0981ad2Sniklas           bus_space_write_2(iot, ioh, CY_PCI_INTENA,
150c0981ad2Sniklas               bus_space_read_2(iot, ioh, CY_PCI_INTENA) | 0x900);
151*7a52a123Sderaadt   }
152ded20a09Sderaadt   return 1;
153ded20a09Sderaadt }
154