pccbb.c revision 1.12 1 /* $NetBSD: pccbb.c,v 1.12 2000/01/13 09:01:17 joda Exp $ */
2
3 /*
4 * Copyright (c) 1998 and 1999 HAYAKAWA Koichi. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by HAYAKAWA Koichi.
17 * 4. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 #define CBB_DEBUG
34 #define SHOW_REGS
35 #define PCCBB_PCMCIA_POLL
36 */
37 /* #define CBB_DEBUG */
38
39 /*
40 #define CB_PCMCIA_POLL
41 #define CB_PCMCIA_POLL_ONLY
42 #define LEVEL2
43 */
44
45 #include <sys/types.h>
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/kernel.h>
49 #include <sys/errno.h>
50 #include <sys/ioctl.h>
51 #include <sys/syslog.h>
52 #include <sys/device.h>
53 #include <sys/malloc.h>
54
55 #include <machine/intr.h>
56 #include <machine/bus.h>
57
58 #include <dev/pci/pcivar.h>
59 #include <dev/pci/pcireg.h>
60 #include <dev/pci/pcidevs.h>
61
62 #include <dev/pci/pccbbreg.h>
63
64 #include <dev/cardbus/cardslotvar.h>
65
66 #include <dev/cardbus/cardbusvar.h>
67
68 #include <dev/pcmcia/pcmciareg.h>
69 #include <dev/pcmcia/pcmciavar.h>
70
71 #include <dev/ic/i82365reg.h>
72 #include <dev/ic/i82365var.h>
73 #include <dev/pci/pccbbvar.h>
74
75 #include "locators.h"
76
77
78 #ifndef __NetBSD_Version__
79 struct cfdriver cbb_cd = {
80 NULL, "cbb", DV_DULL
81 };
82 #endif
83
84 #if defined CBB_DEBUG
85 #define DPRINTF(x) printf x
86 #define STATIC
87 #else
88 #define DPRINTF(x)
89 #define STATIC static
90 #endif
91
92
93 #ifdef __BROKEN_INDIRECT_CONFIG
94 int pcicbbmatch __P((struct device *, void *, void *));
95 #else
96 int pcicbbmatch __P((struct device *, struct cfdata *, void *));
97 #endif
98 void pccbbattach __P((struct device *, struct device *, void *));
99 int pccbbintr __P((void *));
100 static void pci113x_insert __P((void *));
101
102 static int pccbb_detect_card __P((struct pccbb_softc *));
103
104 static void pccbb_pcmcia_write __P((struct pcic_handle *, int, u_int8_t));
105 static u_int8_t pccbb_pcmcia_read __P((struct pcic_handle *, int));
106 #define Pcic_read(ph, reg) ((ph)->ph_read((ph), (reg)))
107 #define Pcic_write(ph, reg, val) ((ph)->ph_write((ph), (reg), (val)))
108
109
110 STATIC int cb_reset __P((struct pccbb_softc *));
111 STATIC int cb_detect_voltage __P((struct pccbb_softc *));
112 STATIC int cbbprint __P((void *, const char *));
113
114 static int cb_chipset __P((u_int32_t, char const **, int *));
115 STATIC void pccbb_pcmcia_attach_setup __P((struct pccbb_softc *, struct pcmciabus_attach_args *));
116 #if 0
117 STATIC void pccbb_pcmcia_attach_card __P((struct pcic_handle *));
118 STATIC void pccbb_pcmcia_detach_card __P((struct pcic_handle *, int));
119 STATIC void pccbb_pcmcia_deactivate_card __P((struct pcic_handle *));
120 #endif
121
122 STATIC int pccbb_ctrl __P((cardbus_chipset_tag_t, int));
123 STATIC int pccbb_power __P((cardbus_chipset_tag_t, int));
124 STATIC int pccbb_cardenable __P((struct pccbb_softc *sc, int function));
125 #if !rbus
126 static int pccbb_io_open __P((cardbus_chipset_tag_t, int, u_int32_t, u_int32_t));
127 static int pccbb_io_close __P((cardbus_chipset_tag_t, int));
128 static int pccbb_mem_open __P((cardbus_chipset_tag_t, int, u_int32_t, u_int32_t));
129 static int pccbb_mem_close __P((cardbus_chipset_tag_t, int));
130 #endif /* !rbus */
131 static void *pccbb_intr_establish __P((cardbus_chipset_tag_t, int irq, int level, int (* ih)(void *), void *sc));
132 static void pccbb_intr_disestablish __P((cardbus_chipset_tag_t ct, void *ih));
133
134 static cardbustag_t pccbb_make_tag __P((cardbus_chipset_tag_t, int, int, int));
135 static void pccbb_free_tag __P((cardbus_chipset_tag_t, cardbustag_t));
136 static cardbusreg_t pccbb_conf_read __P((cardbus_chipset_tag_t, cardbustag_t, int));
137 static void pccbb_conf_write __P((cardbus_chipset_tag_t, cardbustag_t, int, cardbusreg_t));
138 static void pccbb_chipinit __P((struct pccbb_softc *));
139
140
141 STATIC int pccbb_pcmcia_mem_alloc __P((pcmcia_chipset_handle_t, bus_size_t,
142 struct pcmcia_mem_handle *));
143 STATIC void pccbb_pcmcia_mem_free __P((pcmcia_chipset_handle_t,
144 struct pcmcia_mem_handle *));
145 STATIC int pccbb_pcmcia_mem_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
146 bus_size_t, struct pcmcia_mem_handle *, bus_addr_t *, int *));
147 STATIC void pccbb_pcmcia_mem_unmap __P((pcmcia_chipset_handle_t, int));
148 STATIC int pccbb_pcmcia_io_alloc __P((pcmcia_chipset_handle_t, bus_addr_t,
149 bus_size_t, bus_size_t, struct pcmcia_io_handle *));
150 STATIC void pccbb_pcmcia_io_free __P((pcmcia_chipset_handle_t,
151 struct pcmcia_io_handle *));
152 STATIC int pccbb_pcmcia_io_map __P((pcmcia_chipset_handle_t, int, bus_addr_t,
153 bus_size_t, struct pcmcia_io_handle *, int *));
154 STATIC void pccbb_pcmcia_io_unmap __P((pcmcia_chipset_handle_t, int));
155 STATIC void *pccbb_pcmcia_intr_establish __P((pcmcia_chipset_handle_t,
156 struct pcmcia_function *, int, int (*) (void *), void *));
157 STATIC void pccbb_pcmcia_intr_disestablish __P((pcmcia_chipset_handle_t, void *));
158 STATIC void pccbb_pcmcia_socket_enable __P((pcmcia_chipset_handle_t));
159 STATIC void pccbb_pcmcia_socket_disable __P((pcmcia_chipset_handle_t));
160 STATIC int pccbb_pcmcia_card_detect __P((pcmcia_chipset_handle_t pch));
161
162 static void pccbb_pcmcia_do_io_map __P((struct pcic_handle *, int));
163 static void pccbb_pcmcia_wait_ready __P((struct pcic_handle *));
164 static void pccbb_pcmcia_do_mem_map __P((struct pcic_handle *, int));
165
166 /* bus-space allocation and disallocation functions */
167 #if rbus
168
169 static int pccbb_rbus_cb_space_alloc __P((cardbus_chipset_tag_t, rbus_tag_t,
170 bus_addr_t addr, bus_size_t size,
171 bus_addr_t mask, bus_size_t align,
172 int flags, bus_addr_t *addrp,
173 bus_space_handle_t *bshp));
174 static int pccbb_rbus_cb_space_free __P((cardbus_chipset_tag_t, rbus_tag_t,
175 bus_space_handle_t, bus_size_t));
176
177 #endif /* rbus */
178
179 #if rbus
180
181 static int pccbb_open_win __P((struct pccbb_softc *, bus_space_tag_t, bus_addr_t, bus_size_t, bus_space_handle_t, int flags));
182 static int pccbb_close_win __P((struct pccbb_softc *, bus_space_tag_t, bus_space_handle_t, bus_size_t));
183 static int pccbb_winlist_insert __P((struct pccbb_win_chain **, bus_addr_t,
184 bus_size_t, bus_space_handle_t, int));
185 static int pccbb_winlist_delete __P((struct pccbb_win_chain **,
186 bus_space_handle_t, bus_size_t));
187 static void pccbb_winset __P((bus_addr_t align, struct pccbb_softc *,
188 bus_space_tag_t));
189 void pccbb_winlist_show(struct pccbb_win_chain *);
190
191 #endif /* rbus */
192
193 /* for config_defer */
194 static void pccbb_pci_callback __P((struct device *));
195
196
197 #if defined SHOW_REGS
198 static void cb_show_regs __P((pci_chipset_tag_t pc, pcitag_t tag, bus_space_tag_t memt, bus_space_handle_t memh));
199 #endif
200
201
202
203 struct cfattach cbb_pci_ca = {
204 sizeof(struct pccbb_softc), pcicbbmatch, pccbbattach
205 };
206
207
208 static struct pcmcia_chip_functions pccbb_pcmcia_funcs = {
209 pccbb_pcmcia_mem_alloc,
210 pccbb_pcmcia_mem_free,
211 pccbb_pcmcia_mem_map,
212 pccbb_pcmcia_mem_unmap,
213 pccbb_pcmcia_io_alloc,
214 pccbb_pcmcia_io_free,
215 pccbb_pcmcia_io_map,
216 pccbb_pcmcia_io_unmap,
217 pccbb_pcmcia_intr_establish,
218 pccbb_pcmcia_intr_disestablish,
219 pccbb_pcmcia_socket_enable,
220 pccbb_pcmcia_socket_disable,
221 pccbb_pcmcia_card_detect
222 };
223
224 #if rbus
225 static struct cardbus_functions pccbb_funcs = {
226 pccbb_rbus_cb_space_alloc,
227 pccbb_rbus_cb_space_free,
228 pccbb_intr_establish,
229 pccbb_intr_disestablish,
230 pccbb_ctrl,
231 pccbb_power,
232 pccbb_make_tag,
233 pccbb_free_tag,
234 pccbb_conf_read,
235 pccbb_conf_write,
236 };
237 #else
238 static struct cardbus_functions pccbb_funcs = {
239 pccbb_ctrl,
240 pccbb_power,
241 pccbb_mem_open,
242 pccbb_mem_close,
243 pccbb_io_open,
244 pccbb_io_close,
245 pccbb_intr_establish,
246 pccbb_intr_disestablish,
247 pccbb_make_tag,
248 pccbb_conf_read,
249 pccbb_conf_write,
250 };
251 #endif
252
253
254
255
256 int
257 pcicbbmatch(parent, match, aux)
258 struct device *parent;
259 #ifdef __BROKEN_INDIRECT_CONFIG
260 void *match;
261 #else
262 struct cfdata *match;
263 #endif
264 void *aux;
265 {
266 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
267
268 if(PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
269 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_CARDBUS &&
270 PCI_INTERFACE(pa->pa_class) == 0) {
271 return 1;
272 }
273
274 return 0;
275 }
276
277
278 #define MAKEID(vendor, prod) (((vendor) << PCI_VENDOR_SHIFT) \
279 | ((prod) << PCI_PRODUCT_SHIFT))
280
281
282 struct yenta_chipinfo {
283 pcireg_t yc_id; /* vendor tag | product tag */
284 const char *yc_name;
285 int yc_chiptype;
286 int yc_flags;
287 } yc_chipsets[] = {
288 /* Texas Instruments chips */
289 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1130), "TI1130", CB_TI113X,
290 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
291 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1131), "TI1131", CB_TI113X,
292 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
293
294 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1250), "TI1250", CB_TI12XX,
295 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
296 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1220), "TI1220", CB_TI12XX,
297 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
298 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1221), "TI1221", CB_TI12XX,
299 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
300 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1225), "TI1225", CB_TI12XX,
301 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
302 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251), "TI1251", CB_TI12XX,
303 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
304 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1251B), "TI1251B", CB_TI12XX,
305 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
306 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1211), "TI1211", CB_TI12XX,
307 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
308 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1420), "TI1420", CB_TI12XX,
309 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
310 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI1450), "TI1450", CB_TI12XX,
311 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
312 {MAKEID(PCI_VENDOR_TI, PCI_PRODUCT_TI_PCI2030), "TI2030", CB_UNKNOWN,
313 PCCBB_PCMCIA_IO_RELOC | PCCBB_PCMCIA_MEM_32},
314
315 /* Ricoh chips */
316 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C475), "Rx5C475",
317 CB_RX5C47X, PCCBB_PCMCIA_MEM_32},
318 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_RL5C476), "RL5C476",
319 CB_RX5C47X, PCCBB_PCMCIA_MEM_32},
320 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C477), "Rx5C477",
321 CB_RX5C47X, PCCBB_PCMCIA_MEM_32},
322 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C478), "Rx5C478",
323 CB_RX5C47X, PCCBB_PCMCIA_MEM_32},
324
325 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C465), "Rx5C465",
326 CB_RX5C46X, PCCBB_PCMCIA_MEM_32},
327 {MAKEID(PCI_VENDOR_RICOH, PCI_PRODUCT_RICOH_Rx5C466), "Rx5C466",
328 CB_RX5C46X, PCCBB_PCMCIA_MEM_32},
329
330 /* Toshiba products */
331 {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC95), "ToPIC95",
332 CB_TOPIC95, PCCBB_PCMCIA_MEM_32},
333 {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC95B), "ToPIC95B",
334 CB_TOPIC95B, PCCBB_PCMCIA_MEM_32},
335 {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC97), "ToPIC97",
336 CB_TOPIC97, PCCBB_PCMCIA_MEM_32},
337 {MAKEID(PCI_VENDOR_TOSHIBA2, PCI_PRODUCT_TOSHIBA2_ToPIC100), "ToPIC100",
338 CB_TOPIC97, PCCBB_PCMCIA_MEM_32},
339
340 /* Cirrus Logic products */
341 {MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6832), "CL-PD683X",
342 CB_CIRRUS, PCCBB_PCMCIA_MEM_32},
343 {MAKEID(PCI_VENDOR_CIRRUS, PCI_PRODUCT_CIRRUS_CL_PD6833), "CL-PD683X",
344 CB_CIRRUS, PCCBB_PCMCIA_MEM_32},
345
346 /* sentinel, or Generic chip */
347 {0 /* null id */, "unknown", CB_UNKNOWN, PCCBB_PCMCIA_MEM_32},
348 };
349
350
351
352 static int
353 cb_chipset(pci_id, namep, flagp)
354 u_int32_t pci_id;
355 char const **namep;
356 int *flagp;
357 {
358 int loopend = sizeof(yc_chipsets)/sizeof(yc_chipsets[0]);
359 struct yenta_chipinfo *ycp, *ycend;
360
361 ycend = yc_chipsets + loopend;
362
363 for (ycp =yc_chipsets; ycp < ycend && pci_id != ycp->yc_id; ++ycp);
364
365 if (ycp == ycend) {
366 /* not found */
367 ycp = yc_chipsets + loopend - 1; /* to point the sentinel */
368 }
369
370 if (namep != NULL) {
371 *namep = ycp->yc_name;
372 }
373
374 if (flagp != NULL) {
375 *flagp = ycp->yc_flags;
376 }
377
378 return ycp->yc_chiptype;
379 }
380
381
382
383
384
385 void
386 pccbbattach(parent, self, aux)
387 struct device *parent;
388 struct device *self;
389 void *aux;
390 {
391 struct pccbb_softc *sc = (void *)self;
392 struct pci_attach_args *pa = aux;
393 pci_chipset_tag_t pc = pa->pa_pc;
394 pcireg_t sock_base, busreg;
395 bus_addr_t sockbase;
396 char const *name;
397 int flags;
398
399 sc->sc_chipset = cb_chipset(pa->pa_id, &name, &flags);
400 printf(" (%s), chipflags %d\n", name, flags);
401
402 #if rbus
403 sc->sc_rbus_iot = rbus_pccbb_parent_io(pa);
404 sc->sc_rbus_memt = rbus_pccbb_parent_mem(pa);
405 #endif /* rbus */
406
407 sc->sc_base_memh = 0;
408
409 /*
410 * MAP socket registers and ExCA registers on memory-space
411 * When no valid address is set on socket base registers (on pci
412 * config space), get it not polite way.
413 */
414 sock_base = pci_conf_read(pc, pa->pa_tag, PCI_SOCKBASE);
415
416 if (PCI_MAPREG_MEM_ADDR(sock_base) >= 0x100000 &&
417 PCI_MAPREG_MEM_ADDR(sock_base) != 0xfffffff0) {
418 /* The address must be valid. */
419 if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_MEM, 0,
420 &sc->sc_base_memt, &sc->sc_base_memh, &sockbase,
421 NULL)) {
422 printf("%s: can't map socket base address 0x%x\n", sc->sc_dev.dv_xname,
423 sock_base);
424 /* I think it's funny: socket base registers must be mapped on
425 memory space, but ... */
426 if (pci_mapreg_map(pa, PCI_SOCKBASE, PCI_MAPREG_TYPE_IO, 0,
427 &sc->sc_base_memt, &sc->sc_base_memh,
428 &sockbase, NULL)) {
429 printf("%s: can't map socket base address 0x%lx: io mode\n",
430 sc->sc_dev.dv_xname, sockbase);
431 /* give up... allocate register space via rbus. */
432 sc->sc_base_memh = 0;
433 pci_conf_write(pc, pa->pa_tag, PCI_SOCKBASE, 0);
434 }
435 } else {
436 DPRINTF(("%s: socket base address 0x%lx\n",
437 sc->sc_dev.dv_xname, sockbase));
438 }
439 }
440
441
442 sc->sc_mem_start = 0; /* XXX */
443 sc->sc_mem_end = 0xffffffff; /* XXX */
444
445 /*
446 * When interrupt isn't routed correctly, give up probing cbb and do
447 * not kill pcic-compatible port.
448 */
449 if ((0 == pa->pa_intrline) || (255 == pa->pa_intrline)) {
450 printf(" Do not use %s because of intr unconfig.\n", sc->sc_dev.dv_xname);
451 return;
452 }
453
454 /*
455 * When bus number isn't set correctly, give up using 32-bit CardBus
456 * mode.
457 */
458 busreg = pci_conf_read(pc, pa->pa_tag, PCI_BUSNUM);
459 #if notyet
460 if (((busreg >> 8) & 0xff) == 0) {
461 printf(" CardBus on %s will not be configured, because of bus no unconfig.\n", sc->sc_dev.dv_xname);
462 flags |= PCCBB_PCMCIA_16BITONLY;
463 }
464 #endif
465
466 /* pccbb_machdep.c end */
467
468
469 #if defined CBB_DEBUG
470 {
471 static char *intrname[5] = {"NON", "A", "B", "C", "D"};
472 printf(" intrpin %s, intrtag %d\n", intrname[pa->pa_intrpin],
473 pa->pa_intrline);
474 }
475 #endif
476
477
478 /* setup softc */
479 sc->sc_pc = pc;
480 sc->sc_iot = pa->pa_iot;
481 sc->sc_memt = pa->pa_memt;
482 sc->sc_dmat = pa->pa_dmat;
483 sc->sc_tag = pa->pa_tag;
484 sc->sc_function = pa->pa_function;
485
486 sc->sc_intrline = pa->pa_intrline;
487 sc->sc_intrtag = pa->pa_intrtag;
488 sc->sc_intrpin = pa->pa_intrpin;
489
490 sc->sc_pcmcia_flags = flags; /* set PCMCIA facility */
491
492 /* bus bridge initialisation */
493 pccbb_chipinit(sc);
494
495 #if __NetBSD_Version__ > 103060000
496 config_defer(self, pccbb_pci_callback);
497 #else
498 pccbb_pci_callback(self);
499 #endif
500 }
501
502
503
504
505 static void
506 pccbb_pci_callback(self)
507 struct device *self;
508 {
509 struct pccbb_softc *sc = (void *)self;
510 pci_chipset_tag_t pc = sc->sc_pc;
511 bus_space_tag_t base_memt;
512 bus_space_handle_t base_memh;
513 u_int32_t maskreg;
514 pci_intr_handle_t ih;
515 const char *intrstr = NULL;
516 bus_addr_t sockbase;
517 struct cbslot_attach_args cba;
518 struct pcmciabus_attach_args paa;
519 struct cardslot_attach_args caa;
520 struct cardslot_softc *csc;
521
522 if (0 == sc->sc_base_memh) {
523 /* The socket registers aren't mapped correctly. */
524 #if rbus
525 if (rbus_space_alloc(sc->sc_rbus_memt,
526 0, /* address: I don't mind where it is mapped */
527 0x1000, /* size */
528 0x0fff, /* mask */
529 (sc->sc_chipset == CB_RX5C47X || sc->sc_chipset == CB_TI113X) ? 0x10000 : 0x1000, /* align */
530 0, /* flags */
531 &sockbase, &sc->sc_base_memh)) {
532 return;
533 }
534 sc->sc_base_memt = sc->sc_memt;
535 pci_conf_write(pc, sc->sc_tag, PCI_SOCKBASE, sockbase);
536 DPRINTF(("%s: CardBus resister address 0x%lx -> 0x%x\n",
537 sc->sc_dev.dv_xname, sockbase, pci_conf_read(pc, sc->sc_tag, PCI_SOCKBASE)));
538 #else
539 sc->sc_base_memt = sc->sc_memt;
540 #if !defined CBB_PCI_BASE
541 #define CBB_PCI_BASE 0x20000000
542 #endif
543 if (bus_space_alloc(sc->sc_base_memt, CBB_PCI_BASE, 0xffffffff,
544 0x1000, /* size */
545 0x1000, /* alignment */
546 0, /* boundary */
547 0, /* flags */
548 &sockbase, &sc->sc_base_memh)) {
549 /* cannot allocate memory space */
550 return;
551 }
552 pci_conf_write(pc, sc->sc_tag, PCI_SOCKBASE, sockbase);
553 DPRINTF(("%s: CardBus resister address 0x%x -> 0x%x\n",sc->sc_dev.dv_xname,
554 sock_base, pci_conf_read(pc, sc->sc_tag, PCI_SOCKBASE)));
555 #endif
556 }
557
558 base_memt = sc->sc_base_memt; /* socket regs memory tag */
559 base_memh = sc->sc_base_memh; /* socket regs memory handle */
560
561
562 /* CSC Interrupt: Card detect interrupt on */
563 maskreg = bus_space_read_4(base_memt, base_memh, CB_SOCKET_MASK);
564 maskreg |= CB_SOCKET_MASK_CD; /* Card detect intr is turned on. */
565 bus_space_write_4(base_memt, base_memh, CB_SOCKET_MASK, maskreg);
566 /* reset interrupt */
567 bus_space_write_4(base_memt, base_memh, CB_SOCKET_EVENT,
568 bus_space_read_4(base_memt, base_memh, CB_SOCKET_EVENT));
569
570
571 /* Map and establish the interrupt. */
572 if (pci_intr_map(pc, sc->sc_intrtag, sc->sc_intrpin,
573 sc->sc_intrline, &ih)) {
574 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
575 return;
576 }
577 intrstr = pci_intr_string(pc, ih);
578 sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, pccbbintr, sc);
579
580 if (sc->sc_ih == NULL) {
581 printf("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
582 if (intrstr != NULL) {
583 printf(" at %s", intrstr);
584 }
585 printf("\n");
586 return;
587 }
588
589 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
590
591 {
592 u_int32_t sockstat = bus_space_read_4(base_memt,base_memh, CB_SOCKET_STAT);
593 if (0 == (sockstat & CB_SOCKET_STAT_CD)) { /* card exist */
594 sc->sc_flags |= CBB_CARDEXIST;
595 }
596 }
597
598 /*
599 * attach cardbus
600 */
601 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY)) {
602 pcireg_t busreg = pci_conf_read(pc, sc->sc_tag, PCI_BUSNUM);
603 pcireg_t bhlc = pci_conf_read(pc, sc->sc_tag, PCI_BHLC_REG);
604
605 /* initialise cbslot_attach */
606 cba.cba_busname = "cardbus";
607 cba.cba_iot = sc->sc_iot;
608 cba.cba_memt = sc->sc_memt;
609 cba.cba_dmat = sc->sc_dmat;
610 cba.cba_function = 0;
611 cba.cba_bus = (busreg >> 8) & 0x0ff;
612 cba.cba_cc = (void *)sc;
613 cba.cba_cf = &pccbb_funcs;
614 cba.cba_intrline = sc->sc_intrline;
615
616 #if rbus
617 cba.cba_rbus_iot = sc->sc_rbus_iot;
618 cba.cba_rbus_memt = sc->sc_rbus_memt;
619 #endif
620
621 cba.cba_cacheline = PCI_CACHELINE(bhlc);
622 cba.cba_lattimer = PCI_CB_LATENCY(busreg);
623
624 printf("%s: cacheline 0x%x lattimer 0x%x\n", sc->sc_dev.dv_xname,
625 cba.cba_cacheline, cba.cba_lattimer);
626 printf("%s: bhlc 0x%x lscp 0x%x\n", sc->sc_dev.dv_xname,
627 bhlc, busreg);
628 #if defined SHOW_REGS
629 cb_show_regs(sc->sc_pc, sc->sc_tag, sc->sc_base_memt, sc->sc_base_memh);
630 #endif
631 }
632
633 pccbb_pcmcia_attach_setup(sc, &paa);
634 caa.caa_cb_attach = NULL;
635 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_16BITONLY)) {
636 caa.caa_cb_attach = &cba;
637 }
638 caa.caa_16_attach = &paa;
639 caa.caa_ph = &sc->sc_pcmcia_h;
640
641 if (NULL != (csc = (void *)config_found(self, &caa, cbbprint))) {
642 DPRINTF(("pccbbattach: found cardslot\n"));
643 sc->sc_csc = csc;
644 }
645
646 return;
647 }
648
649
650
651 static void
652 pccbb_chipinit(sc)
653 struct pccbb_softc *sc;
654 {
655 pci_chipset_tag_t pc = sc->sc_pc;
656 pcitag_t tag = sc->sc_tag;
657 bus_space_tag_t base_memt = sc->sc_base_memt; /* socket regs memory tag */
658 bus_space_handle_t base_memh = sc->sc_base_memh; /* socket regs memory handle */
659 pcireg_t cbctrl;
660
661 /*
662 * Set PCI command reg.
663 * Some laptop's BIOSes (i.e. TICO) do not enable CardBus chip.
664 */
665 {
666 pcireg_t command = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
667
668 /* I believe it is harmless. */
669 command |= (PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
670 PCI_COMMAND_MASTER_ENABLE);
671 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, command);
672 }
673
674 /*
675 * Set CardBus latency timer
676 */
677 {
678 pcireg_t pci_lscp = pci_conf_read(pc, tag, PCI_CB_LSCP_REG);
679 if (PCI_CB_LATENCY(pci_lscp) < 0x20) {
680 pci_lscp &= ~(PCI_CB_LATENCY_MASK << PCI_CB_LATENCY_SHIFT);
681 pci_lscp |= (0x20 << PCI_CB_LATENCY_SHIFT);
682 pci_conf_write(pc, tag, PCI_CB_LSCP_REG, pci_lscp);
683 }
684 DPRINTF(("CardBus latency timer 0x%x (%x)\n", PCI_CB_LATENCY(pci_lscp),
685 pci_conf_read(pc, tag, PCI_CB_LSCP_REG)));
686 }
687
688 /*
689 * Set PCI latency timer
690 */
691 {
692 pcireg_t pci_bhlc = pci_conf_read(pc, tag, PCI_BHLC_REG);
693 if (PCI_LATTIMER(pci_bhlc) < 0x10) {
694 pci_bhlc &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
695 pci_bhlc |= (0x10 << PCI_LATTIMER_SHIFT);
696 pci_conf_write(pc, tag, PCI_BHLC_REG, pci_bhlc);
697 }
698 DPRINTF(("PCI latency timer 0x%x (%x)\n", PCI_LATTIMER(pci_bhlc),
699 pci_conf_read(pc, tag, PCI_BHLC_REG)));
700 }
701
702 /* disable Legacy IO */
703
704 switch (sc->sc_chipset) {
705 case CB_RX5C46X: /* fallthrogh */
706 #if 0
707 case CB_RX5C47X:
708 #endif
709 /*
710 * The legacy pcic io-port on Ricoh CardBus bridges cannot be
711 * disabled by substituting 0 into PCI_LEGACY register. Ricoh
712 * CardBus bridges have special bits on Bridge control reg (addr
713 * 0x3e on PCI config space).
714 */
715 {
716 pcireg_t bcri = pci_conf_read(pc, tag, PCI_BCR_INTR);
717 bcri &= ~(CB_BCRI_RL_3E0_ENA | CB_BCRI_RL_3E2_ENA);
718 pci_conf_write(pc, tag, PCI_BCR_INTR, bcri);
719 }
720 break;
721 default:
722 /* XXX: I don't know proper way to kill Legacy IO properly. */
723 pci_conf_write(pc, tag, PCI_LEGACY, 0x0);
724 break;
725 }
726
727
728
729 /*
730 * Interrupt routing: use PCI interrupt
731 */
732 {
733 u_int32_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
734 bcr &= ~CB_BCR_INTR_IREQ_ENABLE; /* use PCI Intr */
735 bcr |= CB_BCR_WRITE_POST_ENABLE; /* enable write post */
736 pci_conf_write(pc, tag, PCI_BCR_INTR, bcr);
737 }
738
739 if (CB_TI113X == sc->sc_chipset) {
740 cbctrl = pci_conf_read(pc, tag, PCI_CBCTRL);
741 if (0 == sc->sc_function) {
742 cbctrl |= PCI113X_CBCTRL_PCI_IRQ_ENA;
743 }
744 cbctrl |= PCI113X_CBCTRL_PCI_IRQ_ENA; /* XXX: bug in PCI113X */
745 cbctrl |= PCI113X_CBCTRL_PCI_CSC; /* CSC intr enable */
746 cbctrl &= ~PCI113X_CBCTRL_PCI_INTR; /* functional intr prohibit */
747 cbctrl &= ~PCI113X_CBCTRL_INT_MASK; /* prohibit ISA routing */
748 pci_conf_write(pc, tag, PCI_CBCTRL, cbctrl);
749
750 /* set ExCA regs: PCI113X required to be set bit 4 at Interrupt
751 and General Register, which is IRQ Enable Register, and clear
752 bit 3:0 to zero in order to route CSC interrupt to PCI
753 interrupt pin. */
754 bus_space_write_1(base_memt, base_memh, 0x0803, 0x10);
755 /* set ExCA regs: prohibit all pcmcia-style CSC intr. */
756 bus_space_write_1(base_memt, base_memh, 0x0805, 0x00);
757 #if 1
758 DPRINTF(("ExCA regs:"));
759 DPRINTF((" 0x803: %02x", bus_space_read_1(base_memt, base_memh, 0x803)));
760 DPRINTF((" 0x805: %02x", bus_space_read_1(base_memt, base_memh, 0x805)));
761 DPRINTF((" 0x81e: %02x\n", bus_space_read_1(base_memt,base_memh,0x81e)));
762 #endif
763 } else if (sc->sc_chipset == CB_TI12XX) {
764 cbctrl = pci_conf_read(pc, tag, PCI_CBCTRL);
765 cbctrl &= ~PCI12XX_CBCTRL_INT_MASK; /* intr routing reset */
766 pci_conf_write(pc, tag, PCI_CBCTRL, cbctrl);
767 /*
768 * set ExCA regs: PCI12XX required to be set bit 4 at Interrupt
769 * and General Register, which is IRQ Enable Register, and clear
770 * bit 3:0 to zero in order to route CSC interrupt to PCI
771 * interrupt pin.
772 */
773 bus_space_write_1(base_memt, base_memh, 0x0803, 0x10);
774 /* set ExCA regs: prohibit all pcmcia-style CSC intr. */
775 bus_space_write_1(base_memt, base_memh, 0x0805, 0x00);
776 } else if (sc->sc_chipset == CB_TOPIC95B) {
777 cardbusreg_t sock_ctrl, slot_ctrl;
778
779 sock_ctrl = pci_conf_read(pc, tag, TOPIC_SOCKET_CTRL);
780 pci_conf_write(pc, tag, TOPIC_SOCKET_CTRL,
781 sock_ctrl | TOPIC_SOCKET_CTRL_SCR_IRQSEL);
782
783 slot_ctrl = pci_conf_read(pc, tag, TOPIC_SLOT_CTRL);
784 DPRINTF(("%s: topic slot ctrl reg 0x%x -> ", sc->sc_dev.dv_xname,
785 slot_ctrl));
786 slot_ctrl |= (TOPIC_SLOT_CTRL_SLOTON | TOPIC_SLOT_CTRL_SLOTEN |
787 TOPIC_SLOT_CTRL_ID_LOCK);
788 slot_ctrl |= TOPIC_SLOT_CTRL_CARDBUS;
789 slot_ctrl &= ~TOPIC_SLOT_CTRL_SWDETECT;
790 pci_conf_write(pc, tag, TOPIC_SLOT_CTRL, slot_ctrl);
791 DPRINTF(("0x%x\n", slot_ctrl));
792 }
793
794 /* close all memory and io windows */
795 pci_conf_write(pc, tag, PCI_CB_MEMBASE0, 0xffffffff);
796 pci_conf_write(pc, tag, PCI_CB_MEMLIMIT0, 0);
797 pci_conf_write(pc, tag, PCI_CB_MEMBASE1, 0xffffffff);
798 pci_conf_write(pc, tag, PCI_CB_MEMLIMIT1, 0);
799 pci_conf_write(pc, tag, PCI_CB_IOBASE0, 0xffffffff);
800 pci_conf_write(pc, tag, PCI_CB_IOLIMIT0, 0);
801 pci_conf_write(pc, tag, PCI_CB_IOBASE1, 0xffffffff);
802 pci_conf_write(pc, tag, PCI_CB_IOLIMIT1, 0);
803
804 return;
805 }
806
807
808
809 /*
810 * attach pccard bus
811 */
812 STATIC void
813 pccbb_pcmcia_attach_setup(sc, paa)
814 struct pccbb_softc *sc;
815 struct pcmciabus_attach_args *paa;
816 {
817 struct pcic_handle *ph = &sc->sc_pcmcia_h;
818 #if rbus
819 rbus_tag_t rb;
820 #endif
821
822 /* initialise pcmcia part in pccbb_softc */
823 ph->ph_parent = (struct device *)sc;
824 ph->sock = sc->sc_function;
825 ph->flags = 0;
826 ph->shutdown = 0;
827 ph->ih_irq = sc->sc_intrline;
828 ph->ph_bus_t = sc->sc_base_memt;
829 ph->ph_bus_h = sc->sc_base_memh;
830 ph->ph_read = pccbb_pcmcia_read;
831 ph->ph_write = pccbb_pcmcia_write;
832 sc->sc_pct = &pccbb_pcmcia_funcs;
833
834 Pcic_write(ph, PCIC_CSC_INTR, 0);
835 Pcic_read(ph, PCIC_CSC);
836
837 /* initialise pcmcia bus attachment */
838 paa->paa_busname = "pcmcia";
839 paa->pct = sc->sc_pct;
840 paa->pch = ph;
841 paa->iobase = 0; /* I don't use them */
842 paa->iosize = 0;
843 #if rbus
844 rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
845 paa->iobase = rb->rb_start + rb->rb_offset;
846 paa->iosize = rb->rb_end - rb->rb_start;
847 #endif
848
849 return;
850 }
851
852
853 #if 0
854 STATIC void
855 pccbb_pcmcia_attach_card(ph)
856 struct pcic_handle *ph;
857 {
858 if (ph->flags & PCIC_FLAG_CARDP) {
859 panic("pccbb_pcmcia_attach_card: already attached");
860 }
861
862 /* call the MI attach function */
863 pcmcia_card_attach(ph->pcmcia);
864
865 ph->flags |= PCIC_FLAG_CARDP;
866 }
867
868
869 STATIC void
870 pccbb_pcmcia_detach_card(ph, flags)
871 struct pcic_handle *ph;
872 int flags;
873 {
874 if (!(ph->flags & PCIC_FLAG_CARDP)) {
875 panic("pccbb_pcmcia_detach_card: already detached");
876 }
877
878 ph->flags &= ~PCIC_FLAG_CARDP;
879
880 /* call the MI detach function */
881 pcmcia_card_detach(ph->pcmcia, flags);
882 }
883 #endif
884
885
886
887
888 /*
889 * int pccbbintr(arg)
890 * void *arg;
891 * This routine handles the interrupt from Yenta PCI-CardBus bridge
892 * itself.
893 */
894 int
895 pccbbintr(arg)
896 void *arg;
897 {
898 struct pccbb_softc *sc = (struct pccbb_softc *)arg;
899 u_int32_t sockevent;
900 bus_space_tag_t memt = sc->sc_base_memt;
901 bus_space_handle_t memh = sc->sc_base_memh;
902 u_int32_t sockstate;
903
904 sockevent = bus_space_read_4(memt, memh, CB_SOCKET_EVENT);
905 if (0 == sockevent) { /* not for me */
906 return 0;
907 } else {
908 bus_space_write_4(memt, memh, CB_SOCKET_EVENT, sockevent); /* reset bit */
909 }
910 sockstate = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
911
912 if (sockevent & CB_SOCKET_EVENT_CD) {
913 if (CB_SOCKET_STAT_CD == (sockstate & CB_SOCKET_STAT_CD)) {
914 /* A card should be removed. */
915 if (sc->sc_flags & CBB_CARDEXIST) {
916 DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname, sockevent));
917 DPRINTF((" card removed, 0x%08x\n", sockstate));
918 sc->sc_flags &= ~CBB_CARDEXIST;
919 if (sc->sc_csc->sc_status & CARDSLOT_STATUS_CARD_16) {
920 #if 0
921 struct pcic_handle *ph = &sc->sc_pcmcia_h;
922
923 pcmcia_card_deactivate(ph->pcmcia);
924 pccbb_pcmcia_socket_disable(ph);
925 pccbb_pcmcia_detach_card(ph, DETACH_FORCE);
926 #endif
927 cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_REMOVAL_16);
928 } else if (sc->sc_csc->sc_status & CARDSLOT_STATUS_CARD_CB) {
929 /* Cardbus intr removed */
930 cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_REMOVAL_CB);
931 }
932 }
933 } else if (0x00 == (sockstate & CB_SOCKET_STAT_CD)) {
934 if (sc->sc_flags & CBB_INSERTING) {
935 untimeout(pci113x_insert, sc);
936 }
937 timeout(pci113x_insert, sc, hz/10);
938 sc->sc_flags |= CBB_INSERTING;
939 }
940 } else {
941 DPRINTF(("%s: sockevent = %b\n",
942 sc->sc_dev.dv_xname, sockevent, PCCBB_SOCKEVENT_BITS));
943 DPRINTF(("%s: sockstate = %b\n",
944 sc->sc_dev.dv_xname,
945 sockstate, PCCBB_SOCKSTATE_BITS));
946 }
947
948 return 1;
949 }
950
951
952
953 static void
954 pci113x_insert(arg)
955 void *arg;
956 {
957 struct pccbb_softc *sc = (struct pccbb_softc *)arg;
958 u_int32_t sockevent, sockstate;
959
960 sockevent = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
961 CB_SOCKET_EVENT);
962 sockstate = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh,
963 CB_SOCKET_STAT);
964
965 if (0 == (sockstate & CB_SOCKET_STAT_CD)) { /* card exist */
966 DPRINTF(("%s: 0x%08x", sc->sc_dev.dv_xname, sockevent));
967 DPRINTF((" card inserted, 0x%08x\n", sockstate));
968 sc->sc_flags |= CBB_CARDEXIST;
969 /* call pccard intterupt handler here */
970 if (sockstate & CB_SOCKET_STAT_16BIT) {
971 /* 16-bit card found */
972 /* pccbb_pcmcia_attach_card(&sc->sc_pcmcia_h); */
973 cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_INSERTION_16);
974 } else if (sockstate & CB_SOCKET_STAT_CB) {
975 /* cardbus card fuond */
976 /* cardbus_attach_card(sc->sc_csc); */
977 cardslot_event_throw(sc->sc_csc, CARDSLOT_EVENT_INSERTION_CB);
978 } else {
979 /* who are you? */
980 }
981 } else {
982 timeout(pci113x_insert, sc, hz/10);
983 }
984 }
985
986
987
988
989 #define PCCBB_PCMCIA_OFFSET 0x800
990 static u_int8_t
991 pccbb_pcmcia_read(ph, reg)
992 struct pcic_handle *ph;
993 int reg;
994 {
995 return bus_space_read_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg);
996 }
997
998
999
1000 static void
1001 pccbb_pcmcia_write(ph, reg, val)
1002 struct pcic_handle *ph;
1003 int reg;
1004 u_int8_t val;
1005 {
1006 bus_space_write_1(ph->ph_bus_t, ph->ph_bus_h, PCCBB_PCMCIA_OFFSET + reg, val);
1007
1008 return;
1009 }
1010
1011
1012
1013
1014 /*
1015 * STATIC int pccbb_ctrl(cardbus_chipset_tag_t, int)
1016 */
1017 STATIC int
1018 pccbb_ctrl(ct, command)
1019 cardbus_chipset_tag_t ct;
1020 int command;
1021 {
1022 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1023
1024 switch(command) {
1025 case CARDBUS_CD:
1026 if (2 == pccbb_detect_card(sc)) {
1027 int retval = 0;
1028 int status = cb_detect_voltage(sc);
1029 if (PCCARD_VCC_5V & status) {
1030 retval |= CARDBUS_5V_CARD;
1031 }
1032 if (PCCARD_VCC_3V & status) {
1033 retval |= CARDBUS_3V_CARD;
1034 }
1035 if (PCCARD_VCC_XV & status) {
1036 retval |= CARDBUS_XV_CARD;
1037 }
1038 if (PCCARD_VCC_YV & status) {
1039 retval |= CARDBUS_YV_CARD;
1040 }
1041 return retval;
1042 } else {
1043 return 0;
1044 }
1045 break;
1046 case CARDBUS_RESET:
1047 return cb_reset(sc);
1048 break;
1049 case CARDBUS_IO_ENABLE: /* fallthrough */
1050 case CARDBUS_IO_DISABLE: /* fallthrough */
1051 case CARDBUS_MEM_ENABLE: /* fallthrough */
1052 case CARDBUS_MEM_DISABLE: /* fallthrough */
1053 case CARDBUS_BM_ENABLE: /* fallthrough */
1054 case CARDBUS_BM_DISABLE: /* fallthrough */
1055 return pccbb_cardenable(sc, command);
1056 break;
1057 }
1058
1059 return 0;
1060 }
1061
1062
1063
1064 /*
1065 * STATIC int pccbb_power(cardbus_chipset_tag_t, int)
1066 * This function returns true when it succeeds and returns false when
1067 * it fails.
1068 */
1069 STATIC int
1070 pccbb_power(ct, command)
1071 cardbus_chipset_tag_t ct;
1072 int command;
1073 {
1074 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1075
1076 u_int32_t status, sock_ctrl;
1077 bus_space_tag_t memt = sc->sc_base_memt;
1078 bus_space_handle_t memh = sc->sc_base_memh;
1079
1080 DPRINTF(("pccbb_power: %s and %s [%x]\n",
1081 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" :
1082 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_5V ? "CARDBUS_VCC_5V" :
1083 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_3V ? "CARDBUS_VCC_3V" :
1084 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_XV ? "CARDBUS_VCC_XV" :
1085 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_YV ? "CARDBUS_VCC_YV" :
1086 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_0V ? "CARDBUS_VCC_0V" :
1087 "UNKNOWN",
1088 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_UC ? "CARDBUS_VPP_UC" :
1089 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_12V ? "CARDBUS_VPP_12V" :
1090 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_VCC ? "CARDBUS_VPP_VCC" :
1091 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" :
1092 "UNKNOWN",
1093 command));
1094
1095 status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
1096 sock_ctrl = bus_space_read_4(memt, memh, CB_SOCKET_CTRL);
1097
1098 switch (command & CARDBUS_VCCMASK) {
1099 case CARDBUS_VCC_UC:
1100 break;
1101 case CARDBUS_VCC_5V:
1102 if (CB_SOCKET_STAT_5VCARD & status) { /* check 5 V card */
1103 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
1104 sock_ctrl |= CB_SOCKET_CTRL_VCC_5V;
1105 } else {
1106 printf("%s: BAD voltage request: no 5 V card\n", sc->sc_dev.dv_xname);
1107 }
1108 break;
1109 case CARDBUS_VCC_3V:
1110 if (CB_SOCKET_STAT_3VCARD & status) {
1111 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
1112 sock_ctrl |= CB_SOCKET_CTRL_VCC_3V;
1113 } else {
1114 printf("%s: BAD voltage request: no 3.3 V card\n", sc->sc_dev.dv_xname);
1115 }
1116 break;
1117 case CARDBUS_VCC_0V:
1118 sock_ctrl &= ~CB_SOCKET_CTRL_VCCMASK;
1119 break;
1120 default:
1121 return 0; /* power NEVER changed */
1122 break;
1123 }
1124
1125 switch (command & CARDBUS_VPPMASK) {
1126 case CARDBUS_VPP_UC:
1127 break;
1128 case CARDBUS_VPP_0V:
1129 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
1130 break;
1131 case CARDBUS_VPP_VCC:
1132 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
1133 sock_ctrl |= ((sock_ctrl >> 4) & 0x07);
1134 break;
1135 case CARDBUS_VPP_12V:
1136 sock_ctrl &= ~CB_SOCKET_CTRL_VPPMASK;
1137 sock_ctrl |= CB_SOCKET_CTRL_VPP_12V;
1138 break;
1139 }
1140
1141 #if 0
1142 DPRINTF(("sock_ctrl: %x\n", sock_ctrl));
1143 #endif
1144 bus_space_write_4(memt, memh, CB_SOCKET_CTRL, sock_ctrl);
1145 status = bus_space_read_4(memt, memh, CB_SOCKET_STAT);
1146
1147 delay(20*1000); /* wait 20 ms: Vcc setup time */
1148 /* XXX
1149 delay 200 ms: though the standard defines that the Vcc set-up time
1150 is 20 ms, some PC-Card bridge requires longer duration.
1151 */
1152 delay(200*1000);
1153
1154
1155 if (status & CB_SOCKET_STAT_BADVCC) { /* bad Vcc request */
1156 printf("%s: bad Vcc request. sock_ctrl 0x%x, sock_status 0x%x\n",
1157 sc->sc_dev.dv_xname, sock_ctrl ,status);
1158 DPRINTF(("pccbb_power: %s and %s [%x]\n",
1159 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_UC ? "CARDBUS_VCC_UC" :
1160 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_5V ? "CARDBUS_VCC_5V":
1161 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_3V ? "CARDBUS_VCC_3V":
1162 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_XV ? "CARDBUS_VCC_XV":
1163 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_YV ? "CARDBUS_VCC_YV":
1164 (command & CARDBUS_VCCMASK) == CARDBUS_VCC_0V ? "CARDBUS_VCC_0V":
1165 "UNKNOWN",
1166 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_UC ? "CARDBUS_VPP_UC":
1167 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_12V ?"CARDBUS_VPP_12V":
1168 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_VCC ?"CARDBUS_VPP_VCC":
1169 (command & CARDBUS_VPPMASK) == CARDBUS_VPP_0V ? "CARDBUS_VPP_0V" :
1170 "UNKNOWN",
1171 command));
1172 #if 0
1173 if (command == (CARDBUS_VCC_0V | CARDBUS_VPP_0V)) {
1174 u_int32_t force = bus_space_read_4(memt, memh, CB_SOCKET_FORCE);
1175 /* Reset Bad Vcc request */
1176 force &= ~CB_SOCKET_FORCE_BADVCC;
1177 bus_space_write_4(memt, memh, CB_SOCKET_FORCE, force);
1178 printf("new status 0x%x\n", bus_space_read_4(memt, memh,CB_SOCKET_STAT));
1179 return 1;
1180 }
1181 #endif
1182 return 0;
1183 }
1184 return 1; /* power changed correctly */
1185 }
1186
1187
1188
1189
1190
1191
1192 #if defined CB_PCMCIA_POLL
1193 struct cb_poll_str {
1194 void *arg;
1195 int (* func) __P((void *));
1196 int level;
1197 pccard_chipset_tag_t ct;
1198 int count;
1199 };
1200
1201 static struct cb_poll_str cb_poll[10];
1202 static int cb_poll_n = 0;
1203
1204 static void cb_pcmcia_poll __P((void *arg));
1205
1206 static void
1207 cb_pcmcia_poll(arg)
1208 void *arg;
1209 {
1210 struct cb_poll_str *poll = arg;
1211 struct cbb_pcmcia_softc *psc = (void *)poll->ct->v;
1212 struct pccbb_softc *sc = psc->cpc_parent;
1213 int s;
1214 u_int32_t spsr; /* socket present-state reg */
1215
1216 timeout(cb_pcmcia_poll, arg, hz/10);
1217 switch (poll->level) {
1218 case IPL_NET:
1219 s = splnet();
1220 break;
1221 case IPL_BIO:
1222 s = splbio();
1223 break;
1224 case IPL_TTY: /* fallthrough */
1225 default:
1226 s = spltty();
1227 break;
1228 }
1229
1230 spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
1231
1232 #if defined CB_PCMCIA_POLL_ONLY && defined LEVEL2
1233 if (!(spsr & 0x40)) { /* CINT low */
1234 #else
1235 if (1) {
1236 #endif
1237 if ((*poll->func)(poll->arg) == 1) {
1238 ++poll->count;
1239 printf("intr: reported from poller, 0x%x\n", spsr);
1240 #if defined LEVEL2
1241 } else {
1242 printf("intr: miss! 0x%x\n", spsr);
1243 #endif
1244 }
1245 }
1246 splx(s);
1247 }
1248 #endif /* defined CB_PCMCIA_POLL */
1249
1250
1251
1252
1253 /*
1254 * static int pccbb_detect_card(struct pccbb_softc *sc)
1255 * return value: 0 if no card exists.
1256 * 1 if 16-bit card exists.
1257 * 2 if cardbus card exists.
1258 */
1259 static int
1260 pccbb_detect_card(sc)
1261 struct pccbb_softc *sc;
1262 {
1263 bus_space_handle_t base_memh = sc->sc_base_memh;
1264 bus_space_tag_t base_memt = sc->sc_base_memt;
1265 u_int32_t sockstat = bus_space_read_4(base_memt,base_memh, CB_SOCKET_STAT);
1266 int retval = 0;
1267
1268 if (0x00 == (sockstat & CB_SOCKET_STAT_CD)) { /* CD1 and CD2 asserted */
1269 /* card must be present */
1270 if (!(CB_SOCKET_STAT_NOTCARD & sockstat)) { /* NOTACARD DEASSERTED */
1271 if (CB_SOCKET_STAT_CB & sockstat) { /* CardBus mode */
1272 retval = 2;
1273 } else if (CB_SOCKET_STAT_16BIT & sockstat) { /* 16-bit mode */
1274 retval = 1;
1275 }
1276 }
1277 }
1278 return retval;
1279 }
1280
1281
1282
1283
1284 /*
1285 * STATIC int cb_reset(struct pccbb_softc *sc)
1286 * This function resets CardBus card.
1287 */
1288 STATIC int
1289 cb_reset(sc)
1290 struct pccbb_softc *sc;
1291 {
1292 /*
1293 * Reset Assert at least 20 ms
1294 * Some machines request longer duration.
1295 */
1296 int reset_duration = (sc->sc_chipset == CB_RX5C47X ? 400*1000 : 40*1000);
1297 u_int32_t bcr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR);
1298
1299 bcr |= (0x40 << 16); /* Reset bit Assert (bit 6 at 0x3E) */
1300 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, bcr);
1301 delay(reset_duration);
1302
1303 if (CBB_CARDEXIST & sc->sc_flags) { /* A card exists. Reset it! */
1304 bcr &= ~(0x40 << 16); /* Reset bit Deassert (bit 6 at 0x3E) */
1305 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_BCR_INTR, bcr);
1306 delay(reset_duration);
1307 }
1308 /* No card found on the slot. Keep Reset. */
1309 return 1;
1310 }
1311
1312
1313
1314
1315 /*
1316 * STATIC int cb_detect_voltage(struct pccbb_softc *sc)
1317 * This function detect card Voltage.
1318 */
1319 STATIC int
1320 cb_detect_voltage(sc)
1321 struct pccbb_softc *sc;
1322 {
1323 u_int32_t psr; /* socket present-state reg */
1324 bus_space_tag_t iot = sc->sc_base_memt;
1325 bus_space_handle_t ioh = sc->sc_base_memh;
1326 int vol = PCCARD_VCC_UKN; /* set 0 */
1327
1328 psr = bus_space_read_4(iot, ioh, CB_SOCKET_STAT);
1329
1330 if (0x400u & psr) {
1331 vol |= PCCARD_VCC_5V;
1332 }
1333 if (0x800u & psr) {
1334 vol |= PCCARD_VCC_3V;
1335 }
1336
1337 return vol;
1338 }
1339
1340
1341
1342
1343
1344
1345 STATIC int
1346 cbbprint(aux, pcic)
1347 void *aux;
1348 const char *pcic;
1349 {
1350 /*
1351 struct cbslot_attach_args *cba = aux;
1352
1353 if (cba->cba_slot >= 0) {
1354 printf(" slot %d", cba->cba_slot);
1355 }
1356 */
1357 return UNCONF;
1358 }
1359
1360
1361
1362
1363 /*
1364 * STATIC int pccbb_cardenable(struct pccbb_softc *sc, int function)
1365 * This function enables and disables the card
1366 */
1367 STATIC int
1368 pccbb_cardenable(sc, function)
1369 struct pccbb_softc *sc;
1370 int function;
1371 {
1372 u_int32_t command = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
1373
1374 DPRINTF(("pccbb_cardenable:"));
1375 switch (function) {
1376 case CARDBUS_IO_ENABLE:
1377 command |= PCI_COMMAND_IO_ENABLE;
1378 break;
1379 case CARDBUS_IO_DISABLE:
1380 command &= ~PCI_COMMAND_IO_ENABLE;
1381 break;
1382 case CARDBUS_MEM_ENABLE:
1383 command |= PCI_COMMAND_MEM_ENABLE;
1384 break;
1385 case CARDBUS_MEM_DISABLE:
1386 command &= ~PCI_COMMAND_MEM_ENABLE;
1387 break;
1388 case CARDBUS_BM_ENABLE:
1389 command |= PCI_COMMAND_MASTER_ENABLE;
1390 break;
1391 case CARDBUS_BM_DISABLE:
1392 command &= ~PCI_COMMAND_MASTER_ENABLE;
1393 break;
1394 default:
1395 return 0;
1396 }
1397
1398 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, command);
1399 DPRINTF((" command reg 0x%x\n", command));
1400 return 1;
1401 }
1402
1403
1404
1405
1406
1407
1408 #if !rbus
1409 /*
1410 * int pccbb_io_open(cardbus_chipset_tag_t, int, u_int32_t, u_int32_t)
1411 */
1412 static int
1413 pccbb_io_open(ct, win, start, end)
1414 cardbus_chipset_tag_t ct;
1415 int win;
1416 u_int32_t start, end;
1417 {
1418 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1419 int basereg;
1420 int limitreg;
1421
1422 if ((win < 0) || (win > 2)) {
1423 #if defined DIAGNOSTIC
1424 printf("cardbus_io_open: window out of range %d\n", win);
1425 #endif
1426 return 0;
1427 }
1428
1429 basereg = win*8 + 0x2c;
1430 limitreg = win*8 + 0x30;
1431
1432 DPRINTF(("pccbb_io_open: 0x%x[0x%x] - 0x%x[0x%x]\n",
1433 start, basereg, end, limitreg));
1434
1435 pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, start);
1436 pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, end);
1437 return 1;
1438 }
1439
1440 /*
1441 * int pccbb_io_close(cardbus_chipset_tag_t, int)
1442 */
1443 static int
1444 pccbb_io_close(ct, win)
1445 cardbus_chipset_tag_t ct;
1446 int win;
1447 {
1448 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1449 int basereg;
1450 int limitreg;
1451
1452 if ((win < 0) || (win > 2)) {
1453 #if defined DIAGNOSTIC
1454 printf("cardbus_io_close: window out of range %d\n", win);
1455 #endif
1456 return 0;
1457 }
1458
1459 basereg = win*8 + 0x2c;
1460 limitreg = win*8 + 0x30;
1461
1462 pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, 0);
1463 pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, 0);
1464 return 1;
1465 }
1466
1467 /*
1468 * int pccbb_mem_open(cardbus_chipset_tag_t, int, u_int32_t, u_int32_t)
1469 */
1470 static int
1471 pccbb_mem_open(ct, win, start, end)
1472 cardbus_chipset_tag_t ct;
1473 int win;
1474 u_int32_t start, end;
1475 {
1476 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1477 int basereg;
1478 int limitreg;
1479
1480 if ((win < 0) || (win > 2)) {
1481 #if defined DIAGNOSTIC
1482 printf("cardbus_mem_open: window out of range %d\n", win);
1483 #endif
1484 return 0;
1485 }
1486
1487 basereg = win*8 + 0x1c;
1488 limitreg = win*8 + 0x20;
1489
1490 pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, start);
1491 pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, end);
1492 return 1;
1493 }
1494
1495
1496 /*
1497 * int pccbb_mem_close(cardbus_chipset_tag_t, int)
1498 */
1499 static int
1500 pccbb_mem_close(ct, win)
1501 cardbus_chipset_tag_t ct;
1502 int win;
1503 {
1504 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1505 int basereg;
1506 int limitreg;
1507
1508 if ((win < 0) || (win > 2)) {
1509 #if defined DIAGNOSTIC
1510 printf("cardbus_mem_close: window out of range %d\n", win);
1511 #endif
1512 return 0;
1513 }
1514
1515 basereg = win*8 + 0x1c;
1516 limitreg = win*8 + 0x20;
1517
1518 pci_conf_write(sc->sc_pc, sc->sc_tag, basereg, 0);
1519 pci_conf_write(sc->sc_pc, sc->sc_tag, limitreg, 0);
1520 return 1;
1521 }
1522 #endif
1523
1524
1525
1526 static void *
1527 pccbb_intr_establish(ct, irq, level, func, arg)
1528 cardbus_chipset_tag_t ct;
1529 int irq, level;
1530 int (* func) __P((void *));
1531 void *arg;
1532 {
1533 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1534
1535 switch (sc->sc_chipset) {
1536 case CB_TI113X:
1537 {
1538 pcireg_t cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
1539 cbctrl |= PCI113X_CBCTRL_PCI_INTR; /* functional intr enabled */
1540 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
1541 }
1542 break;
1543 default:
1544 break;
1545 }
1546
1547 return pci_intr_establish(sc->sc_pc, irq, level, func, arg);
1548 }
1549
1550
1551
1552
1553 static void
1554 pccbb_intr_disestablish(ct, ih)
1555 cardbus_chipset_tag_t ct;
1556 void *ih;
1557 {
1558 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
1559
1560 switch (sc->sc_chipset) {
1561 case CB_TI113X:
1562 {
1563 pcireg_t cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
1564 cbctrl &= ~PCI113X_CBCTRL_PCI_INTR; /* functional intr disabled */
1565 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
1566 }
1567 break;
1568 default:
1569 break;
1570 }
1571
1572 pci_intr_disestablish(sc->sc_pc, ih);
1573 }
1574
1575
1576
1577
1578
1579 #if defined SHOW_REGS
1580 static void
1581 cb_show_regs(pc, tag, memt, memh)
1582 pci_chipset_tag_t pc;
1583 pcitag_t tag;
1584 bus_space_tag_t memt;
1585 bus_space_handle_t memh;
1586 {
1587 int i;
1588 printf("PCI config regs:");
1589 for (i = 0; i < 0x50; i += 4) {
1590 if (i % 16 == 0) {
1591 printf("\n 0x%02x:", i);
1592 }
1593 printf(" %08x", pci_conf_read(pc, tag, i));
1594 }
1595 for (i = 0x80; i < 0xb0; i += 4) {
1596 if (i % 16 == 0) {
1597 printf("\n 0x%02x:", i);
1598 }
1599 printf(" %08x", pci_conf_read(pc, tag, i));
1600 }
1601
1602 if (memh == 0) {
1603 printf("\n");
1604 return;
1605 }
1606
1607 printf("\nsocket regs:");
1608 for (i = 0; i <= 0x10; i += 0x04) {
1609 printf(" %08x", bus_space_read_4(memt, memh, i));
1610 }
1611 printf("\nExCA regs:");
1612 for (i = 0; i < 0x08; ++i) {
1613 printf(" %02x", bus_space_read_1(memt, memh, 0x800 + i));
1614 }
1615 printf("\n");
1616 return;
1617 }
1618 #endif
1619
1620
1621
1622 /*
1623 * static cardbustag_t pccbb_make_tag(cardbus_chipset_tag_t cc,
1624 * int busno, int devno, int function)
1625 * This is the function to make a tag to access config space of
1626 * a CardBus Card. It works same as pci_conf_read.
1627 */
1628 static cardbustag_t
1629 pccbb_make_tag(cc, busno, devno, function)
1630 cardbus_chipset_tag_t cc;
1631 int busno, devno, function;
1632 {
1633 struct pccbb_softc *sc = (struct pccbb_softc *)cc;
1634
1635 return pci_make_tag(sc->sc_pc, busno, devno, function);
1636 }
1637
1638
1639 static void
1640 pccbb_free_tag(cc, tag)
1641 cardbus_chipset_tag_t cc;
1642 cardbustag_t tag;
1643 {
1644 }
1645
1646
1647 /*
1648 * static cardbusreg_t pccbb_conf_read(cardbus_chipset_tag_t cc,
1649 * cardbustag_t tag, int offset)
1650 * This is the function to read the config space of a CardBus Card.
1651 * It works same as pci_conf_read.
1652 */
1653 static cardbusreg_t
1654 pccbb_conf_read(cc, tag, offset)
1655 cardbus_chipset_tag_t cc;
1656 cardbustag_t tag;
1657 int offset; /* register offset */
1658 {
1659 struct pccbb_softc *sc = (struct pccbb_softc *)cc;
1660
1661 return pci_conf_read(sc->sc_pc, tag, offset);
1662 }
1663
1664
1665
1666 /*
1667 * static void pccbb_conf_write(cardbus_chipset_tag_t cc, cardbustag_t tag,
1668 * int offs, cardbusreg_t val)
1669 * This is the function to write the config space of a CardBus Card.
1670 * It works same as pci_conf_write.
1671 */
1672 static void
1673 pccbb_conf_write(cc, tag, reg, val)
1674 cardbus_chipset_tag_t cc;
1675 cardbustag_t tag;
1676 int reg; /* register offset */
1677 cardbusreg_t val;
1678 {
1679 struct pccbb_softc *sc = (struct pccbb_softc *)cc;
1680
1681 pci_conf_write(sc->sc_pc, tag, reg, val);
1682 }
1683
1684
1685
1686
1687
1688 #if 0
1689 STATIC int
1690 pccbb_new_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
1691 bus_addr_t start, bus_size_t size,
1692 bus_size_t align, bus_addr_t mask, /* address line width */
1693 int speed, int flags, /* bus width */
1694 bus_space_handle_t *iohp)
1695 #endif
1696
1697
1698 /*
1699 * STATIC int pccbb_pcmcia_io_alloc(pcmcia_chipset_handle_t pch,
1700 * bus_addr_t start, bus_size_t size,
1701 * bus_size_t align,
1702 * struct pcmcia_io_handle *pcihp
1703 *
1704 * This function only allocates I/O region for pccard. This function
1705 * never maps the allcated region to pccard I/O area.
1706 *
1707 * XXX: The interface of this function is not very good, I believe.
1708 */
1709 STATIC int
1710 pccbb_pcmcia_io_alloc(pch, start, size, align, pcihp)
1711 pcmcia_chipset_handle_t pch;
1712 bus_addr_t start; /* start address */
1713 bus_size_t size;
1714 bus_size_t align;
1715 struct pcmcia_io_handle *pcihp;
1716 {
1717 struct pcic_handle *ph = (struct pcic_handle *)pch;
1718 bus_addr_t ioaddr;
1719 int flags = 0;
1720 bus_space_tag_t iot;
1721 bus_space_handle_t ioh;
1722 #if rbus
1723 rbus_tag_t rb;
1724 #endif
1725 if (align == 0) {
1726 align = size; /* XXX: funny??? */
1727 }
1728
1729
1730 /*
1731 * Allocate some arbitrary I/O space.
1732 */
1733
1734 iot = ((struct pccbb_softc *)(ph->ph_parent))->sc_iot;
1735
1736 #if rbus
1737 rb = ((struct pccbb_softc *)(ph->ph_parent))->sc_rbus_iot;
1738 if (rbus_space_alloc(rb, start, size, 0x3ff /* XXX: I assume all card decode lower 10 bits by its hardware */,
1739 align, 0, &ioaddr, &ioh)) {
1740 return 1;
1741 }
1742 #else
1743 if (start) {
1744 ioaddr = start;
1745 if (bus_space_map(iot, start, size, 0, &ioh)) {
1746 return 1;
1747 }
1748 DPRINTF(("pccbb_pcmcia_io_alloc map port %lx+%lx\n",
1749 (u_long) ioaddr, (u_long) size));
1750 } else {
1751 flags |= PCMCIA_IO_ALLOCATED;
1752 if (bus_space_alloc(iot, 0x700/* ph->sc->sc_iobase */,
1753 0x800/* ph->sc->sc_iobase + ph->sc->sc_iosize*/,
1754 size, align, 0, 0, &ioaddr, &ioh)) {
1755 /* No room be able to be get. */
1756 return 1;
1757 }
1758 DPRINTF(("pccbb_pcmmcia_io_alloc alloc port 0x%lx+0x%lx\n",
1759 (u_long) ioaddr, (u_long) size));
1760 }
1761 #endif
1762
1763 pcihp->iot = iot;
1764 pcihp->ioh = ioh;
1765 pcihp->addr = ioaddr;
1766 pcihp->size = size;
1767 pcihp->flags = flags;
1768
1769 return 0;
1770 }
1771
1772
1773
1774
1775
1776 /*
1777 * STATIC int pccbb_pcmcia_io_free(pcmcia_chipset_handle_t pch,
1778 * struct pcmcia_io_handle *pcihp)
1779 *
1780 * This function only frees I/O region for pccard.
1781 *
1782 * XXX: The interface of this function is not very good, I believe.
1783 */
1784 void
1785 pccbb_pcmcia_io_free(pch, pcihp)
1786 pcmcia_chipset_handle_t pch;
1787 struct pcmcia_io_handle *pcihp;
1788 {
1789 #if !rbus
1790 bus_space_tag_t iot = pcihp->iot;
1791 #endif
1792 bus_space_handle_t ioh = pcihp->ioh;
1793 bus_size_t size = pcihp->size;
1794
1795 #if rbus
1796 struct pccbb_softc *sc = (struct pccbb_softc *)((struct pcic_handle *)pch)->ph_parent;
1797 rbus_tag_t rb = sc->sc_rbus_iot;
1798
1799 rbus_space_free(rb, ioh, size, NULL);
1800 #else
1801 if (pcihp->flags & PCMCIA_IO_ALLOCATED)
1802 bus_space_free(iot, ioh, size);
1803 else
1804 bus_space_unmap(iot, ioh, size);
1805 #endif
1806 }
1807
1808
1809
1810 /*
1811 * STATIC int pccbb_pcmcia_io_map(pcmcia_chipset_handle_t pch, int width,
1812 * bus_addr_t offset, bus_size_t size,
1813 * struct pcmcia_io_handle *pcihp,
1814 * int *windowp)
1815 *
1816 * This function maps the allocated I/O region to pccard. This function
1817 * never allocates any I/O region for pccard I/O area. I don't
1818 * understand why the original authors of pcmciabus separated alloc and
1819 * map. I believe the two must be unite.
1820 *
1821 * XXX: no wait timing control?
1822 */
1823 int
1824 pccbb_pcmcia_io_map(pch, width, offset, size, pcihp, windowp)
1825 pcmcia_chipset_handle_t pch;
1826 int width;
1827 bus_addr_t offset;
1828 bus_size_t size;
1829 struct pcmcia_io_handle *pcihp;
1830 int *windowp;
1831 {
1832 struct pcic_handle *ph = (struct pcic_handle *) pch;
1833 bus_addr_t ioaddr = pcihp->addr + offset;
1834 int i, win;
1835 #if defined CBB_DEBUG
1836 static char *width_names[] = { "dynamic", "io8", "io16" };
1837 #endif
1838
1839 /* Sanity check I/O handle. */
1840
1841 if (((struct pccbb_softc *)ph->ph_parent)->sc_iot != pcihp->iot) {
1842 panic("pccbb_pcmcia_io_map iot is bogus");
1843 }
1844
1845 /* XXX Sanity check offset/size. */
1846
1847 win = -1;
1848 for (i = 0; i < PCIC_IO_WINS; i++) {
1849 if ((ph->ioalloc & (1 << i)) == 0) {
1850 win = i;
1851 ph->ioalloc |= (1 << i);
1852 break;
1853 }
1854 }
1855
1856 if (win == -1) {
1857 return 1;
1858 }
1859
1860 *windowp = win;
1861
1862 /* XXX this is pretty gross */
1863
1864 DPRINTF(("pccbb_pcmcia_io_map window %d %s port %lx+%lx\n",
1865 win, width_names[width], (u_long) ioaddr, (u_long) size));
1866
1867 /* XXX wtf is this doing here? */
1868
1869 #if 0
1870 printf(" port 0x%lx", (u_long) ioaddr);
1871 if (size > 1) {
1872 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
1873 }
1874 #endif
1875
1876 ph->io[win].addr = ioaddr;
1877 ph->io[win].size = size;
1878 ph->io[win].width = width;
1879
1880 /* actual dirty register-value changing in the function below. */
1881 pccbb_pcmcia_do_io_map(ph, win);
1882
1883 return 0;
1884 }
1885
1886
1887
1888 /*
1889 * STATIC void pccbb_pcmcia_do_io_map(struct pcic_handle *h, int win)
1890 *
1891 * This function changes register-value to map I/O region for pccard.
1892 */
1893 static void
1894 pccbb_pcmcia_do_io_map(ph, win)
1895 struct pcic_handle *ph;
1896 int win;
1897 {
1898 static u_int8_t pcic_iowidth[3] = {
1899 PCIC_IOCTL_IO0_IOCS16SRC_CARD,
1900 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_8BIT,
1901 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_16BIT,
1902 };
1903
1904 #define PCIC_SIA_START_LOW 0
1905 #define PCIC_SIA_START_HIGH 1
1906 #define PCIC_SIA_STOP_LOW 2
1907 #define PCIC_SIA_STOP_HIGH 3
1908
1909 int regbase_win = 0x8 + win*0x04;
1910 u_int8_t ioctl, enable;
1911
1912 DPRINTF(("pccbb_pcmcia_do_io_map win %d addr 0x%lx size 0x%lx width %d\n",
1913 win, (long) ph->io[win].addr, (long) ph->io[win].size,
1914 ph->io[win].width * 8));
1915
1916 Pcic_write(ph, regbase_win + PCIC_SIA_START_LOW,
1917 ph->io[win].addr & 0xff);
1918 Pcic_write(ph, regbase_win + PCIC_SIA_START_HIGH,
1919 (ph->io[win].addr >> 8) & 0xff);
1920
1921 Pcic_write(ph, regbase_win + PCIC_SIA_STOP_LOW,
1922 (ph->io[win].addr + ph->io[win].size - 1) & 0xff);
1923 Pcic_write(ph, regbase_win + PCIC_SIA_STOP_HIGH,
1924 ((ph->io[win].addr + ph->io[win].size - 1) >> 8) & 0xff);
1925
1926 ioctl = Pcic_read(ph, PCIC_IOCTL);
1927 enable = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
1928 switch (win) {
1929 case 0:
1930 ioctl &= ~(PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
1931 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK);
1932 ioctl |= pcic_iowidth[ph->io[win].width];
1933 enable |= PCIC_ADDRWIN_ENABLE_IO0;
1934 break;
1935 case 1:
1936 ioctl &= ~(PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
1937 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK);
1938 ioctl |= (pcic_iowidth[ph->io[win].width] << 4);
1939 enable |= PCIC_ADDRWIN_ENABLE_IO1;
1940 break;
1941 }
1942 Pcic_write(ph, PCIC_IOCTL, ioctl);
1943 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, enable);
1944 #if defined CBB_DEBUG
1945 {
1946 u_int8_t start_low = Pcic_read(ph, regbase_win + PCIC_SIA_START_LOW);
1947 u_int8_t start_high = Pcic_read(ph, regbase_win + PCIC_SIA_START_HIGH);
1948 u_int8_t stop_low = Pcic_read(ph, regbase_win + PCIC_SIA_STOP_LOW);
1949 u_int8_t stop_high = Pcic_read(ph, regbase_win + PCIC_SIA_STOP_HIGH);
1950 printf(" start %02x %02x, stop %02x %02x, ioctl %02x enable %02x\n",
1951 start_low, start_high, stop_low, stop_high, ioctl, enable);
1952 }
1953 #endif
1954 }
1955
1956
1957
1958 /*
1959 * STATIC void pccbb_pcmcia_io_unmap(pcmcia_chipset_handle_t *h, int win)
1960 *
1961 * This function unmapss I/O region. No return value.
1962 */
1963 STATIC void
1964 pccbb_pcmcia_io_unmap(pch, win)
1965 pcmcia_chipset_handle_t pch;
1966 int win;
1967 {
1968 struct pcic_handle *ph = (struct pcic_handle *)pch;
1969 int reg;
1970
1971 if (win >= PCIC_IO_WINS || win < 0) {
1972 panic("pccbb_pcmcia_io_unmap: window out of range");
1973 }
1974
1975 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
1976 switch (win) {
1977 case 0:
1978 reg &= ~PCIC_ADDRWIN_ENABLE_IO0;
1979 break;
1980 case 1:
1981 reg &= ~PCIC_ADDRWIN_ENABLE_IO1;
1982 break;
1983 }
1984 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
1985
1986 ph->ioalloc &= ~(1 << win);
1987 }
1988
1989
1990
1991
1992
1993 /*
1994 * static void pccbb_pcmcia_wait_ready(struct pcic_handle *ph)
1995 *
1996 * This function enables the card. All information is stored in
1997 * the first argument, pcmcia_chipset_handle_t.
1998 */
1999 static void
2000 pccbb_pcmcia_wait_ready(ph)
2001 struct pcic_handle *ph;
2002 {
2003 int i;
2004
2005 DPRINTF(("pccbb_pcmcia_wait_ready: status 0x%02x\n",
2006 Pcic_read(ph, PCIC_IF_STATUS)));
2007
2008 for (i = 0; i < 10000; i++) {
2009 if (Pcic_read(ph, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY) {
2010 return;
2011 }
2012 delay(500);
2013 #ifdef CBB_DEBUG
2014 if ((i > 5000) && (i%100 == 99))
2015 printf(".");
2016 #endif
2017 }
2018
2019 #ifdef DIAGNOSTIC
2020 printf("pcic_wait_ready: ready never happened, status = %02x\n",
2021 Pcic_read(ph, PCIC_IF_STATUS));
2022 #endif
2023 }
2024
2025
2026
2027 /*
2028 * STATIC void pccbb_pcmcia_socket_enable(pcmcia_chipset_handle_t pch)
2029 *
2030 * This function enables the card. All information is stored in
2031 * the first argument, pcmcia_chipset_handle_t.
2032 */
2033 STATIC void
2034 pccbb_pcmcia_socket_enable(pch)
2035 pcmcia_chipset_handle_t pch;
2036 {
2037 struct pcic_handle *ph = (struct pcic_handle *)pch;
2038 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2039 int cardtype, win;
2040 u_int8_t power, intr;
2041 pcireg_t spsr;
2042 int voltage;
2043 #define PCIC_INTR_PCI PCIC_INTR_ENABLE
2044
2045 /* this bit is mostly stolen from pcic_attach_card */
2046
2047 DPRINTF(("pccbb_pcmcia_socket_enable: "));
2048
2049 /* get card Vcc info */
2050
2051 spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
2052 if (spsr & CB_SOCKET_STAT_5VCARD) {
2053 DPRINTF(("5V card\n"));
2054 voltage = CARDBUS_VCC_5V | CARDBUS_VPP_VCC;
2055 } else if (spsr & CB_SOCKET_STAT_3VCARD) {
2056 DPRINTF(("3V card\n"));
2057 voltage = CARDBUS_VCC_3V | CARDBUS_VPP_VCC;
2058 } else {
2059 printf("?V card, 0x%x\n", spsr); /* XXX */
2060 return;
2061 }
2062
2063 /* assert reset bit */
2064
2065 intr = Pcic_read(ph, PCIC_INTR);
2066 intr &= ~PCIC_INTR_RESET;
2067 intr |= PCIC_INTR_PCI; /* XXX */
2068 Pcic_write(ph, PCIC_INTR, intr);
2069
2070 /* disable socket i/o: negate output enable bit */
2071
2072 power = Pcic_read(ph, PCIC_PWRCTL);
2073 power &= ~PCIC_PWRCTL_OE;
2074 Pcic_write(ph, PCIC_PWRCTL, power);
2075
2076 /* power down the socket to reset it, clear the card reset pin */
2077
2078 pccbb_power(sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
2079
2080 /*
2081 * wait 200ms until power fails (Tpf). Then, wait 100ms since
2082 * we are changing Vcc (Toff).
2083 */
2084 /* delay(300*1000); too much */
2085
2086 /* power up the socket */
2087 pccbb_power(sc, voltage);
2088
2089 /*
2090 * wait 100ms until power raise (Tpr) and 20ms to become
2091 * stable (Tsu(Vcc)).
2092 *
2093 * some machines require some more time to be settled
2094 * (another 200ms is added here).
2095 */
2096 /* delay((100 + 20 + 200)*1000); too much */
2097
2098 power = Pcic_read(ph, PCIC_PWRCTL);
2099 Pcic_write(ph, PCIC_PWRCTL, power | PCIC_PWRCTL_OE);
2100
2101 /*
2102 * hold RESET at least 10us.
2103 */
2104 delay(10);
2105 delay(2*1000); /* XXX: TI1130 requires it. */
2106 delay(20*1000); /* XXX: TI1130 requires it. */
2107
2108 /* clear the reset flag */
2109
2110 intr = Pcic_read(ph, PCIC_INTR);
2111 Pcic_write(ph, PCIC_INTR, intr | PCIC_INTR_RESET);
2112
2113 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
2114
2115 delay(20000);
2116
2117 /* wait for the chip to finish initializing */
2118
2119 pccbb_pcmcia_wait_ready(ph);
2120
2121 /* zero out the address windows */
2122
2123 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, 0);
2124
2125 /* set the card type */
2126
2127 cardtype = pcmcia_card_gettype(ph->pcmcia);
2128
2129 intr = Pcic_read(ph, PCIC_INTR);
2130 intr &= ~PCIC_INTR_CARDTYPE_MASK;
2131 intr |= ((cardtype == PCMCIA_IFTYPE_IO) ?
2132 PCIC_INTR_CARDTYPE_IO :
2133 PCIC_INTR_CARDTYPE_MEM);
2134 Pcic_write(ph, PCIC_INTR, intr);
2135
2136 DPRINTF(("%s: pccbb_pcmcia_socket_enable %02x cardtype %s %02x\n",
2137 ph->ph_parent->dv_xname, ph->sock,
2138 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), intr));
2139
2140 /* reinstall all the memory and io mappings */
2141
2142 for (win = 0; win < PCIC_MEM_WINS; ++win) {
2143 if (ph->memalloc & (1 << win)) {
2144 pccbb_pcmcia_do_mem_map(ph, win);
2145 }
2146 }
2147
2148 for (win = 0; win < PCIC_IO_WINS; ++win) {
2149 if (ph->ioalloc & (1 << win)) {
2150 pccbb_pcmcia_do_io_map(ph, win);
2151 }
2152 }
2153 }
2154
2155
2156
2157 /*
2158 * STATIC void pccbb_pcmcia_socket_disable(pcmcia_chipset_handle_t *ph)
2159 *
2160 * This function disables the card. All information is stored in
2161 * the first argument, pcmcia_chipset_handle_t.
2162 */
2163 STATIC void
2164 pccbb_pcmcia_socket_disable(pch)
2165 pcmcia_chipset_handle_t pch;
2166 {
2167 struct pcic_handle *ph = (struct pcic_handle *)pch;
2168 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2169 u_int8_t power, intr;
2170
2171 DPRINTF(("pccbb_pcmcia_socket_disable\n"));
2172
2173 /* reset signal asserting... */
2174
2175 intr = Pcic_read(ph, PCIC_INTR);
2176 intr &= ~PCIC_INTR_RESET;
2177 Pcic_write(ph, PCIC_INTR, intr);
2178 delay(2*1000);
2179
2180 /* power down the socket */
2181 power = Pcic_read(ph, PCIC_PWRCTL);
2182 power &= ~PCIC_PWRCTL_OE;
2183 Pcic_write(ph, PCIC_PWRCTL, power);
2184 pccbb_power(sc, CARDBUS_VCC_0V | CARDBUS_VPP_0V);
2185 /*
2186 * wait 300ms until power fails (Tpf).
2187 */
2188 delay(300 * 1000);
2189 }
2190
2191
2192
2193 /*
2194 * STATIC int pccbb_pcmcia_card_detect(pcmcia_chipset_handle_t *ph)
2195 *
2196 * This function detects whether a card is in the slot or not.
2197 * If a card is inserted, return 1. Otherwise, return 0.
2198 */
2199 STATIC int
2200 pccbb_pcmcia_card_detect(pch)
2201 pcmcia_chipset_handle_t pch;
2202 {
2203 struct pcic_handle *ph = (struct pcic_handle *)pch;
2204 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2205
2206 DPRINTF(("pccbb_pcmcia_card_detect\n"));
2207 return pccbb_detect_card(sc) == 1 ? 1 : 0;
2208 }
2209
2210
2211
2212 #if 0
2213 STATIC int
2214 pccbb_new_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
2215 bus_addr_t start, bus_size_t size,
2216 bus_size_t align,
2217 int speed, int flags, /* bus width */
2218 bus_space_tag_t *memtp
2219 bus_space_handle_t *memhp)
2220 #endif
2221
2222
2223 /*
2224 * STATIC int pccbb_pcmcia_mem_alloc(pcmcia_chipset_handle_t pch,
2225 * bus_size_t size,
2226 * struct pcmcia_mem_handle *pcmhp)
2227 *
2228 * This function only allocates memory region for pccard. This
2229 * function never maps the allcated region to pccard memory area.
2230 *
2231 * XXX: Why the argument of start address is not in?
2232 */
2233 STATIC int
2234 pccbb_pcmcia_mem_alloc(pch, size, pcmhp)
2235 pcmcia_chipset_handle_t pch;
2236 bus_size_t size;
2237 struct pcmcia_mem_handle *pcmhp;
2238 {
2239 struct pcic_handle *ph = (struct pcic_handle *)pch;
2240 bus_space_handle_t memh;
2241 bus_addr_t addr;
2242 bus_size_t sizepg;
2243 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2244 #if rbus
2245 rbus_tag_t rb;
2246 #endif
2247
2248 /* out of sc->memh, allocate as many pages as necessary */
2249
2250 /* convert size to PCIC pages */
2251 /*
2252 This is not enough; when the requested region is on the
2253 page boundaries, this may calculate wrong result.
2254 */
2255 sizepg = (size + (PCIC_MEM_PAGESIZE - 1)) / PCIC_MEM_PAGESIZE;
2256 #if 0
2257 if (sizepg > PCIC_MAX_MEM_PAGES) {
2258 return 1;
2259 }
2260 #endif
2261
2262 if (!(sc->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32)) {
2263 return 1;
2264 }
2265
2266 addr = 0; /* XXX gcc -Wuninitialized */
2267
2268 #if rbus
2269 rb = sc->sc_rbus_memt;
2270 if (rbus_space_alloc(rb, 0, sizepg*PCIC_MEM_PAGESIZE,
2271 sizepg*PCIC_MEM_PAGESIZE - 1, PCIC_MEM_PAGESIZE,
2272 0, &addr, &memh)) {
2273 return 1;
2274 }
2275
2276 #else
2277 if (bus_space_alloc(sc->sc_memt, sc->sc_mem_start, sc->sc_mem_end,
2278 sizepg*PCIC_MEM_PAGESIZE, PCIC_MEM_PAGESIZE,
2279 0 /* boundary */, 0 /* flags */,
2280 &addr, &memh)) {
2281 return 1;
2282 }
2283 #endif
2284
2285 DPRINTF(("pccbb_pcmcia_alloc_mem: addr 0x%lx size 0x%lx, realsize 0x%lx\n",
2286 addr, size, sizepg*PCIC_MEM_PAGESIZE));
2287
2288 pcmhp->memt = sc->sc_memt;
2289 pcmhp->memh = memh;
2290 pcmhp->addr = addr;
2291 pcmhp->size = size;
2292 pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
2293 /* What is mhandle? I feel it is very dirty and it must go trush. */
2294 pcmhp->mhandle = 0;
2295 /* No offset??? Funny. */
2296
2297 return 0;
2298 }
2299
2300
2301
2302
2303 /*
2304 * STATIC void pccbb_pcmcia_mem_free(pcmcia_chipset_handle_t pch,
2305 * struct pcmcia_mem_handle *pcmhp)
2306 *
2307 * This function release the memory space allocated by the fuction
2308 * pccbb_pcmcia_mem_alloc().
2309 */
2310 STATIC void
2311 pccbb_pcmcia_mem_free(pch, pcmhp)
2312 pcmcia_chipset_handle_t pch;
2313 struct pcmcia_mem_handle *pcmhp;
2314 {
2315 #if rbus
2316 struct pcic_handle *ph = (struct pcic_handle *)pch;
2317 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2318
2319 rbus_space_free(sc->sc_rbus_memt, pcmhp->memh, pcmhp->realsize, NULL);
2320 #else
2321 bus_space_free(pcmhp->memt, pcmhp->memh, pcmhp->realsize);
2322 #endif
2323 }
2324
2325
2326
2327
2328 /*
2329 * STATIC void pccbb_pcmcia_do_mem_map(struct pcic_handle *ph, int win)
2330 *
2331 * This function release the memory space allocated by the fuction
2332 * pccbb_pcmcia_mem_alloc().
2333 */
2334 STATIC void
2335 pccbb_pcmcia_do_mem_map(ph, win)
2336 struct pcic_handle *ph;
2337 int win;
2338 {
2339 int regbase_win;
2340 bus_addr_t phys_addr;
2341 bus_addr_t phys_end;
2342
2343 #define PCIC_SMM_START_LOW 0
2344 #define PCIC_SMM_START_HIGH 1
2345 #define PCIC_SMM_STOP_LOW 2
2346 #define PCIC_SMM_STOP_HIGH 3
2347 #define PCIC_CMA_LOW 4
2348 #define PCIC_CMA_HIGH 5
2349
2350 u_int8_t start_low, start_high = 0;
2351 u_int8_t stop_low, stop_high;
2352 u_int8_t off_low, off_high;
2353 u_int8_t mem_window;
2354 int reg;
2355
2356 int kind = ph->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
2357 int mem8 = (ph->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8;
2358
2359 regbase_win = 0x10 + win*0x08;
2360
2361 phys_addr = ph->mem[win].addr;
2362 phys_end = phys_addr + ph->mem[win].size;
2363
2364 DPRINTF(("pccbb_pcmcia_do_mem_map: start 0x%lx end 0x%lx off 0x%lx\n",
2365 phys_addr, phys_end, ph->mem[win].offset));
2366
2367 #define PCIC_MEMREG_LSB_SHIFT PCIC_SYSMEM_ADDRX_SHIFT
2368 #define PCIC_MEMREG_MSB_SHIFT (PCIC_SYSMEM_ADDRX_SHIFT + 8)
2369 #define PCIC_MEMREG_WIN_SHIFT (PCIC_SYSMEM_ADDRX_SHIFT + 12)
2370
2371 start_low = (phys_addr >> PCIC_MEMREG_LSB_SHIFT) & 0xff; /* bit 19:12 */
2372 start_high = ((phys_addr >> PCIC_MEMREG_MSB_SHIFT) & 0x0f) /* bit 23:20 */
2373 | mem8 ? 0 : PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT; /* bit 7 on */
2374 /* bit 31:24, for 32-bit address */
2375 mem_window = (phys_addr >> PCIC_MEMREG_WIN_SHIFT) & 0xff; /* bit 31:24 */
2376
2377 Pcic_write(ph, regbase_win + PCIC_SMM_START_LOW, start_low);
2378 Pcic_write(ph, regbase_win + PCIC_SMM_START_HIGH, start_high);
2379
2380 if (((struct pccbb_softc *)ph->ph_parent)->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
2381 Pcic_write(ph, 0x40 + win, mem_window);
2382 }
2383
2384
2385 #if 0
2386 /* XXX do I want 16 bit all the time? */
2387 PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT;
2388 #endif
2389
2390
2391 stop_low = (phys_end >> PCIC_MEMREG_LSB_SHIFT) & 0xff;
2392 stop_high = ((phys_end >> PCIC_MEMREG_MSB_SHIFT) & 0x0f)
2393 | PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2; /* wait 2 cycles */
2394 /* XXX Geee, WAIT2!! Crazy!! I must rewrite this routine. */
2395
2396 Pcic_write(ph, regbase_win + PCIC_SMM_STOP_LOW, stop_low);
2397 Pcic_write(ph, regbase_win + PCIC_SMM_STOP_HIGH, stop_high);
2398
2399 off_low = (ph->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff;
2400 off_high = ((ph->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8))
2401 & PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK)
2402 | ((kind == PCMCIA_MEM_ATTR) ?
2403 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0);
2404
2405 Pcic_write(ph, regbase_win + PCIC_CMA_LOW, off_low);
2406 Pcic_write(ph, regbase_win + PCIC_CMA_HIGH, off_high);
2407
2408 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
2409 reg |= ((1 << win) | PCIC_ADDRWIN_ENABLE_MEMCS16);
2410 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
2411
2412 #if defined CBB_DEBUG
2413 {
2414 int r1, r2, r3, r4, r5, r6, r7 = 0;
2415
2416 r1 = Pcic_read(ph, regbase_win + PCIC_SMM_START_LOW);
2417 r2 = Pcic_read(ph, regbase_win + PCIC_SMM_START_HIGH);
2418 r3 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_LOW);
2419 r4 = Pcic_read(ph, regbase_win + PCIC_SMM_STOP_HIGH);
2420 r5 = Pcic_read(ph, regbase_win + PCIC_CMA_LOW);
2421 r6 = Pcic_read(ph, regbase_win + PCIC_CMA_HIGH);
2422 if (((struct pccbb_softc *)(ph->ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
2423 r7 = Pcic_read(ph, 0x40 + win);
2424 }
2425
2426 DPRINTF(("pccbb_pcmcia_do_mem_map window %d: %02x%02x %02x%02x "
2427 "%02x%02x", win, r1, r2, r3, r4, r5, r6));
2428 if (((struct pccbb_softc *)(ph->ph_parent))->sc_pcmcia_flags & PCCBB_PCMCIA_MEM_32) {
2429 DPRINTF((" %02x",r7));
2430 }
2431 DPRINTF(("\n"));
2432 }
2433 #endif
2434 }
2435
2436
2437
2438
2439 /*
2440 * STATIC int pccbb_pcmcia_mem_map(pcmcia_chipset_handle_t pch, int kind,
2441 * bus_addr_t card_addr, bus_size_t size,
2442 * struct pcmcia_mem_handle *pcmhp,
2443 * bus_addr_t *offsetp, int *windowp)
2444 *
2445 * This function maps memory space allocated by the fuction
2446 * pccbb_pcmcia_mem_alloc().
2447 */
2448 STATIC int
2449 pccbb_pcmcia_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
2450 pcmcia_chipset_handle_t pch;
2451 int kind;
2452 bus_addr_t card_addr;
2453 bus_size_t size;
2454 struct pcmcia_mem_handle *pcmhp;
2455 bus_addr_t *offsetp;
2456 int *windowp;
2457 {
2458 struct pcic_handle *ph = (struct pcic_handle *)pch;
2459 bus_addr_t busaddr;
2460 long card_offset;
2461 int win;
2462
2463 for (win = 0; win < PCIC_MEM_WINS; ++win) {
2464 if ((ph->memalloc & (1 << win)) == 0) {
2465 ph->memalloc |= (1 << win);
2466 break;
2467 }
2468 }
2469
2470 if (win == PCIC_MEM_WINS) {
2471 return 1;
2472 }
2473
2474 *windowp = win;
2475
2476 /* XXX this is pretty gross */
2477
2478 if (((struct pccbb_softc *)ph->ph_parent)->sc_memt != pcmhp->memt) {
2479 panic("pccbb_pcmcia_mem_map memt is bogus");
2480 }
2481
2482 busaddr = pcmhp->addr;
2483
2484 /*
2485 * compute the address offset to the pcmcia address space for the
2486 * pcic. this is intentionally signed. The masks and shifts below
2487 * will cause TRT to happen in the pcic registers. Deal with making
2488 * sure the address is aligned, and return the alignment offset.
2489 */
2490
2491 *offsetp = card_addr % PCIC_MEM_PAGESIZE;
2492 card_addr -= *offsetp;
2493
2494 DPRINTF(("pccbb_pcmcia_mem_map window %d bus %lx+%lx+%lx at card addr "
2495 "%lx\n", win, (u_long)busaddr, (u_long)*offsetp, (u_long)size,
2496 (u_long)card_addr));
2497
2498 /*
2499 * include the offset in the size, and decrement size by one, since
2500 * the hw wants start/stop
2501 */
2502 size += *offsetp - 1;
2503
2504 card_offset = (((long) card_addr) - ((long) busaddr));
2505
2506 ph->mem[win].addr = busaddr;
2507 ph->mem[win].size = size;
2508 ph->mem[win].offset = card_offset;
2509 ph->mem[win].kind = kind;
2510
2511 pccbb_pcmcia_do_mem_map(ph, win);
2512
2513 return 0;
2514 }
2515
2516
2517
2518 /*
2519 * STATIC int pccbb_pcmcia_mem_unmap(pcmcia_chipset_handle_t pch,
2520 * int window)
2521 *
2522 * This function unmaps memory space which mapped by the fuction
2523 * pccbb_pcmcia_mem_map().
2524 */
2525 STATIC void
2526 pccbb_pcmcia_mem_unmap(pch, window)
2527 pcmcia_chipset_handle_t pch;
2528 int window;
2529 {
2530 struct pcic_handle *ph = (struct pcic_handle *)pch;
2531 int reg;
2532
2533 if (window >= PCIC_MEM_WINS) {
2534 panic("pccbb_pcmcia_mem_unmap: window out of range");
2535 }
2536
2537 reg = Pcic_read(ph, PCIC_ADDRWIN_ENABLE);
2538 reg &= ~(1 << window);
2539 Pcic_write(ph, PCIC_ADDRWIN_ENABLE, reg);
2540
2541 ph->memalloc &= ~(1 << window);
2542 }
2543
2544
2545
2546 #if defined PCCBB_PCMCIA_POLL
2547 struct pccbb_poll_str {
2548 void *arg;
2549 int (* func) __P((void *));
2550 int level;
2551 struct pcic_handle *ph;
2552 int count;
2553 int num;
2554 };
2555
2556 static struct pccbb_poll_str pccbb_poll[10];
2557 static int pccbb_poll_n = 0;
2558
2559 static void pccbb_pcmcia_poll __P((void *arg));
2560
2561 static void
2562 pccbb_pcmcia_poll(arg)
2563 void *arg;
2564 {
2565 struct pccbb_poll_str *poll = arg;
2566 struct pcic_handle *ph = poll->ph;
2567 struct pccbb_softc *sc = ph->sc;
2568 int s;
2569 u_int32_t spsr; /* socket present-state reg */
2570
2571 timeout(pccbb_pcmcia_poll, arg, hz*2);
2572 switch (poll->level) {
2573 case IPL_NET:
2574 s = splnet();
2575 break;
2576 case IPL_BIO:
2577 s = splbio();
2578 break;
2579 case IPL_TTY: /* fallthrough */
2580 default:
2581 s = spltty();
2582 break;
2583 }
2584
2585 spsr = bus_space_read_4(sc->sc_base_memt, sc->sc_base_memh, CB_SOCKET_STAT);
2586
2587 #if defined PCCBB_PCMCIA_POLL_ONLY && defined LEVEL2
2588 if (!(spsr & 0x40)) /* CINT low */
2589 #else
2590 if (1)
2591 #endif
2592 {
2593 if ((*poll->func)(poll->arg) > 0) {
2594 ++poll->count;
2595 // printf("intr: reported from poller, 0x%x\n", spsr);
2596 #if defined LEVEL2
2597 } else {
2598 printf("intr: miss! 0x%x\n", spsr);
2599 #endif
2600 }
2601 }
2602 splx(s);
2603 }
2604 #endif /* defined CB_PCMCIA_POLL */
2605
2606
2607
2608 /*
2609 * STATIC void *pccbb_pcmcia_intr_establish(pcmcia_chipset_handle_t pch,
2610 * struct pcmcia_function *pf,
2611 * int ipl,
2612 * int (*func)(void *),
2613 * void *arg);
2614 *
2615 * This function enables PC-Card interrupt. PCCBB uses PCI interrupt line.
2616 */
2617 STATIC void *
2618 pccbb_pcmcia_intr_establish(pch, pf, ipl, func, arg)
2619 pcmcia_chipset_handle_t pch;
2620 struct pcmcia_function *pf;
2621 int ipl;
2622 int (*func) __P((void *));
2623 void *arg;
2624 {
2625 struct pcic_handle *ph = (struct pcic_handle *)pch;
2626 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2627 pci_intr_handle_t handle;
2628 void *ih;
2629
2630 if (!(pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)) {
2631 /* what should I do? */
2632 if ((pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)) {
2633 DPRINTF(("%s does not provide edge nor pulse interrupt\n",
2634 sc->sc_dev.dv_xname));
2635 return NULL;
2636 }
2637 /*
2638 * XXX Noooooo! The interrupt flag must set properly!!
2639 * dumb pcmcia driver!!
2640 */
2641 }
2642
2643 if (pci_intr_map(sc->sc_pc, sc->sc_intrtag, sc->sc_intrpin,
2644 sc->sc_intrline, &handle)) {
2645 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
2646 return NULL;
2647 }
2648 DPRINTF(("pccbb_pcmcia_intr_establish: line %d, handle %d\n",
2649 sc->sc_intrline, handle));
2650
2651 if (NULL != (ih = pci_intr_establish(sc->sc_pc, handle, ipl, func, arg)))
2652 {
2653 u_int32_t cbctrl;
2654
2655 if ((CB_TI113X == sc->sc_chipset)) {
2656 cbctrl = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CBCTRL);
2657 cbctrl |= PCI113X_CBCTRL_PCI_INTR; /* PCI functional intr req */
2658 pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CBCTRL, cbctrl);
2659 }
2660 }
2661 #if defined PCCBB_PCMCIA_POLL
2662 if (pccbb_poll_n < 10) {
2663 pccbb_poll[pccbb_poll_n].arg = arg;
2664 pccbb_poll[pccbb_poll_n].func = func;
2665 pccbb_poll[pccbb_poll_n].level = ipl;
2666 pccbb_poll[pccbb_poll_n].count = 0;
2667 pccbb_poll[pccbb_poll_n].num = pccbb_poll_n;
2668 pccbb_poll[pccbb_poll_n].ph = ph;
2669 timeout(pccbb_pcmcia_poll, &pccbb_poll[pccbb_poll_n++], hz*2);
2670 printf("polling set\n");
2671 }
2672 #endif
2673 #if defined SHOW_REGS
2674 cb_show_regs(sc->sc_pc, sc->sc_tag, sc->sc_base_memt, sc->sc_base_memh);
2675 #endif
2676
2677 return ih;
2678 }
2679
2680
2681
2682
2683 /*
2684 * STATIC void pccbb_pcmcia_intr_disestablish(pcmcia_chipset_handle_t pch,
2685 * void *ih)
2686 *
2687 * This function disables PC-Card interrupt.
2688 */
2689 STATIC void
2690 pccbb_pcmcia_intr_disestablish(pch, ih)
2691 pcmcia_chipset_handle_t pch;
2692 void *ih;
2693 {
2694 struct pcic_handle *ph = (struct pcic_handle *)pch;
2695 struct pccbb_softc *sc = (struct pccbb_softc *)ph->ph_parent;
2696
2697 pci_intr_disestablish(sc->sc_pc, ih);
2698 }
2699
2700
2701
2702
2703 #if rbus
2704 /*
2705 * static int
2706 * pccbb_rbus_cb_space_alloc(cardbus_chipset_tag_t ct, rbus_tag_t rb,
2707 * bus_addr_t addr, bus_size_t size,
2708 * bus_addr_t mask, bus_size_t align,
2709 * int flags, bus_addr_t *addrp;
2710 * bus_space_handle_t *bshp)
2711 *
2712 * This function allocates a portion of memory or io space for
2713 * clients. This function is called from CardBus card drivers.
2714 */
2715 static int
2716 pccbb_rbus_cb_space_alloc(ct, rb, addr, size, mask, align, flags, addrp, bshp)
2717 cardbus_chipset_tag_t ct;
2718 rbus_tag_t rb;
2719 bus_addr_t addr;
2720 bus_size_t size;
2721 bus_addr_t mask;
2722 bus_size_t align;
2723 int flags;
2724 bus_addr_t *addrp;
2725 bus_space_handle_t *bshp;
2726 {
2727 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
2728
2729 DPRINTF(("pccbb_rbus_cb_space_alloc: adr %lx, size %lx, mask %lx, align %lx\n", addr, size, mask, align));
2730
2731 if (align == 0) {
2732 align = size;
2733 }
2734
2735 if (rb->rb_bt == sc->sc_memt) {
2736 if (align < 16) {
2737 return 1;
2738 }
2739 } else if (rb->rb_bt == sc->sc_iot) {
2740 if (align < 4) {
2741 return 1;
2742 }
2743 } else {
2744 DPRINTF(("pccbb_rbus_cb_space_alloc: Bus space tag %x is NOT used.\n",
2745 rb->rb_bt));
2746 return 1;
2747 /* XXX: panic here? */
2748 }
2749
2750 /* XXX: hack for avoiding ISA image */
2751 if (mask < 0x3ff) {
2752 mask = 0x3ff;
2753 addr = 0x300;
2754 }
2755
2756 if (rbus_space_alloc(rb, addr, size, mask, align, flags, addrp, bshp)) {
2757 printf("%s: <rbus> no bus space\n", sc->sc_dev.dv_xname);
2758 return 1;
2759 }
2760
2761 pccbb_open_win(sc, rb->rb_bt, *addrp, size, *bshp, 0);
2762
2763 return 0;
2764 }
2765
2766
2767
2768
2769
2770 /*
2771 * static int
2772 * pccbb_rbus_cb_space_free(cardbus_chipset_tag_t *ct, rbus_tag_t rb,
2773 * bus_space_handle_t *bshp, bus_size_t size);
2774 *
2775 * This function is called from CardBus card drivers.
2776 */
2777 static int
2778 pccbb_rbus_cb_space_free(ct, rb, bsh, size)
2779 cardbus_chipset_tag_t ct;
2780 rbus_tag_t rb;
2781 bus_space_handle_t bsh;
2782 bus_size_t size;
2783 {
2784 struct pccbb_softc *sc = (struct pccbb_softc *)ct;
2785 bus_space_tag_t bt = rb->rb_bt;
2786
2787 pccbb_close_win(sc, bt, bsh, size);
2788
2789 if (bt == sc->sc_memt) {
2790 } else if (bt == sc->sc_iot) {
2791 } else {
2792 return 1;
2793 /* XXX: panic here? */
2794 }
2795
2796 return rbus_space_free(rb, bsh, size, NULL);
2797 }
2798 #endif /* rbus */
2799
2800
2801 #if rbus
2802
2803 static int
2804 pccbb_open_win(sc, bst, addr, size, bsh, flags)
2805 struct pccbb_softc *sc;
2806 bus_space_tag_t bst;
2807 bus_addr_t addr;
2808 bus_size_t size;
2809 bus_space_handle_t bsh;
2810 int flags;
2811 {
2812 struct pccbb_win_chain **top;
2813 bus_addr_t align;
2814
2815 top = &sc->sc_iowindow;
2816 align = 0x04;
2817 if (sc->sc_memt == bst) {
2818 top = &sc->sc_memwindow;
2819 align = 0x1000;
2820 DPRINTF(("using memory window, %x %x %x\n\n",
2821 sc->sc_iot, sc->sc_memt, bst));
2822 }
2823
2824 if (pccbb_winlist_insert(top, addr, size, bsh, flags)) {
2825 printf("winlist insert fails:\n");
2826 }
2827 pccbb_winset(align, sc, bst);
2828
2829 return 0;
2830 }
2831
2832
2833
2834 static int
2835 pccbb_close_win(sc, bst, bsh, size)
2836 struct pccbb_softc *sc;
2837 bus_space_tag_t bst;
2838 bus_space_handle_t bsh;
2839 bus_size_t size;
2840 {
2841 struct pccbb_win_chain **top;
2842 bus_addr_t align;
2843
2844 top = &sc->sc_iowindow;
2845 align = 0x04;
2846 if (sc->sc_memt == bst) {
2847 top = &sc->sc_memwindow;
2848 align = 0x1000;
2849 }
2850
2851 if (pccbb_winlist_delete(top, bsh, size)) {
2852 printf("winlist delete fails:\n");
2853 }
2854 pccbb_winset(align, sc, bst);
2855
2856 return 0;
2857 }
2858
2859
2860 static int
2861 pccbb_winlist_insert(top, start, size, bsh, flags)
2862 struct pccbb_win_chain **top;
2863 bus_addr_t start;
2864 bus_size_t size;
2865 bus_space_handle_t bsh;
2866 int flags;
2867 {
2868 struct pccbb_win_chain *chainp = *top;
2869 struct pccbb_win_chain *before = *top;
2870 struct pccbb_win_chain *elem;
2871
2872 if (*top == NULL) {
2873 if (NULL == (elem = (struct pccbb_win_chain *)malloc(sizeof(struct pccbb_win_chain), M_DEVBUF, M_NOWAIT))) {
2874 return 1; /* fail */
2875 }
2876
2877 elem->wc_start = start;
2878 elem->wc_end = start + size - 1;
2879 elem->wc_handle = bsh;
2880 elem->wc_flags = flags;
2881
2882 *top = elem;
2883 elem->wc_next = NULL;
2884 return 0;
2885 }
2886
2887 for(; chainp && chainp->wc_start <= start; chainp = chainp->wc_next) {
2888 before = chainp;
2889 }
2890
2891 if (chainp != NULL) {
2892 if (chainp->wc_start < start + size) {
2893 printf("fatal! 0x%lx 0x%lx\n", chainp->wc_start, start+size);
2894 return 1;
2895 }
2896 }
2897 if ((before != *top) && (before->wc_end >= start)) {
2898 printf("fatal!! 0x%lx 0x%lx\n", before->wc_end, start);
2899 return 1;
2900 }
2901
2902 if (NULL == (elem = (struct pccbb_win_chain *)malloc(sizeof(struct pccbb_win_chain), M_DEVBUF, M_NOWAIT))) {
2903 return 1; /* fail */
2904 }
2905
2906 elem->wc_start = start;
2907 elem->wc_end = start + size - 1;
2908 elem->wc_handle = bsh;
2909 elem->wc_flags = flags;
2910
2911 elem->wc_next = chainp;
2912 if (chainp == *top) {
2913 *top = elem;
2914 } else {
2915 before->wc_next = elem;
2916 }
2917 return 0;
2918 }
2919
2920
2921
2922
2923 static int
2924 pccbb_winlist_delete(top, bsh, size)
2925 struct pccbb_win_chain **top;
2926 bus_space_handle_t bsh;
2927 bus_size_t size;
2928 {
2929 struct pccbb_win_chain *chainp = *top;
2930 struct pccbb_win_chain **before = top;
2931
2932 for (; chainp && chainp->wc_handle != bsh; chainp = chainp->wc_next) {
2933 before = &chainp->wc_next;
2934 }
2935
2936 if (chainp == NULL) {
2937 return 1; /* fail: no candidate to remove */
2938 }
2939
2940 if (chainp->wc_end - chainp->wc_start != size - 1) {
2941 printf("fatal!!! 0x%lx\n", chainp->wc_start);
2942 return 1; /* fail: no candidate to remove */
2943 }
2944
2945 *before = chainp->wc_next;
2946 free(chainp, M_DEVBUF);
2947
2948 return 0;
2949 }
2950
2951
2952
2953 static void
2954 pccbb_winset(align, sc, bst)
2955 bus_addr_t align;
2956 struct pccbb_softc *sc;
2957 bus_space_tag_t bst;
2958 {
2959 pci_chipset_tag_t pc;
2960 pcitag_t tag;
2961 bus_addr_t mask = ~(align - 1);
2962 struct {
2963 cardbusreg_t win_start;
2964 cardbusreg_t win_limit;
2965 int win_flags;
2966 } win[2];
2967 struct pccbb_win_chain *chainp;
2968 int offs;
2969
2970 win[0].win_start = 0xffffffff;
2971 win[0].win_limit = 0;
2972 win[1].win_start = 0xffffffff;
2973 win[1].win_limit = 0;
2974
2975 chainp = sc->sc_iowindow;
2976 offs = 0x2c;
2977 if (sc->sc_memt == bst) {
2978 chainp = sc->sc_memwindow;
2979 offs = 0x1c;
2980 }
2981
2982 if (chainp) {
2983 win[0].win_start = chainp->wc_start & mask;
2984 win[0].win_limit = chainp->wc_end & mask;
2985 win[0].win_flags = chainp->wc_flags;
2986 chainp = chainp->wc_next;
2987 }
2988
2989 for(; chainp; chainp = chainp->wc_next) {
2990 if (win[1].win_start == 0xffffffff) {
2991 /* window 1 is not used */
2992 if ((win[0].win_flags == chainp->wc_flags) &&
2993 (win[0].win_limit + align >= (chainp->wc_start & mask))) {
2994 /* concatinate */
2995 win[0].win_limit = chainp->wc_end & mask;
2996 } else {
2997 /* make new window */
2998 win[1].win_start = chainp->wc_start & mask;
2999 win[1].win_limit = chainp->wc_end & mask;
3000 win[1].win_flags = chainp->wc_flags;
3001 }
3002 continue;
3003 }
3004
3005 /* Both windows are engagad. */
3006 if (win[0].win_flags == win[1].win_flags) {
3007 /* same flags */
3008 if (win[0].win_flags == chainp->wc_flags) {
3009 if (win[1].win_start - (win[0].win_limit + align)
3010 < (chainp->wc_start & mask) - ((chainp->wc_end & mask) + align)) {
3011 /* merge window 0 and 1, and set win1 to chainp */
3012 win[0].win_limit = win[1].win_limit;
3013 win[1].win_start = chainp->wc_start & mask;
3014 win[1].win_limit = chainp->wc_end & mask;
3015 } else {
3016 win[1].win_limit = chainp->wc_end & mask;
3017 }
3018 } else {
3019 /* different flags */
3020
3021 /* concatinate win0 and win1 */
3022 win[0].win_limit = win[1].win_limit;
3023 /* allocate win[1] to new space */
3024 win[1].win_start = chainp->wc_start & mask;
3025 win[1].win_limit = chainp->wc_end & mask;
3026 win[1].win_flags = chainp->wc_flags;
3027 }
3028 } else {
3029 /* the flags of win[0] and win[1] is different */
3030 if (win[0].win_flags == chainp->wc_flags) {
3031 win[0].win_limit = chainp->wc_end & mask;
3032 /* XXX this creates overlapping windows, so what should the
3033 poor bridge do if one is cachable, and the other is not? */
3034 printf("%s: overlapping windows\n", sc->sc_dev.dv_xname);
3035 } else {
3036 win[1].win_limit = chainp->wc_end & mask;
3037 }
3038 }
3039 }
3040
3041 pc = sc->sc_pc;
3042 tag = sc->sc_tag;
3043 pci_conf_write(pc, tag, offs, win[0].win_start);
3044 pci_conf_write(pc, tag, offs+4, win[0].win_limit);
3045 pci_conf_write(pc, tag, offs+8, win[1].win_start);
3046 pci_conf_write(pc, tag, offs+12, win[1].win_limit);
3047 DPRINTF(("--pccbb_winset: win0 [%x, %lx), win1 [%x, %lx)\n",
3048 pci_conf_read(pc, tag, offs),
3049 pci_conf_read(pc, tag, offs+4) + align,
3050 pci_conf_read(pc, tag, offs+8),
3051 pci_conf_read(pc, tag, offs+12) + align));
3052
3053 if (bst == sc->sc_memt) {
3054 if (win[0].win_flags & PCCBB_MEM_CACHABLE) {
3055 pcireg_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
3056 bcr |= CB_BCR_PREFETCH_MEMWIN0;
3057 pci_conf_write(pc,tag, PCI_BCR_INTR, bcr);
3058 }
3059 if (win[1].win_flags & PCCBB_MEM_CACHABLE) {
3060 pcireg_t bcr = pci_conf_read(pc, tag, PCI_BCR_INTR);
3061 bcr |= CB_BCR_PREFETCH_MEMWIN1;
3062 pci_conf_write(pc,tag, PCI_BCR_INTR, bcr);
3063 }
3064 }
3065 }
3066
3067 #endif /* rbus */
3068