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