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