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