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