]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/pccard/pcic_pci.c
- Added PCI identification support for the TI1251 PCI/CardBus bridge.
[FreeBSD/FreeBSD.git] / sys / pccard / pcic_pci.c
1 /*
2  * Copyright (c) 1997 Ted Faber
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice immediately at the beginning of the file, without modification,
11  *    this list of conditions, and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Absolutely no warranty of function or purpose is made by the author
16  *    Ted Faber.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * $Id: pcic_p.c,v 1.10 1999/04/24 20:14:03 peter Exp $
30  */
31
32 #include "pci.h"
33 #if NPCI > 0
34
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/systm.h>
38 #include <pci/pcireg.h>
39 #include <pci/pcivar.h>
40 #include <pci/pcic_p.h>
41 #include <pccard/i82365.h>
42 #include <vm/vm.h>
43 #include <vm/pmap.h>
44
45 static u_long pcic_pci_count = 0;
46
47 static const char *pcic_pci_probe(pcici_t, pcidi_t);
48 static void  pcic_pci_attach(pcici_t, int);
49
50 static void  pd6832_legacy_init(pcici_t tag, int unit);
51
52 static struct pci_device pcic_pci_driver = {
53         "pcic",
54         pcic_pci_probe,
55         pcic_pci_attach,
56         &pcic_pci_count,
57         NULL
58 };
59
60 #ifdef COMPAT_PCI_DRIVER
61 COMPAT_PCI_DRIVER(pcic_pci, pcic_pci_driver);
62 #else
63 DATA_SET(pcidevice_set, pcic_pci_driver);
64 #endif /* COMPAT_PCI_DRIVER */
65
66 /*
67  * Return the ID string for the controller if the vendor/product id
68  * matches, NULL otherwise.
69  */
70 static const char *
71 pcic_pci_probe(pcici_t tag, pcidi_t type)
72 {
73         switch (type) {
74         case PCI_DEVICE_ID_PCIC_CLPD6832:
75                 return ("Cirrus Logic PD6832 PCI/CardBus Bridge");
76         case PCI_DEVICE_ID_PCIC_TI1130:
77                 return ("TI PCI-1130 PCI-CardBus Bridge");
78         case PCI_DEVICE_ID_PCIC_TI1131:
79                 return ("TI PCI-1131 PCI-CardBus Bridge");
80         case PCI_DEVICE_ID_PCIC_TI1220:
81                 return ("TI PCI-1220 PCI-CardBus Bridge");
82         case PCI_DEVICE_ID_PCIC_TI1221:
83                 return ("TI PCI-1221 PCI-CardBus Bridge");
84         case PCI_DEVICE_ID_PCIC_TI1250:
85                 return ("TI PCI-1250 PCI-CardBus Bridge");
86         case PCI_DEVICE_ID_PCIC_TI1251:
87                 return ("TI PCI-1251 PCI-CardBus Bridge");
88         case PCI_DEVICE_ID_TOSHIBA_TOPIC95:
89                 return ("Toshiba ToPIC95 PCI-CardBus Bridge");
90         case PCI_DEVICE_ID_TOSHIBA_TOPIC97:
91                 return ("Toshiba ToPIC97 PCI-CardBus Bridge");
92         case PCI_DEVICE_ID_RICOH_RL5C465:
93                 return ("Ricoh RL5C465 PCI-CardBus Brige");
94         case PCI_DEVICE_ID_RICOH_RL5C475:
95                 return ("Ricoh RL5C475 PCI-CardBus Brige");
96         case PCI_DEVICE_ID_RICOH_RL5C476:
97                 return ("Ricoh RL5C476 PCI-CardBus Brige");
98         case PCI_DEVICE_ID_RICOH_RL5C478:
99                 return ("Ricoh RL5C478 PCI-CardBus Brige");
100         /* 16bit PC-card bridges */
101         case PCI_DEVICE_ID_PCIC_CLPD6729:
102                 return ("Cirrus Logic PD6729/6730 PC-Card Controller");
103         case PCI_DEVICE_ID_PCIC_OZ6729:
104                 return ("O2micro OZ6729 PC-Card Bridge");
105         case PCI_DEVICE_ID_PCIC_OZ6730:
106                 return ("O2micro OZ6730 PC-Card Bridge");
107
108         default:
109                 break;
110         }
111         return (NULL);
112 }
113
114
115 /*
116  * General PCI based card dispatch routine.  Right now
117  * it only understands the CL-PD6832.
118  */
119 static void
120 pcic_pci_attach(pcici_t config_id, int unit)
121 {
122         u_long pcic_type;       /* The vendor id of the PCI pcic */
123
124         pcic_type = pci_conf_read(config_id, PCI_ID_REG);
125
126         switch (pcic_type) { 
127         case PCI_DEVICE_ID_PCIC_CLPD6832:
128                 pd6832_legacy_init(config_id, unit);
129                 break;
130         }
131
132         if (bootverbose) {              
133                 int i, j;
134                 u_char *p;
135                 u_long *pl;
136
137                 printf("PCI Config space:\n");
138                 for (j = 0; j < 0x98; j += 16) {
139                         printf("%02x: ", j);
140                         for (i = 0; i < 16; i += 4)
141                                 printf(" %08lx", pci_conf_read(config_id, i+j));
142                         printf("\n");
143                 }
144                 p = (u_char *)pmap_mapdev(pci_conf_read(config_id, 0x10),
145                                           0x1000);
146                 pl = (u_long *)p;
147                 printf("Cardbus Socket registers:\n");
148                 printf("00: ");
149                 for (i = 0; i < 4; i += 1)
150                         printf(" %08lx:", pl[i]);
151                 printf("\n10: ");
152                 for (i = 4; i < 8; i += 1)
153                         printf(" %08lx:", pl[i]);
154                 printf("\nExCa registers:\n");
155                 for (i = 0; i < 0x40; i += 16)
156                         printf("%02x: %16D\n", i, p + 0x800 + i, " ");
157         }
158 }
159
160 /*
161  * Set up the CL-PD6832 to look like a ISA based PCMCIA chip (a
162  * PD672X).  This routine is called once per PCMCIA socket.
163  */
164 static void
165 pd6832_legacy_init(pcici_t tag, int unit)
166 {
167         u_long bcr;             /* to set interrupts */
168         u_short io_port;        /* the io_port to map this slot on */
169         static int num6832 = 0; /* The number of 6832s initialized */
170
171         /*
172          * Some BIOS leave the legacy address uninitialized.  This
173          * insures that the PD6832 puts itself where the driver will
174          * look.  We assume that multiple 6832's should be laid out
175          * sequentially.  We only initialize the first socket's legacy port,
176          * the other is a dummy.
177          */
178         io_port = PCIC_INDEX_0 + num6832 * CLPD6832_NUM_REGS;
179         if (unit == 0)
180             pci_conf_write(tag, CLPD6832_LEGACY_16BIT_IOADDR,
181                            io_port & ~PCI_MAP_IO);
182
183         /*
184          * I think this should be a call to pci_map_port, but that
185          * routine won't map regiaters above 0x28, and the register we
186          * need to map is 0x44.
187          */
188         io_port = pci_conf_read(tag, CLPD6832_LEGACY_16BIT_IOADDR)
189             & ~PCI_MAP_IO;
190
191         /*
192          * Configure the first I/O window to contain CLPD6832_NUM_REGS
193          * words and deactivate the second by setting the limit lower
194          * than the base.
195          */
196         pci_conf_write(tag, CLPD6832_IO_BASE0, io_port | 1);
197         pci_conf_write(tag, CLPD6832_IO_LIMIT0,
198                        (io_port + CLPD6832_NUM_REGS) | 1);
199
200         pci_conf_write(tag, CLPD6832_IO_BASE1, (io_port + 0x20) | 1);
201         pci_conf_write(tag, CLPD6832_IO_LIMIT1, io_port | 1 );
202
203         /*
204          * Set default operating mode (I/O port space) and allocate
205          * this socket to the current unit.
206          */
207         pci_conf_write(tag, PCI_COMMAND_STATUS_REG, CLPD6832_COMMAND_DEFAULTS );
208         pci_conf_write(tag, CLPD6832_SOCKET, unit);
209
210         /*
211          * Set up the card inserted/card removed interrupts to come
212          * through the isa IRQ.
213          */
214         bcr = pci_conf_read(tag, CLPD6832_BRIDGE_CONTROL);
215         bcr |= (CLPD6832_BCR_ISA_IRQ|CLPD6832_BCR_MGMT_IRQ_ENA);
216         pci_conf_write(tag, CLPD6832_BRIDGE_CONTROL, bcr);
217
218         /* After initializing 2 sockets, the chip is fully configured */
219         if (unit == 1)
220                 num6832++;
221
222         if (bootverbose)
223                 printf("CardBus: Legacy PC-card 16bit I/O address [0x%x]\n",
224                        io_port);
225 }
226 #endif /* NPCI > 0 */