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