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