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