i82365.c revision 1.65 1 /* $NetBSD: i82365.c,v 1.65 2001/12/15 13:23:21 soren Exp $ */
2
3 /*
4 * Copyright (c) 2000 Christian E. Hopps. All rights reserved.
5 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Marc Horowitz.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: i82365.c,v 1.65 2001/12/15 13:23:21 soren Exp $");
35
36 #define PCICDEBUG
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/device.h>
41 #include <sys/extent.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/kthread.h>
45
46 #include <machine/bus.h>
47 #include <machine/intr.h>
48
49 #include <dev/pcmcia/pcmciareg.h>
50 #include <dev/pcmcia/pcmciavar.h>
51
52 #include <dev/ic/i82365reg.h>
53 #include <dev/ic/i82365var.h>
54
55 #include "locators.h"
56
57 #ifdef PCICDEBUG
58 int pcic_debug = 0;
59 #define DPRINTF(arg) if (pcic_debug) printf arg;
60 #else
61 #define DPRINTF(arg)
62 #endif
63
64 /*
65 * Individual drivers will allocate their own memory and io regions. Memory
66 * regions must be a multiple of 4k, aligned on a 4k boundary.
67 */
68
69 #define PCIC_MEM_ALIGN PCIC_MEM_PAGESIZE
70
71 void pcic_attach_socket __P((struct pcic_handle *));
72 void pcic_attach_socket_finish __P((struct pcic_handle *));
73
74 int pcic_submatch __P((struct device *, struct cfdata *, void *));
75 int pcic_print __P((void *arg, const char *pnp));
76 int pcic_intr_socket __P((struct pcic_handle *));
77 void pcic_poll_intr __P((void *));
78
79 void pcic_attach_card __P((struct pcic_handle *));
80 void pcic_detach_card __P((struct pcic_handle *, int));
81 void pcic_deactivate_card __P((struct pcic_handle *));
82
83 void pcic_chip_do_mem_map __P((struct pcic_handle *, int));
84 void pcic_chip_do_io_map __P((struct pcic_handle *, int));
85
86 void pcic_create_event_thread __P((void *));
87 void pcic_event_thread __P((void *));
88
89 void pcic_queue_event __P((struct pcic_handle *, int));
90 void pcic_power __P((int, void *));
91
92 static void pcic_wait_ready __P((struct pcic_handle *));
93 static void pcic_delay __P((struct pcic_handle *, int, const char *));
94
95 static u_int8_t st_pcic_read __P((struct pcic_handle *, int));
96 static void st_pcic_write __P((struct pcic_handle *, int, u_int8_t));
97
98 int
99 pcic_ident_ok(ident)
100 int ident;
101 {
102 /* this is very empirical and heuristic */
103
104 if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO))
105 return (0);
106
107 if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) {
108 #ifdef DIAGNOSTIC
109 printf("pcic: does not support memory and I/O cards, "
110 "ignored (ident=%0x)\n", ident);
111 #endif
112 return (0);
113 }
114 return (1);
115 }
116
117 int
118 pcic_vendor(h)
119 struct pcic_handle *h;
120 {
121 int reg;
122
123 /*
124 * the chip_id of the cirrus toggles between 11 and 00 after a write.
125 * weird.
126 */
127
128 pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0);
129 reg = pcic_read(h, -1);
130
131 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) ==
132 PCIC_CIRRUS_CHIP_INFO_CHIP_ID) {
133 reg = pcic_read(h, -1);
134 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) {
135 if (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS)
136 return (PCIC_VENDOR_CIRRUS_PD672X);
137 else
138 return (PCIC_VENDOR_CIRRUS_PD6710);
139 }
140 }
141
142 reg = pcic_read(h, PCIC_IDENT);
143
144 if ((reg & PCIC_IDENT_REV_MASK) == PCIC_IDENT_REV_I82365SLR0)
145 return (PCIC_VENDOR_I82365SLR0);
146 else
147 return (PCIC_VENDOR_I82365SLR1);
148
149 return (PCIC_VENDOR_UNKNOWN);
150 }
151
152 char *
153 pcic_vendor_to_string(vendor)
154 int vendor;
155 {
156 switch (vendor) {
157 case PCIC_VENDOR_I82365SLR0:
158 return ("Intel 82365SL Revision 0");
159 case PCIC_VENDOR_I82365SLR1:
160 return ("Intel 82365SL Revision 1");
161 case PCIC_VENDOR_CIRRUS_PD6710:
162 return ("Cirrus PD6710");
163 case PCIC_VENDOR_CIRRUS_PD672X:
164 return ("Cirrus PD672X");
165 }
166
167 return ("Unknown controller");
168 }
169
170 void
171 pcic_attach(sc)
172 struct pcic_softc *sc;
173 {
174 int i, reg, chip, socket, intr;
175 struct pcic_handle *h;
176
177 DPRINTF(("pcic ident regs:"));
178
179 lockinit(&sc->sc_pcic_lock, PWAIT, "pciclk", 0, 0);
180
181 /* find and configure for the available sockets */
182 for (i = 0; i < PCIC_NSLOTS; i++) {
183 h = &sc->handle[i];
184 chip = i / 2;
185 socket = i % 2;
186
187 h->ph_parent = (struct device *)sc;
188 h->chip = chip;
189 h->sock = chip * PCIC_CHIP_OFFSET + socket * PCIC_SOCKET_OFFSET;
190 h->laststate = PCIC_LASTSTATE_EMPTY;
191 /* initialize pcic_read and pcic_write functions */
192 h->ph_read = st_pcic_read;
193 h->ph_write = st_pcic_write;
194 h->ph_bus_t = sc->iot;
195 h->ph_bus_h = sc->ioh;
196
197 /* need to read vendor -- for cirrus to report no xtra chip */
198 if (socket == 0)
199 h->vendor = (h+1)->vendor = pcic_vendor(h);
200
201 /*
202 * During the socket probe, read the ident register twice.
203 * I don't understand why, but sometimes the clone chips
204 * in hpcmips boxes read all-0s the first time. -- mycroft
205 */
206 reg = pcic_read(h, PCIC_IDENT);
207 reg = pcic_read(h, PCIC_IDENT);
208 DPRINTF(("ident reg 0x%02x\n", reg));
209 if (pcic_ident_ok(reg))
210 h->flags = PCIC_FLAG_SOCKETP;
211 else
212 h->flags = 0;
213 }
214
215 for (i = 0; i < PCIC_NSLOTS; i++) {
216 h = &sc->handle[i];
217
218 if (h->flags & PCIC_FLAG_SOCKETP) {
219 SIMPLEQ_INIT(&h->events);
220
221 /* disable interrupts -- for now */
222 pcic_write(h, PCIC_CSC_INTR, 0);
223 intr = pcic_read(h, PCIC_INTR);
224 DPRINTF(("intr was 0x%02x\n", intr));
225 intr &= ~(PCIC_INTR_RI_ENABLE | PCIC_INTR_ENABLE |
226 PCIC_INTR_IRQ_MASK);
227 pcic_write(h, PCIC_INTR, intr);
228 (void) pcic_read(h, PCIC_CSC);
229 }
230 }
231
232 /* print detected info */
233 for (i = 0; i < PCIC_NSLOTS; i += 2) {
234 h = &sc->handle[i];
235 chip = i / 2;
236
237 printf("%s: controller %d (%s) has ", sc->dev.dv_xname, chip,
238 pcic_vendor_to_string(sc->handle[i].vendor));
239
240 if ((h->flags & PCIC_FLAG_SOCKETP) &&
241 ((h+1)->flags & PCIC_FLAG_SOCKETP))
242 printf("sockets A and B\n");
243 else if (h->flags & PCIC_FLAG_SOCKETP)
244 printf("socket A only\n");
245 else if ((h+1)->flags & PCIC_FLAG_SOCKETP)
246 printf("socket B only\n");
247 else
248 printf("no sockets\n");
249 }
250 }
251
252 /*
253 * attach the sockets before we know what interrupts we have
254 */
255 void
256 pcic_attach_sockets(sc)
257 struct pcic_softc *sc;
258 {
259 int i;
260
261 for (i = 0; i < PCIC_NSLOTS; i++)
262 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
263 pcic_attach_socket(&sc->handle[i]);
264 }
265
266 void
267 pcic_power(why, arg)
268 int why;
269 void *arg;
270 {
271 struct pcic_handle *h = (struct pcic_handle *)arg;
272 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
273 int reg;
274
275 DPRINTF(("%s: power: why %d\n", h->ph_parent->dv_xname, why));
276
277 if (h->flags & PCIC_FLAG_SOCKETP) {
278 if ((why == PWR_RESUME) &&
279 (pcic_read(h, PCIC_CSC_INTR) == 0)) {
280 #ifdef PCICDEBUG
281 char bitbuf[64];
282 #endif
283 reg = PCIC_CSC_INTR_CD_ENABLE;
284 if (sc->irq != -1)
285 reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT;
286 pcic_write(h, PCIC_CSC_INTR, reg);
287 DPRINTF(("%s: CSC_INTR was zero; reset to %s\n",
288 sc->dev.dv_xname,
289 bitmask_snprintf(pcic_read(h, PCIC_CSC_INTR),
290 PCIC_CSC_INTR_FORMAT,
291 bitbuf, sizeof(bitbuf))));
292 }
293
294 /*
295 * check for card insertion or removal during suspend period.
296 * XXX: the code can't cope with card swap (remove then insert).
297 * how can we detect such situation?
298 */
299 if (why == PWR_RESUME)
300 (void)pcic_intr_socket(h);
301 }
302 }
303
304
305 /*
306 * attach a socket -- we don't know about irqs yet
307 */
308 void
309 pcic_attach_socket(h)
310 struct pcic_handle *h;
311 {
312 struct pcmciabus_attach_args paa;
313 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
314
315 /* initialize the rest of the handle */
316
317 h->shutdown = 0;
318 h->memalloc = 0;
319 h->ioalloc = 0;
320 h->ih_irq = 0;
321
322 /* now, config one pcmcia device per socket */
323
324 paa.paa_busname = "pcmcia";
325 paa.pct = (pcmcia_chipset_tag_t) sc->pct;
326 paa.pch = (pcmcia_chipset_handle_t) h;
327 paa.iobase = sc->iobase;
328 paa.iosize = sc->iosize;
329
330 h->pcmcia = config_found_sm(&sc->dev, &paa, pcic_print, pcic_submatch);
331 if (h->pcmcia == NULL) {
332 h->flags &= ~PCIC_FLAG_SOCKETP;
333 return;
334 }
335
336 /*
337 * queue creation of a kernel thread to handle insert/removal events.
338 */
339 #ifdef DIAGNOSTIC
340 if (h->event_thread != NULL)
341 panic("pcic_attach_socket: event thread");
342 #endif
343 config_pending_incr();
344 kthread_create(pcic_create_event_thread, h);
345 }
346
347 /*
348 * now finish attaching the sockets, we are ready to allocate
349 * interrupts
350 */
351 void
352 pcic_attach_sockets_finish(sc)
353 struct pcic_softc *sc;
354 {
355 int i;
356
357 for (i = 0; i < PCIC_NSLOTS; i++)
358 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
359 pcic_attach_socket_finish(&sc->handle[i]);
360 }
361
362 /*
363 * finishing attaching the socket. Interrupts may now be on
364 * if so expects the pcic interrupt to be blocked
365 */
366 void
367 pcic_attach_socket_finish(h)
368 struct pcic_handle *h;
369 {
370 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
371 int reg, intr;
372
373 DPRINTF(("%s: attach finish socket %ld\n", h->ph_parent->dv_xname,
374 (long) (h - &sc->handle[0])));
375
376 /*
377 * Set up a powerhook to ensure it continues to interrupt on
378 * card detect even after suspend.
379 * (this works around a bug seen in suspend-to-disk on the
380 * Sony VAIO Z505; on resume, the CSC_INTR state is not preserved).
381 */
382 powerhook_establish(pcic_power, h);
383
384 /* enable interrupts on card detect, poll for them if no irq avail */
385 reg = PCIC_CSC_INTR_CD_ENABLE;
386 if (sc->irq == -1) {
387 if (sc->poll_established == 0) {
388 callout_init(&sc->poll_ch);
389 callout_reset(&sc->poll_ch, hz / 2, pcic_poll_intr, sc);
390 sc->poll_established = 1;
391 }
392 } else
393 reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT;
394 pcic_write(h, PCIC_CSC_INTR, reg);
395
396 /* steer above mgmt interrupt to configured place */
397 intr = pcic_read(h, PCIC_INTR);
398 intr &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE);
399 pcic_write(h, PCIC_INTR, intr);
400
401 /* power down the socket */
402 pcic_write(h, PCIC_PWRCTL, 0);
403
404 /* zero out the address windows */
405 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
406
407 /* clear possible card detect interrupt */
408 pcic_read(h, PCIC_CSC);
409
410 DPRINTF(("%s: attach finish vendor 0x%02x\n", h->ph_parent->dv_xname,
411 h->vendor));
412
413 /* unsleep the cirrus controller */
414 if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) ||
415 (h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) {
416 reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
417 if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
418 DPRINTF(("%s: socket %02x was suspended\n",
419 h->ph_parent->dv_xname, h->sock));
420 reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
421 pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
422 }
423 }
424
425 /* if there's a card there, then attach it. */
426 reg = pcic_read(h, PCIC_IF_STATUS);
427 if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
428 PCIC_IF_STATUS_CARDDETECT_PRESENT) {
429 pcic_queue_event(h, PCIC_EVENT_INSERTION);
430 h->laststate = PCIC_LASTSTATE_PRESENT;
431 } else {
432 h->laststate = PCIC_LASTSTATE_EMPTY;
433 }
434 }
435
436 void
437 pcic_create_event_thread(arg)
438 void *arg;
439 {
440 struct pcic_handle *h = arg;
441 const char *cs;
442
443 switch (h->sock) {
444 case C0SA:
445 cs = "0,0";
446 break;
447 case C0SB:
448 cs = "0,1";
449 break;
450 case C1SA:
451 cs = "1,0";
452 break;
453 case C1SB:
454 cs = "1,1";
455 break;
456 default:
457 panic("pcic_create_event_thread: unknown pcic socket");
458 }
459
460 if (kthread_create1(pcic_event_thread, h, &h->event_thread,
461 "%s,%s", h->ph_parent->dv_xname, cs)) {
462 printf("%s: unable to create event thread for sock 0x%02x\n",
463 h->ph_parent->dv_xname, h->sock);
464 panic("pcic_create_event_thread");
465 }
466 }
467
468 void
469 pcic_event_thread(arg)
470 void *arg;
471 {
472 struct pcic_handle *h = arg;
473 struct pcic_event *pe;
474 int s, first = 1;
475 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
476
477 while (h->shutdown == 0) {
478 /*
479 * Serialize event processing on the PCIC. We may
480 * sleep while we hold this lock.
481 */
482 (void) lockmgr(&sc->sc_pcic_lock, LK_EXCLUSIVE, NULL);
483
484 s = splhigh();
485 if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) {
486 splx(s);
487 if (first) {
488 first = 0;
489 config_pending_decr();
490 }
491 /*
492 * No events to process; release the PCIC lock.
493 */
494 (void) lockmgr(&sc->sc_pcic_lock, LK_RELEASE, NULL);
495 (void) tsleep(&h->events, PWAIT, "pcicev", 0);
496 continue;
497 } else {
498 splx(s);
499 /* sleep .25s to be enqueued chatterling interrupts */
500 (void) tsleep((caddr_t)pcic_event_thread, PWAIT,
501 "pcicss", hz/4);
502 }
503 s = splhigh();
504 SIMPLEQ_REMOVE_HEAD(&h->events, pe, pe_q);
505 splx(s);
506
507 switch (pe->pe_type) {
508 case PCIC_EVENT_INSERTION:
509 s = splhigh();
510 while (1) {
511 struct pcic_event *pe1, *pe2;
512
513 if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
514 break;
515 if (pe1->pe_type != PCIC_EVENT_REMOVAL)
516 break;
517 if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
518 break;
519 if (pe2->pe_type == PCIC_EVENT_INSERTION) {
520 SIMPLEQ_REMOVE_HEAD(&h->events, pe1,
521 pe_q);
522 free(pe1, M_TEMP);
523 SIMPLEQ_REMOVE_HEAD(&h->events, pe2,
524 pe_q);
525 free(pe2, M_TEMP);
526 }
527 }
528 splx(s);
529
530 DPRINTF(("%s: insertion event\n",
531 h->ph_parent->dv_xname));
532 pcic_attach_card(h);
533 break;
534
535 case PCIC_EVENT_REMOVAL:
536 s = splhigh();
537 while (1) {
538 struct pcic_event *pe1, *pe2;
539
540 if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
541 break;
542 if (pe1->pe_type != PCIC_EVENT_INSERTION)
543 break;
544 if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
545 break;
546 if (pe2->pe_type == PCIC_EVENT_REMOVAL) {
547 SIMPLEQ_REMOVE_HEAD(&h->events, pe1,
548 pe_q);
549 free(pe1, M_TEMP);
550 SIMPLEQ_REMOVE_HEAD(&h->events, pe2,
551 pe_q);
552 free(pe2, M_TEMP);
553 }
554 }
555 splx(s);
556
557 DPRINTF(("%s: removal event\n",
558 h->ph_parent->dv_xname));
559 pcic_detach_card(h, DETACH_FORCE);
560 break;
561
562 default:
563 panic("pcic_event_thread: unknown event %d",
564 pe->pe_type);
565 }
566 free(pe, M_TEMP);
567
568 (void) lockmgr(&sc->sc_pcic_lock, LK_RELEASE, NULL);
569 }
570
571 h->event_thread = NULL;
572
573 /* In case parent is waiting for us to exit. */
574 wakeup(sc);
575
576 kthread_exit(0);
577 }
578
579 int
580 pcic_submatch(parent, cf, aux)
581 struct device *parent;
582 struct cfdata *cf;
583 void *aux;
584 {
585
586 struct pcmciabus_attach_args *paa = aux;
587 struct pcic_handle *h = (struct pcic_handle *) paa->pch;
588
589 switch (h->sock) {
590 case C0SA:
591 if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] !=
592 PCMCIABUSCF_CONTROLLER_DEFAULT &&
593 cf->cf_loc[PCMCIABUSCF_CONTROLLER] != 0)
594 return 0;
595 if (cf->cf_loc[PCMCIABUSCF_SOCKET] !=
596 PCMCIABUSCF_SOCKET_DEFAULT &&
597 cf->cf_loc[PCMCIABUSCF_SOCKET] != 0)
598 return 0;
599
600 break;
601 case C0SB:
602 if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] !=
603 PCMCIABUSCF_CONTROLLER_DEFAULT &&
604 cf->cf_loc[PCMCIABUSCF_CONTROLLER] != 0)
605 return 0;
606 if (cf->cf_loc[PCMCIABUSCF_SOCKET] !=
607 PCMCIABUSCF_SOCKET_DEFAULT &&
608 cf->cf_loc[PCMCIABUSCF_SOCKET] != 1)
609 return 0;
610
611 break;
612 case C1SA:
613 if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] !=
614 PCMCIABUSCF_CONTROLLER_DEFAULT &&
615 cf->cf_loc[PCMCIABUSCF_CONTROLLER] != 1)
616 return 0;
617 if (cf->cf_loc[PCMCIABUSCF_SOCKET] !=
618 PCMCIABUSCF_SOCKET_DEFAULT &&
619 cf->cf_loc[PCMCIABUSCF_SOCKET] != 0)
620 return 0;
621
622 break;
623 case C1SB:
624 if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] !=
625 PCMCIABUSCF_CONTROLLER_DEFAULT &&
626 cf->cf_loc[PCMCIABUSCF_CONTROLLER] != 1)
627 return 0;
628 if (cf->cf_loc[PCMCIABUSCF_SOCKET] !=
629 PCMCIABUSCF_SOCKET_DEFAULT &&
630 cf->cf_loc[PCMCIABUSCF_SOCKET] != 1)
631 return 0;
632
633 break;
634 default:
635 panic("unknown pcic socket");
636 }
637
638 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
639 }
640
641 int
642 pcic_print(arg, pnp)
643 void *arg;
644 const char *pnp;
645 {
646 struct pcmciabus_attach_args *paa = arg;
647 struct pcic_handle *h = (struct pcic_handle *) paa->pch;
648
649 /* Only "pcmcia"s can attach to "pcic"s... easy. */
650 if (pnp)
651 printf("pcmcia at %s", pnp);
652
653 switch (h->sock) {
654 case C0SA:
655 printf(" controller 0 socket 0");
656 break;
657 case C0SB:
658 printf(" controller 0 socket 1");
659 break;
660 case C1SA:
661 printf(" controller 1 socket 0");
662 break;
663 case C1SB:
664 printf(" controller 1 socket 1");
665 break;
666 default:
667 panic("unknown pcic socket");
668 }
669
670 return (UNCONF);
671 }
672
673 void
674 pcic_poll_intr(arg)
675 void *arg;
676 {
677 struct pcic_softc *sc;
678 int i, s;
679
680 s = spltty();
681 sc = arg;
682 for (i = 0; i < PCIC_NSLOTS; i++)
683 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
684 (void)pcic_intr_socket(&sc->handle[i]);
685 callout_reset(&sc->poll_ch, hz / 2, pcic_poll_intr, sc);
686 splx(s);
687 }
688
689 int
690 pcic_intr(arg)
691 void *arg;
692 {
693 struct pcic_softc *sc = arg;
694 int i, ret = 0;
695
696 DPRINTF(("%s: intr\n", sc->dev.dv_xname));
697
698 for (i = 0; i < PCIC_NSLOTS; i++)
699 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
700 ret += pcic_intr_socket(&sc->handle[i]);
701
702 return (ret ? 1 : 0);
703 }
704
705 int
706 pcic_intr_socket(h)
707 struct pcic_handle *h;
708 {
709 int cscreg;
710
711 cscreg = pcic_read(h, PCIC_CSC);
712
713 cscreg &= (PCIC_CSC_GPI |
714 PCIC_CSC_CD |
715 PCIC_CSC_READY |
716 PCIC_CSC_BATTWARN |
717 PCIC_CSC_BATTDEAD);
718
719 if (cscreg & PCIC_CSC_GPI) {
720 DPRINTF(("%s: %02x GPI\n", h->ph_parent->dv_xname, h->sock));
721 }
722 if (cscreg & PCIC_CSC_CD) {
723 int statreg;
724
725 statreg = pcic_read(h, PCIC_IF_STATUS);
726
727 DPRINTF(("%s: %02x CD %x\n", h->ph_parent->dv_xname, h->sock,
728 statreg));
729
730 if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
731 PCIC_IF_STATUS_CARDDETECT_PRESENT) {
732 if (h->laststate != PCIC_LASTSTATE_PRESENT) {
733 DPRINTF(("%s: enqueing INSERTION event\n",
734 h->ph_parent->dv_xname));
735 pcic_queue_event(h, PCIC_EVENT_INSERTION);
736 }
737 h->laststate = PCIC_LASTSTATE_PRESENT;
738 } else {
739 if (h->laststate == PCIC_LASTSTATE_PRESENT) {
740 /* Deactivate the card now. */
741 DPRINTF(("%s: deactivating card\n",
742 h->ph_parent->dv_xname));
743 pcic_deactivate_card(h);
744
745 DPRINTF(("%s: enqueing REMOVAL event\n",
746 h->ph_parent->dv_xname));
747 pcic_queue_event(h, PCIC_EVENT_REMOVAL);
748 }
749 h->laststate =
750 ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) == 0) ?
751 PCIC_LASTSTATE_EMPTY : PCIC_LASTSTATE_HALF;
752 }
753 }
754 if (cscreg & PCIC_CSC_READY) {
755 DPRINTF(("%s: %02x READY\n", h->ph_parent->dv_xname, h->sock));
756 /* shouldn't happen */
757 }
758 if (cscreg & PCIC_CSC_BATTWARN) {
759 DPRINTF(("%s: %02x BATTWARN\n", h->ph_parent->dv_xname,
760 h->sock));
761 }
762 if (cscreg & PCIC_CSC_BATTDEAD) {
763 DPRINTF(("%s: %02x BATTDEAD\n", h->ph_parent->dv_xname,
764 h->sock));
765 }
766 return (cscreg ? 1 : 0);
767 }
768
769 void
770 pcic_queue_event(h, event)
771 struct pcic_handle *h;
772 int event;
773 {
774 struct pcic_event *pe;
775 int s;
776
777 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
778 if (pe == NULL)
779 panic("pcic_queue_event: can't allocate event");
780
781 pe->pe_type = event;
782 s = splhigh();
783 SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q);
784 splx(s);
785 wakeup(&h->events);
786 }
787
788 void
789 pcic_attach_card(h)
790 struct pcic_handle *h;
791 {
792
793 if (!(h->flags & PCIC_FLAG_CARDP)) {
794 /* call the MI attach function */
795 pcmcia_card_attach(h->pcmcia);
796
797 h->flags |= PCIC_FLAG_CARDP;
798 } else {
799 DPRINTF(("pcic_attach_card: already attached"));
800 }
801 }
802
803 void
804 pcic_detach_card(h, flags)
805 struct pcic_handle *h;
806 int flags; /* DETACH_* */
807 {
808
809 if (h->flags & PCIC_FLAG_CARDP) {
810 h->flags &= ~PCIC_FLAG_CARDP;
811
812 /* call the MI detach function */
813 pcmcia_card_detach(h->pcmcia, flags);
814 } else {
815 DPRINTF(("pcic_detach_card: already detached"));
816 }
817 }
818
819 void
820 pcic_deactivate_card(h)
821 struct pcic_handle *h;
822 {
823
824 /* call the MI deactivate function */
825 pcmcia_card_deactivate(h->pcmcia);
826
827 /* power down the socket */
828 pcic_write(h, PCIC_PWRCTL, 0);
829
830 /* reset the socket */
831 pcic_write(h, PCIC_INTR, 0);
832 }
833
834 int
835 pcic_chip_mem_alloc(pch, size, pcmhp)
836 pcmcia_chipset_handle_t pch;
837 bus_size_t size;
838 struct pcmcia_mem_handle *pcmhp;
839 {
840 struct pcic_handle *h = (struct pcic_handle *) pch;
841 bus_space_handle_t memh;
842 bus_addr_t addr;
843 bus_size_t sizepg;
844 int i, mask, mhandle;
845 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
846
847 /* out of sc->memh, allocate as many pages as necessary */
848
849 /* convert size to PCIC pages */
850 sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN;
851 if (sizepg > PCIC_MAX_MEM_PAGES)
852 return (1);
853
854 mask = (1 << sizepg) - 1;
855
856 addr = 0; /* XXX gcc -Wuninitialized */
857 mhandle = 0; /* XXX gcc -Wuninitialized */
858
859 for (i = 0; i <= PCIC_MAX_MEM_PAGES - sizepg; i++) {
860 if ((sc->subregionmask & (mask << i)) == (mask << i)) {
861 if (bus_space_subregion(sc->memt, sc->memh,
862 i * PCIC_MEM_PAGESIZE,
863 sizepg * PCIC_MEM_PAGESIZE, &memh))
864 return (1);
865 mhandle = mask << i;
866 addr = sc->membase + (i * PCIC_MEM_PAGESIZE);
867 sc->subregionmask &= ~(mhandle);
868 pcmhp->memt = sc->memt;
869 pcmhp->memh = memh;
870 pcmhp->addr = addr;
871 pcmhp->size = size;
872 pcmhp->mhandle = mhandle;
873 pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
874 return (0);
875 }
876 }
877
878 return (1);
879 }
880
881 void
882 pcic_chip_mem_free(pch, pcmhp)
883 pcmcia_chipset_handle_t pch;
884 struct pcmcia_mem_handle *pcmhp;
885 {
886 struct pcic_handle *h = (struct pcic_handle *) pch;
887 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
888
889 sc->subregionmask |= pcmhp->mhandle;
890 }
891
892 static const struct mem_map_index_st {
893 int sysmem_start_lsb;
894 int sysmem_start_msb;
895 int sysmem_stop_lsb;
896 int sysmem_stop_msb;
897 int cardmem_lsb;
898 int cardmem_msb;
899 int memenable;
900 } mem_map_index[] = {
901 {
902 PCIC_SYSMEM_ADDR0_START_LSB,
903 PCIC_SYSMEM_ADDR0_START_MSB,
904 PCIC_SYSMEM_ADDR0_STOP_LSB,
905 PCIC_SYSMEM_ADDR0_STOP_MSB,
906 PCIC_CARDMEM_ADDR0_LSB,
907 PCIC_CARDMEM_ADDR0_MSB,
908 PCIC_ADDRWIN_ENABLE_MEM0,
909 },
910 {
911 PCIC_SYSMEM_ADDR1_START_LSB,
912 PCIC_SYSMEM_ADDR1_START_MSB,
913 PCIC_SYSMEM_ADDR1_STOP_LSB,
914 PCIC_SYSMEM_ADDR1_STOP_MSB,
915 PCIC_CARDMEM_ADDR1_LSB,
916 PCIC_CARDMEM_ADDR1_MSB,
917 PCIC_ADDRWIN_ENABLE_MEM1,
918 },
919 {
920 PCIC_SYSMEM_ADDR2_START_LSB,
921 PCIC_SYSMEM_ADDR2_START_MSB,
922 PCIC_SYSMEM_ADDR2_STOP_LSB,
923 PCIC_SYSMEM_ADDR2_STOP_MSB,
924 PCIC_CARDMEM_ADDR2_LSB,
925 PCIC_CARDMEM_ADDR2_MSB,
926 PCIC_ADDRWIN_ENABLE_MEM2,
927 },
928 {
929 PCIC_SYSMEM_ADDR3_START_LSB,
930 PCIC_SYSMEM_ADDR3_START_MSB,
931 PCIC_SYSMEM_ADDR3_STOP_LSB,
932 PCIC_SYSMEM_ADDR3_STOP_MSB,
933 PCIC_CARDMEM_ADDR3_LSB,
934 PCIC_CARDMEM_ADDR3_MSB,
935 PCIC_ADDRWIN_ENABLE_MEM3,
936 },
937 {
938 PCIC_SYSMEM_ADDR4_START_LSB,
939 PCIC_SYSMEM_ADDR4_START_MSB,
940 PCIC_SYSMEM_ADDR4_STOP_LSB,
941 PCIC_SYSMEM_ADDR4_STOP_MSB,
942 PCIC_CARDMEM_ADDR4_LSB,
943 PCIC_CARDMEM_ADDR4_MSB,
944 PCIC_ADDRWIN_ENABLE_MEM4,
945 },
946 };
947
948 void
949 pcic_chip_do_mem_map(h, win)
950 struct pcic_handle *h;
951 int win;
952 {
953 int reg;
954 int kind = h->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
955 int mem8 =
956 (h->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8
957 || (kind == PCMCIA_MEM_ATTR);
958
959 DPRINTF(("mem8 %d\n", mem8));
960 /* mem8 = 1; */
961
962 pcic_write(h, mem_map_index[win].sysmem_start_lsb,
963 (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
964 pcic_write(h, mem_map_index[win].sysmem_start_msb,
965 ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
966 PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK) |
967 (mem8 ? 0 : PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT));
968
969 pcic_write(h, mem_map_index[win].sysmem_stop_lsb,
970 ((h->mem[win].addr + h->mem[win].size) >>
971 PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
972 pcic_write(h, mem_map_index[win].sysmem_stop_msb,
973 (((h->mem[win].addr + h->mem[win].size) >>
974 (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
975 PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
976 PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
977
978 pcic_write(h, mem_map_index[win].cardmem_lsb,
979 (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
980 pcic_write(h, mem_map_index[win].cardmem_msb,
981 ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) &
982 PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) |
983 ((kind == PCMCIA_MEM_ATTR) ?
984 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0));
985
986 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
987 reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16);
988 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
989
990 delay(100);
991
992 #ifdef PCICDEBUG
993 {
994 int r1, r2, r3, r4, r5, r6;
995
996 r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb);
997 r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb);
998 r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb);
999 r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb);
1000 r5 = pcic_read(h, mem_map_index[win].cardmem_msb);
1001 r6 = pcic_read(h, mem_map_index[win].cardmem_lsb);
1002
1003 DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x "
1004 "%02x%02x\n", win, r1, r2, r3, r4, r5, r6));
1005 }
1006 #endif
1007 }
1008
1009 int
1010 pcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
1011 pcmcia_chipset_handle_t pch;
1012 int kind;
1013 bus_addr_t card_addr;
1014 bus_size_t size;
1015 struct pcmcia_mem_handle *pcmhp;
1016 bus_size_t *offsetp;
1017 int *windowp;
1018 {
1019 struct pcic_handle *h = (struct pcic_handle *) pch;
1020 bus_addr_t busaddr;
1021 long card_offset;
1022 int i, win;
1023 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
1024
1025 win = -1;
1026 for (i = 0; i < (sizeof(mem_map_index) / sizeof(mem_map_index[0]));
1027 i++) {
1028 if ((h->memalloc & (1 << i)) == 0) {
1029 win = i;
1030 h->memalloc |= (1 << i);
1031 break;
1032 }
1033 }
1034
1035 if (win == -1)
1036 return (1);
1037
1038 *windowp = win;
1039
1040 /* XXX this is pretty gross */
1041
1042 if (sc->memt != pcmhp->memt)
1043 panic("pcic_chip_mem_map memt is bogus");
1044
1045 busaddr = pcmhp->addr;
1046
1047 /*
1048 * compute the address offset to the pcmcia address space for the
1049 * pcic. this is intentionally signed. The masks and shifts below
1050 * will cause TRT to happen in the pcic registers. Deal with making
1051 * sure the address is aligned, and return the alignment offset.
1052 */
1053
1054 *offsetp = card_addr % PCIC_MEM_ALIGN;
1055 card_addr -= *offsetp;
1056
1057 DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr "
1058 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
1059 (u_long) card_addr));
1060
1061 /*
1062 * include the offset in the size, and decrement size by one, since
1063 * the hw wants start/stop
1064 */
1065 size += *offsetp - 1;
1066
1067 card_offset = (((long) card_addr) - ((long) busaddr));
1068
1069 h->mem[win].addr = busaddr;
1070 h->mem[win].size = size;
1071 h->mem[win].offset = card_offset;
1072 h->mem[win].kind = kind;
1073
1074 pcic_chip_do_mem_map(h, win);
1075
1076 return (0);
1077 }
1078
1079 void
1080 pcic_chip_mem_unmap(pch, window)
1081 pcmcia_chipset_handle_t pch;
1082 int window;
1083 {
1084 struct pcic_handle *h = (struct pcic_handle *) pch;
1085 int reg;
1086
1087 if (window >= (sizeof(mem_map_index) / sizeof(mem_map_index[0])))
1088 panic("pcic_chip_mem_unmap: window out of range");
1089
1090 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1091 reg &= ~mem_map_index[window].memenable;
1092 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1093
1094 h->memalloc &= ~(1 << window);
1095 }
1096
1097 int
1098 pcic_chip_io_alloc(pch, start, size, align, pcihp)
1099 pcmcia_chipset_handle_t pch;
1100 bus_addr_t start;
1101 bus_size_t size;
1102 bus_size_t align;
1103 struct pcmcia_io_handle *pcihp;
1104 {
1105 struct pcic_handle *h = (struct pcic_handle *) pch;
1106 bus_space_tag_t iot;
1107 bus_space_handle_t ioh;
1108 bus_addr_t ioaddr;
1109 int flags = 0;
1110 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
1111
1112 /*
1113 * Allocate some arbitrary I/O space.
1114 */
1115
1116 iot = sc->iot;
1117
1118 if (start) {
1119 ioaddr = start;
1120 if (bus_space_map(iot, start, size, 0, &ioh))
1121 return (1);
1122 DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
1123 (u_long) ioaddr, (u_long) size));
1124 } else {
1125 flags |= PCMCIA_IO_ALLOCATED;
1126 if (bus_space_alloc(iot, sc->iobase,
1127 sc->iobase + sc->iosize, size, align, 0, 0,
1128 &ioaddr, &ioh))
1129 return (1);
1130 DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
1131 (u_long) ioaddr, (u_long) size));
1132 }
1133
1134 pcihp->iot = iot;
1135 pcihp->ioh = ioh;
1136 pcihp->addr = ioaddr;
1137 pcihp->size = size;
1138 pcihp->flags = flags;
1139
1140 return (0);
1141 }
1142
1143 void
1144 pcic_chip_io_free(pch, pcihp)
1145 pcmcia_chipset_handle_t pch;
1146 struct pcmcia_io_handle *pcihp;
1147 {
1148 bus_space_tag_t iot = pcihp->iot;
1149 bus_space_handle_t ioh = pcihp->ioh;
1150 bus_size_t size = pcihp->size;
1151
1152 if (pcihp->flags & PCMCIA_IO_ALLOCATED)
1153 bus_space_free(iot, ioh, size);
1154 else
1155 bus_space_unmap(iot, ioh, size);
1156 }
1157
1158
1159 static const struct io_map_index_st {
1160 int start_lsb;
1161 int start_msb;
1162 int stop_lsb;
1163 int stop_msb;
1164 int ioenable;
1165 int ioctlmask;
1166 int ioctlbits[3]; /* indexed by PCMCIA_WIDTH_* */
1167 } io_map_index[] = {
1168 {
1169 PCIC_IOADDR0_START_LSB,
1170 PCIC_IOADDR0_START_MSB,
1171 PCIC_IOADDR0_STOP_LSB,
1172 PCIC_IOADDR0_STOP_MSB,
1173 PCIC_ADDRWIN_ENABLE_IO0,
1174 PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
1175 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK,
1176 {
1177 PCIC_IOCTL_IO0_IOCS16SRC_CARD,
1178 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
1179 PCIC_IOCTL_IO0_DATASIZE_8BIT,
1180 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
1181 PCIC_IOCTL_IO0_DATASIZE_16BIT,
1182 },
1183 },
1184 {
1185 PCIC_IOADDR1_START_LSB,
1186 PCIC_IOADDR1_START_MSB,
1187 PCIC_IOADDR1_STOP_LSB,
1188 PCIC_IOADDR1_STOP_MSB,
1189 PCIC_ADDRWIN_ENABLE_IO1,
1190 PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
1191 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK,
1192 {
1193 PCIC_IOCTL_IO1_IOCS16SRC_CARD,
1194 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
1195 PCIC_IOCTL_IO1_DATASIZE_8BIT,
1196 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
1197 PCIC_IOCTL_IO1_DATASIZE_16BIT,
1198 },
1199 },
1200 };
1201
1202 void
1203 pcic_chip_do_io_map(h, win)
1204 struct pcic_handle *h;
1205 int win;
1206 {
1207 int reg;
1208
1209 DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
1210 win, (long) h->io[win].addr, (long) h->io[win].size,
1211 h->io[win].width * 8));
1212
1213 pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff);
1214 pcic_write(h, io_map_index[win].start_msb,
1215 (h->io[win].addr >> 8) & 0xff);
1216
1217 pcic_write(h, io_map_index[win].stop_lsb,
1218 (h->io[win].addr + h->io[win].size - 1) & 0xff);
1219 pcic_write(h, io_map_index[win].stop_msb,
1220 ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff);
1221
1222 reg = pcic_read(h, PCIC_IOCTL);
1223 reg &= ~io_map_index[win].ioctlmask;
1224 reg |= io_map_index[win].ioctlbits[h->io[win].width];
1225 pcic_write(h, PCIC_IOCTL, reg);
1226
1227 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1228 reg |= io_map_index[win].ioenable;
1229 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1230 }
1231
1232 int
1233 pcic_chip_io_map(pch, width, offset, size, pcihp, windowp)
1234 pcmcia_chipset_handle_t pch;
1235 int width;
1236 bus_addr_t offset;
1237 bus_size_t size;
1238 struct pcmcia_io_handle *pcihp;
1239 int *windowp;
1240 {
1241 struct pcic_handle *h = (struct pcic_handle *) pch;
1242 bus_addr_t ioaddr = pcihp->addr + offset;
1243 int i, win;
1244 #ifdef PCICDEBUG
1245 static char *width_names[] = { "auto", "io8", "io16" };
1246 #endif
1247 struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
1248
1249 /* XXX Sanity check offset/size. */
1250
1251 win = -1;
1252 for (i = 0; i < (sizeof(io_map_index) / sizeof(io_map_index[0])); i++) {
1253 if ((h->ioalloc & (1 << i)) == 0) {
1254 win = i;
1255 h->ioalloc |= (1 << i);
1256 break;
1257 }
1258 }
1259
1260 if (win == -1)
1261 return (1);
1262
1263 *windowp = win;
1264
1265 /* XXX this is pretty gross */
1266
1267 if (sc->iot != pcihp->iot)
1268 panic("pcic_chip_io_map iot is bogus");
1269
1270 DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
1271 win, width_names[width], (u_long) ioaddr, (u_long) size));
1272
1273 /* XXX wtf is this doing here? */
1274
1275 printf(" port 0x%lx", (u_long) ioaddr);
1276 if (size > 1)
1277 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
1278
1279 h->io[win].addr = ioaddr;
1280 h->io[win].size = size;
1281 h->io[win].width = width;
1282
1283 pcic_chip_do_io_map(h, win);
1284
1285 return (0);
1286 }
1287
1288 void
1289 pcic_chip_io_unmap(pch, window)
1290 pcmcia_chipset_handle_t pch;
1291 int window;
1292 {
1293 struct pcic_handle *h = (struct pcic_handle *) pch;
1294 int reg;
1295
1296 if (window >= (sizeof(io_map_index) / sizeof(io_map_index[0])))
1297 panic("pcic_chip_io_unmap: window out of range");
1298
1299 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1300 reg &= ~io_map_index[window].ioenable;
1301 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1302
1303 h->ioalloc &= ~(1 << window);
1304 }
1305
1306 static void
1307 pcic_wait_ready(h)
1308 struct pcic_handle *h;
1309 {
1310 int i;
1311
1312 /* wait an initial 10ms for quick cards */
1313 if (pcic_read(h, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY)
1314 return;
1315 pcic_delay(h, 10, "pccwr0");
1316 for (i = 0; i < 50; i++) {
1317 if (pcic_read(h, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY)
1318 return;
1319 /* wait .1s (100ms) each iteration now */
1320 pcic_delay(h, 100, "pccwr1");
1321 #ifdef PCICDEBUG
1322 if (pcic_debug) {
1323 if ((i > 20) && (i % 100 == 99))
1324 printf(".");
1325 }
1326 #endif
1327 }
1328
1329 #ifdef DIAGNOSTIC
1330 printf("pcic_wait_ready: ready never happened, status = %02x\n",
1331 pcic_read(h, PCIC_IF_STATUS));
1332 #endif
1333 }
1334
1335 /*
1336 * Perform long (msec order) delay.
1337 */
1338 static void
1339 pcic_delay(h, timo, wmesg)
1340 struct pcic_handle *h;
1341 int timo; /* in ms. must not be zero */
1342 const char *wmesg;
1343 {
1344
1345 #ifdef DIAGNOSTIC
1346 if (timo <= 0) {
1347 printf("called with timeout %d\n", timo);
1348 panic("pcic_delay");
1349 }
1350 if (curproc == NULL) {
1351 printf("called in interrupt context\n");
1352 panic("pcic_delay");
1353 }
1354 if (h->event_thread == NULL) {
1355 printf("no event thread\n");
1356 panic("pcic_delay");
1357 }
1358 #endif
1359 DPRINTF(("pcic_delay: \"%s\" %p, sleep %d ms\n",
1360 wmesg, h->event_thread, timo));
1361 tsleep(pcic_delay, PWAIT, wmesg, roundup(timo * hz, 1000) / 1000);
1362 }
1363
1364 void
1365 pcic_chip_socket_enable(pch)
1366 pcmcia_chipset_handle_t pch;
1367 {
1368 struct pcic_handle *h = (struct pcic_handle *) pch;
1369 int cardtype, win, intr, pwr;
1370 #if defined(DIAGNOSTIC) || defined(PCICDEBUG)
1371 int reg;
1372 #endif
1373
1374 #ifdef DIAGNOSTIC
1375 if (h->flags & PCIC_FLAG_ENABLED)
1376 printf("pcic_chip_socket_enable: enabling twice\n");
1377 #endif
1378
1379 /* disable interrupts */
1380 intr = pcic_read(h, PCIC_INTR);
1381 intr &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE);
1382 pcic_write(h, PCIC_INTR, intr);
1383
1384 /* power down the socket to reset it, clear the card reset pin */
1385 pwr = 0;
1386 pcic_write(h, PCIC_PWRCTL, pwr);
1387
1388 /*
1389 * wait 300ms until power fails (Tpf). Then, wait 100ms since
1390 * we are changing Vcc (Toff).
1391 */
1392 pcic_delay(h, 300 + 100, "pccen0");
1393
1394 #ifdef VADEM_POWER_HACK
1395 bus_space_write_1(sc->iot, sc->ioh, PCIC_REG_INDEX, 0x0e);
1396 bus_space_write_1(sc->iot, sc->ioh, PCIC_REG_INDEX, 0x37);
1397 printf("prcr = %02x\n", pcic_read(h, 0x02));
1398 printf("cvsr = %02x\n", pcic_read(h, 0x2f));
1399 printf("DANGER WILL ROBINSON! Changing voltage select!\n");
1400 pcic_write(h, 0x2f, pcic_read(h, 0x2f) & ~0x03);
1401 printf("cvsr = %02x\n", pcic_read(h, 0x2f));
1402 #endif
1403 /* power up the socket */
1404 pwr |= PCIC_PWRCTL_DISABLE_RESETDRV | PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_VPP1_VCC;
1405 pcic_write(h, PCIC_PWRCTL, pwr);
1406
1407 /*
1408 * wait 100ms until power raise (Tpr) and 20ms to become
1409 * stable (Tsu(Vcc)).
1410 *
1411 * some machines require some more time to be settled
1412 * (300ms is added here).
1413 */
1414 pcic_delay(h, 100 + 20 + 300, "pccen1");
1415 pwr |= PCIC_PWRCTL_OE;
1416 pcic_write(h, PCIC_PWRCTL, pwr);
1417
1418 /* now make sure we have reset# active */
1419 intr &= ~PCIC_INTR_RESET;
1420 pcic_write(h, PCIC_INTR, intr);
1421
1422 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_DISABLE_RESETDRV |
1423 PCIC_PWRCTL_OE | PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_VPP1_VCC);
1424 /*
1425 * hold RESET at least 10us, this is a min allow for slop in
1426 * delay routine.
1427 */
1428 delay(20);
1429
1430 /* clear the reset flag */
1431 intr |= PCIC_INTR_RESET;
1432 pcic_write(h, PCIC_INTR, intr);
1433
1434 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
1435 pcic_delay(h, 20, "pccen2");
1436
1437 #ifdef DIAGNOSTIC
1438 reg = pcic_read(h, PCIC_IF_STATUS);
1439 if (!(reg & PCIC_IF_STATUS_POWERACTIVE)) {
1440 printf("pcic_chip_socket_enable: status %x\n", reg);
1441 }
1442 #endif
1443 /* wait for the chip to finish initializing */
1444 pcic_wait_ready(h);
1445
1446 /* zero out the address windows */
1447 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
1448
1449 /* set the card type and enable the interrupt */
1450 cardtype = pcmcia_card_gettype(h->pcmcia);
1451 intr |= ((cardtype == PCMCIA_IFTYPE_IO) ?
1452 PCIC_INTR_CARDTYPE_IO : PCIC_INTR_CARDTYPE_MEM);
1453 pcic_write(h, PCIC_INTR, intr);
1454
1455 DPRINTF(("%s: pcic_chip_socket_enable %02x cardtype %s %02x\n",
1456 h->ph_parent->dv_xname, h->sock,
1457 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), reg));
1458
1459 /* reinstall all the memory and io mappings */
1460 for (win = 0; win < PCIC_MEM_WINS; win++)
1461 if (h->memalloc & (1 << win))
1462 pcic_chip_do_mem_map(h, win);
1463 for (win = 0; win < PCIC_IO_WINS; win++)
1464 if (h->ioalloc & (1 << win))
1465 pcic_chip_do_io_map(h, win);
1466
1467 h->flags |= PCIC_FLAG_ENABLED;
1468
1469 /* finally enable the interrupt */
1470 intr |= h->ih_irq;
1471 pcic_write(h, PCIC_INTR, intr);
1472 }
1473
1474 void
1475 pcic_chip_socket_disable(pch)
1476 pcmcia_chipset_handle_t pch;
1477 {
1478 struct pcic_handle *h = (struct pcic_handle *) pch;
1479 int intr;
1480
1481 DPRINTF(("pcic_chip_socket_disable\n"));
1482
1483 /* disable interrupts */
1484 intr = pcic_read(h, PCIC_INTR);
1485 intr &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE);
1486 pcic_write(h, PCIC_INTR, intr);
1487
1488 /* power down the socket */
1489 pcic_write(h, PCIC_PWRCTL, 0);
1490
1491 /* zero out the address windows */
1492 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
1493
1494 h->flags &= ~PCIC_FLAG_ENABLED;
1495 }
1496
1497 static u_int8_t
1498 st_pcic_read(h, idx)
1499 struct pcic_handle *h;
1500 int idx;
1501 {
1502
1503 if (idx != -1)
1504 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX,
1505 h->sock + idx);
1506 return (bus_space_read_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA));
1507 }
1508
1509 static void
1510 st_pcic_write(h, idx, data)
1511 struct pcic_handle *h;
1512 int idx;
1513 u_int8_t data;
1514 {
1515
1516 if (idx != -1)
1517 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX,
1518 h->sock + idx);
1519 bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA, data);
1520 }
1521