i82365.c revision 1.1.2.3 1 #define PCICDEBUG
2
3 #include <sys/types.h>
4 #include <sys/param.h>
5 #include <sys/systm.h>
6 #include <sys/device.h>
7 #include <sys/extent.h>
8 #include <sys/malloc.h>
9
10 #include <vm/vm.h>
11
12 #include <machine/bus.h>
13 #include <machine/intr.h>
14
15 #include <dev/isa/isareg.h>
16 #include <dev/isa/isavar.h>
17
18 #include <dev/pcmcia/pcmciareg.h>
19 #include <dev/pcmcia/pcmciachip.h>
20
21 #include <dev/ic/i82365reg.h>
22
23 #ifdef PCICDEBUG
24 int pcic_debug = 0;
25 #define DPRINTF(arg) if (pcic_debug) printf arg;
26 #else
27 #define DPRINTF(arg)
28 #endif
29
30 /* This is sort of arbitrary. It merely needs to be "enough".
31 It can be overridden in the conf file, anyway. */
32
33 #define PCIC_MEM_PAGES 4
34 #define PCIC_MEMSIZE PCIC_MEM_PAGES*PCIC_MEM_PAGESIZE
35
36 #define PCIC_NSLOTS 4
37
38 #define PCIC_FLAG_SOCKETP 0x0001
39 #define PCIC_FLAG_CARDP 0x0002
40
41 #define PCIC_VENDOR_UNKNOWN 0
42 #define PCIC_VENDOR_I82365SLR0 1
43 #define PCIC_VENDOR_I82365SLR1 2
44 #define PCIC_VENDOR_CIRRUS_PD6710 3
45 #define PCIC_VENDOR_CIRRUS_PD672X 4
46
47 struct pcic_handle {
48 struct pcic_softc *sc;
49 int vendor;
50 int sock;
51 int flags;
52 int memalloc;
53 int ioalloc;
54 struct device *pcmcia;
55 };
56
57 struct pcic_softc {
58 struct device dev;
59
60 isa_chipset_tag_t ic;
61
62 bus_space_tag_t memt;
63 bus_space_tag_t memh;
64 bus_space_tag_t iot;
65 bus_space_tag_t ioh;
66
67 /* this needs to be large enough to hold PCIC_MEM_PAGES bits */
68 int subregionmask;
69
70 int irq;
71 void *ih;
72
73 struct pcic_handle handle[PCIC_NSLOTS];
74 };
75
76 #define C0SA PCIC_CHIP0_BASE+PCIC_SOCKETA_INDEX
77 #define C0SB PCIC_CHIP0_BASE+PCIC_SOCKETB_INDEX
78 #define C1SA PCIC_CHIP1_BASE+PCIC_SOCKETA_INDEX
79 #define C1SB PCIC_CHIP1_BASE+PCIC_SOCKETB_INDEX
80
81 /* Individual drivers will allocate their own memory and io regions.
82 Memory regions must be a multiple of 4k, aligned on a 4k boundary. */
83
84 #define PCIC_MEM_ALIGN PCIC_MEM_PAGESIZE
85
86 int pcic_probe __P((struct device *, void *, void *));
87 void pcic_attach __P((struct device *, struct device *, void *));
88
89 int pcic_ident_ok __P((int));
90 int pcic_vendor __P((struct pcic_handle *));
91 char *pcic_vendor_to_string __P((int));
92 static inline int pcic_read __P((struct pcic_handle *, int));
93 static inline void pcic_write __P((struct pcic_handle *, int, int));
94 static inline void pcic_wait_ready __P((struct pcic_handle *));
95 void pcic_attach_socket __P((struct pcic_handle *));
96 void pcic_init_socket __P((struct pcic_handle *));
97
98 #ifdef __BROKEN_INDIRECT_CONFIG
99 int pcic_submatch __P((struct device *, void *, void *));
100 #else
101 int pcic_submatch __P((struct device *, struct cfdata *, void *));
102 #endif
103 int pcic_print __P((void *arg, const char *pnp));
104 int pcic_intr __P((void *arg));
105 int pcic_intr_socket __P((struct pcic_handle *));
106
107 int pcic_chip_mem_alloc __P((pcmcia_chipset_handle_t, bus_size_t,
108 bus_space_tag_t *, bus_space_handle_t *,
109 pcmcia_mem_handle_t *, bus_size_t *));
110 void pcic_chip_mem_free __P((pcmcia_chipset_handle_t, bus_size_t,
111 bus_space_tag_t, bus_space_handle_t,
112 pcmcia_mem_handle_t));
113 int pcic_chip_mem_map __P((pcmcia_chipset_handle_t, int,
114 bus_size_t, bus_space_tag_t, bus_space_handle_t,
115 u_long, u_long *, int *));
116 void pcic_chip_mem_unmap __P((pcmcia_chipset_handle_t, int));
117
118 int pcic_chip_io_alloc __P((pcmcia_chipset_handle_t, bus_addr_t, bus_size_t,
119 bus_space_tag_t *, bus_space_handle_t *));
120 void pcic_chip_io_free __P((pcmcia_chipset_handle_t, bus_size_t,
121 bus_space_tag_t, bus_space_handle_t));
122 int pcic_chip_io_map __P((pcmcia_chipset_handle_t, int, bus_size_t,
123 bus_space_tag_t, bus_space_handle_t, int *));
124 void pcic_chip_io_unmap __P((pcmcia_chipset_handle_t, int));
125
126 void *pcic_chip_intr_establish __P((pcmcia_chipset_handle_t, u_int16_t, int,
127 int (*)(void *), void *));
128 void pcic_chip_intr_disestablish __P((pcmcia_chipset_handle_t, void *));
129
130
131 void pcic_attach_card(struct pcic_handle *);
132 void pcic_detach_card(struct pcic_handle *);
133
134 static struct pcmcia_chip_functions pcic_functions = {
135 pcic_chip_mem_alloc,
136 pcic_chip_mem_free,
137 pcic_chip_mem_map,
138 pcic_chip_mem_unmap,
139
140 pcic_chip_io_alloc,
141 pcic_chip_io_free,
142 pcic_chip_io_map,
143 pcic_chip_io_unmap,
144
145 pcic_chip_intr_establish,
146 pcic_chip_intr_disestablish,
147 };
148
149 struct cfdriver pcic_cd = {
150 NULL, "pcic", DV_DULL
151 };
152
153 struct cfattach pcic_ca = {
154 sizeof(struct pcic_softc), pcic_probe, pcic_attach
155 };
156
157 static inline int
158 pcic_read(h, idx)
159 struct pcic_handle *h;
160 int idx;
161 {
162 if (idx != -1)
163 bus_space_write_1(h->sc->iot, h->sc->ioh, PCIC_REG_INDEX, h->sock+idx);
164 return(bus_space_read_1(h->sc->iot, h->sc->ioh, PCIC_REG_DATA));
165 }
166
167 static inline void
168 pcic_write(h, idx, data)
169 struct pcic_handle *h;
170 int idx;
171 int data;
172 {
173 if (idx != -1)
174 bus_space_write_1(h->sc->iot, h->sc->ioh, PCIC_REG_INDEX, h->sock+idx);
175 bus_space_write_1(h->sc->iot, h->sc->ioh, PCIC_REG_DATA, (data));
176 }
177
178 static inline void
179 pcic_wait_ready(h)
180 struct pcic_handle *h;
181 {
182 int i;
183
184 for (i=0; i<10000; i++) {
185 if (pcic_read(h, PCIC_IF_STATUS) & PCIC_IF_STATUS_READY)
186 return;
187 delay(500);
188 }
189
190 DPRINTF(("pcic_wait_ready ready never happened\n"));
191 }
192
193 int
194 pcic_ident_ok(ident)
195 int ident;
196 {
197 /* this is very empirical and heuristic */
198
199 if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO))
200 return(0);
201
202 if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) {
203 #ifdef DIAGNOSTIC
204 printf("pcic: does not support memory and I/O cards, ignored (ident=%0x)\n",
205 ident);
206 #endif
207 return(0);
208 }
209
210 return(1);
211 }
212
213 int
214 pcic_vendor(h)
215 struct pcic_handle *h;
216 {
217 int reg;
218
219 /* I can't claim to understand this; I'm just doing what the
220 linux driver does */
221
222 pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0);
223 reg = pcic_read(h, -1);
224
225 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) ==
226 PCIC_CIRRUS_CHIP_INFO_CHIP_ID) {
227 reg = pcic_read(h, -1);
228 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) {
229 if (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS)
230 return(PCIC_VENDOR_CIRRUS_PD672X);
231 else
232 return(PCIC_VENDOR_CIRRUS_PD6710);
233 }
234 }
235
236 reg = pcic_read(h, PCIC_IDENT);
237
238 if ((reg & PCIC_IDENT_REV_MASK) == PCIC_IDENT_REV_I82365SLR0)
239 return(PCIC_VENDOR_I82365SLR0);
240 else
241 return(PCIC_VENDOR_I82365SLR1);
242
243 return(PCIC_VENDOR_UNKNOWN);
244 }
245
246 char *
247 pcic_vendor_to_string(vendor)
248 int vendor;
249 {
250 switch (vendor) {
251 case PCIC_VENDOR_I82365SLR0:
252 return("Intel 82365SL Revision 0");
253 case PCIC_VENDOR_I82365SLR1:
254 return("Intel 82365SL Revision 1");
255 case PCIC_VENDOR_CIRRUS_PD6710:
256 return("Cirrus PD6710");
257 case PCIC_VENDOR_CIRRUS_PD672X:
258 return("Cirrus PD672X");
259 }
260
261 return("Unknown controller");
262 }
263
264 int
265 pcic_probe(parent, match, aux)
266 struct device *parent;
267 void *match, *aux;
268 {
269 struct isa_attach_args *ia = aux;
270 bus_space_tag_t iot = ia->ia_iot;
271 bus_space_handle_t ioh, memh;
272 int val, found;
273
274 DPRINTF(("pcic_probe %x\n", ia->ia_iobase));
275
276 if (bus_space_map(iot, ia->ia_iobase, PCIC_IOSIZE, 0, &ioh))
277 return (0);
278
279 if (ia->ia_msize == -1)
280 ia->ia_msize = PCIC_MEMSIZE;
281
282 if (bus_space_map(ia->ia_memt, ia->ia_maddr, ia->ia_msize, 0, &memh))
283 return (0);
284
285 found = 0;
286
287 /* this could be done with a loop, but it would violate the
288 abstraction */
289
290 bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SA+PCIC_IDENT);
291
292 val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
293
294 DPRINTF(("c0sa ident = %02x, ", val));
295
296 if (pcic_ident_ok(val))
297 found++;
298
299
300 bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SB+PCIC_IDENT);
301
302 val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
303
304 DPRINTF(("c0sb ident = %02x, ", val));
305
306 if (pcic_ident_ok(val))
307 found++;
308
309
310 bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SA+PCIC_IDENT);
311
312 val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
313
314 DPRINTF(("c1sa ident = %02x, ", val));
315
316 if (pcic_ident_ok(val))
317 found++;
318
319
320 bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SB+PCIC_IDENT);
321
322 val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
323
324 DPRINTF(("c1sb ident = %02x\n", val));
325
326 if (pcic_ident_ok(val))
327 found++;
328
329
330 bus_space_unmap(iot, ioh, PCIC_IOSIZE);
331 bus_space_unmap(ia->ia_memt, memh, ia->ia_msize);
332
333 if (!found)
334 return(0);
335
336 ia->ia_iosize = PCIC_IOSIZE;
337
338 return(1);
339 }
340
341 void
342 pcic_attach(parent, self, aux)
343 struct device *parent, *self;
344 void *aux;
345 {
346 struct pcic_softc *sc = (void *)self;
347 struct isa_attach_args *ia = aux;
348 isa_chipset_tag_t ic = ia->ia_ic;
349 bus_space_tag_t iot = ia->ia_iot;
350 bus_space_tag_t memt = ia->ia_memt;
351 bus_space_handle_t ioh;
352 bus_space_handle_t memh;
353 int vendor, count, irq, i;
354
355 /* Map i/o space. */
356 if (bus_space_map(iot, ia->ia_iobase, ia->ia_iosize, 0, &ioh))
357 panic("pcic_attach: can't map i/o space");
358
359 /* Map mem space. */
360 if (bus_space_map(memt, ia->ia_maddr, ia->ia_msize, 0, &memh))
361 panic("pcic_attach: can't map i/o space");
362
363 sc->subregionmask = (1<<(ia->ia_msize/PCIC_MEM_PAGESIZE))-1;
364
365 sc->ic = ic;
366
367 sc->iot = iot;
368 sc->ioh = ioh;
369 sc->memt = memt;
370 sc->memh = memh;
371
372 /* now check for each controller/socket */
373
374 /* this could be done with a loop, but it would violate the
375 abstraction */
376
377 count = 0;
378
379 sc->handle[0].sc = sc;
380 sc->handle[0].sock = C0SA;
381 if (pcic_ident_ok(pcic_read(&sc->handle[0], PCIC_IDENT))) {
382 sc->handle[0].flags = PCIC_FLAG_SOCKETP;
383 count++;
384 } else {
385 sc->handle[0].flags = 0;
386 }
387
388 sc->handle[1].sc = sc;
389 sc->handle[1].sock = C0SB;
390 if (pcic_ident_ok(pcic_read(&sc->handle[1], PCIC_IDENT))) {
391 sc->handle[1].flags = PCIC_FLAG_SOCKETP;
392 count++;
393 } else {
394 sc->handle[1].flags = 0;
395 }
396
397 sc->handle[2].sc = sc;
398 sc->handle[2].sock = C1SA;
399 if (pcic_ident_ok(pcic_read(&sc->handle[2], PCIC_IDENT))) {
400 sc->handle[2].flags = PCIC_FLAG_SOCKETP;
401 count++;
402 } else {
403 sc->handle[2].flags = 0;
404 }
405
406 sc->handle[3].sc = sc;
407 sc->handle[3].sock = C1SB;
408 if (pcic_ident_ok(pcic_read(&sc->handle[3], PCIC_IDENT))) {
409 sc->handle[3].flags = PCIC_FLAG_SOCKETP;
410 count++;
411 } else {
412 sc->handle[3].flags = 0;
413 }
414
415 if (count == 0)
416 panic("pcic_attach: attach found no sockets");
417
418 /* allocate an irq. it will be used by both controllers. I could
419 use two different interrupts, but interrupts are relatively
420 scarce, shareable, and for PCIC controllers, very infrequent. */
421
422 if (ia->ia_irq == IRQUNK) {
423 isa_intr_alloc(ic, PCIC_CSC_INTR_IRQ_VALIDMASK, IST_EDGE, &irq);
424 sc->irq = irq;
425
426 printf(": using irq %d", irq);
427 }
428
429 printf("\n");
430
431 /* establish the interrupt */
432
433 /* XXX block interrupts? */
434
435 for (i=0; i<PCIC_NSLOTS; i++) {
436 pcic_write(&sc->handle[i], PCIC_CSC_INTR, 0);
437 pcic_read(&sc->handle[i], PCIC_CSC);
438 }
439
440 sc->ih = isa_intr_establish(ic, irq, IST_EDGE, IPL_TTY, pcic_intr, sc);
441
442 if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) ||
443 (sc->handle[1].flags & PCIC_FLAG_SOCKETP)) {
444 vendor = pcic_vendor(&sc->handle[0]);
445
446 printf("%s: controller 0 (%s) has ", sc->dev.dv_xname,
447 pcic_vendor_to_string(vendor));
448
449 if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) &&
450 (sc->handle[1].flags & PCIC_FLAG_SOCKETP))
451 printf("sockets A and B\n");
452 else if (sc->handle[0].flags & PCIC_FLAG_SOCKETP)
453 printf("socket A only\n");
454 else
455 printf("socket B only\n");
456
457 #if 0
458 pcic_write(&sc->handle[0], PCIC_GLOBAL_CTL,
459 PCIC_GLOBAL_CTL_EXPLICIT_CSC_ACK);
460 #endif
461
462 if (sc->handle[0].flags & PCIC_FLAG_SOCKETP) {
463 sc->handle[0].vendor = vendor;
464 pcic_attach_socket(&sc->handle[0]);
465 }
466 if (sc->handle[1].flags & PCIC_FLAG_SOCKETP) {
467 sc->handle[1].vendor = vendor;
468 pcic_attach_socket(&sc->handle[1]);
469 }
470 }
471
472 if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) ||
473 (sc->handle[3].flags & PCIC_FLAG_SOCKETP)) {
474 vendor = pcic_vendor(&sc->handle[2]);
475
476 printf("%s: controller 1 (%s) has ", sc->dev.dv_xname,
477 pcic_vendor_to_string(vendor));
478
479 if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) &&
480 (sc->handle[3].flags & PCIC_FLAG_SOCKETP))
481 printf("sockets A and B\n");
482 else if (sc->handle[2].flags & PCIC_FLAG_SOCKETP)
483 printf("socket A only\n");
484 else
485 printf("socket B only\n");
486
487 #if 0
488 pcic_write(&sc->handle[2], PCIC_GLOBAL_CTL,
489 PCIC_GLOBAL_CTL_EXPLICIT_CSC_ACK);
490 #endif
491
492 if (sc->handle[2].flags & PCIC_FLAG_SOCKETP) {
493 pcic_attach_socket(&sc->handle[2]);
494 sc->handle[2].vendor = vendor;
495 }
496 if (sc->handle[3].flags & PCIC_FLAG_SOCKETP) {
497 pcic_attach_socket(&sc->handle[3]);
498 sc->handle[3].vendor = vendor;
499 }
500 }
501 }
502
503 void
504 pcic_attach_socket(h)
505 struct pcic_handle *h;
506 {
507 struct pcmciabus_attach_args paa;
508
509 /* initialize the rest of the handle */
510
511 h->memalloc = 0;
512 h->ioalloc = 0;
513
514 /* now, config one pcmcia device per socket */
515
516 paa.pct = (pcmcia_chipset_tag_t) &pcic_functions;
517 paa.pch = (pcmcia_chipset_handle_t) h;
518
519 h->pcmcia = config_found_sm(&h->sc->dev, &paa, pcic_print, pcic_submatch);
520
521 /* if there's actually a pcmcia device attached, initialize the slot */
522
523 if (h->pcmcia)
524 pcic_init_socket(h);
525 }
526
527 void
528 pcic_init_socket(h)
529 struct pcic_handle *h;
530 {
531 int reg;
532
533 /* set up the card to interrupt on card detect */
534
535 pcic_write(h, PCIC_CSC_INTR,
536 (h->sc->irq<<PCIC_CSC_INTR_IRQ_SHIFT)|
537 PCIC_CSC_INTR_CD_ENABLE);
538 pcic_write(h, PCIC_INTR, 0);
539 pcic_read(h, PCIC_CSC);
540
541 /* unsleep the cirrus controller */
542
543 if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) ||
544 (h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) {
545 reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
546 if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
547 DPRINTF(("%s: socket %02x was suspended\n", h->sc->dev.dv_xname,
548 h->sock));
549 reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
550 pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
551 }
552 }
553
554 /* if there's a card there, then attach it. */
555
556 reg = pcic_read(h, PCIC_IF_STATUS);
557
558 if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
559 PCIC_IF_STATUS_CARDDETECT_PRESENT)
560 pcic_attach_card(h);
561 }
562
563 int
564 #ifdef __BROKEN_INDIRECT_CONFIG
565 pcic_submatch(parent, match, aux)
566 #else
567 pcic_submatch(parent, cf, aux)
568 #endif
569 struct device *parent;
570 #ifdef __BROKEN_INDIRECT_CONFIG
571 void *match;
572 #else
573 struct cfdata *cf;
574 #endif
575 void *aux;
576 {
577 #ifdef __BROKEN_INDIRECT_CONFIG
578 struct cfdata *cf = match;
579 #endif
580
581 struct pcmciabus_attach_args *paa = (struct pcmciabus_attach_args *) aux;
582 struct pcic_handle *h = (struct pcic_handle *) paa->pch;
583
584 switch (h->sock) {
585 case C0SA:
586 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
587 return 0;
588 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
589 return 0;
590
591 break;
592 case C0SB:
593 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
594 return 0;
595 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
596 return 0;
597
598 break;
599 case C1SA:
600 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
601 return 0;
602 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
603 return 0;
604
605 break;
606 case C1SB:
607 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
608 return 0;
609 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
610 return 0;
611
612 break;
613 default:
614 panic("unknown pcic socket");
615 }
616
617 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
618 }
619
620 int
621 pcic_print(arg, pnp)
622 void *arg;
623 const char *pnp;
624 {
625 struct pcmciabus_attach_args *paa = (struct pcmciabus_attach_args *) arg;
626 struct pcic_handle *h = (struct pcic_handle *) paa->pch;
627
628 if (pnp)
629 printf("pcmcia at %s", pnp);
630
631 switch (h->sock) {
632 case C0SA:
633 printf(" controller 0 socket 0");
634 break;
635 case C0SB:
636 printf(" controller 0 socket 1");
637 break;
638 case C1SA:
639 printf(" controller 1 socket 0");
640 break;
641 case C1SB:
642 printf(" controller 1 socket 1");
643 break;
644 default:
645 panic("unknown pcic socket");
646 }
647
648 return(UNCONF);
649 }
650
651 int
652 pcic_intr(arg)
653 void *arg;
654 {
655 struct pcic_softc *sc = (struct pcic_softc *) arg;
656 int i, ret = 0;
657
658 DPRINTF(("%s: intr\n", sc->dev.dv_xname));
659
660 for (i=0; i<PCIC_NSLOTS; i++)
661 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
662 ret += pcic_intr_socket(&sc->handle[i]);
663
664 return(ret?1:0);
665 }
666
667 int
668 pcic_intr_socket(h)
669 struct pcic_handle *h;
670 {
671 int cscreg;
672
673 cscreg = pcic_read(h, PCIC_CSC);
674
675 cscreg &= (PCIC_CSC_GPI |
676 PCIC_CSC_CD |
677 PCIC_CSC_READY |
678 PCIC_CSC_BATTWARN |
679 PCIC_CSC_BATTDEAD);
680
681 if (cscreg & PCIC_CSC_GPI) {
682 DPRINTF(("%s: %02x GPI\n", h->sc->dev.dv_xname, h->sock));
683 }
684 if (cscreg & PCIC_CSC_CD) {
685 int statreg;
686
687 statreg = pcic_read(h, PCIC_IF_STATUS);
688
689 DPRINTF(("%s: %02x CD %x\n", h->sc->dev.dv_xname, h->sock,
690 statreg));
691
692 if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
693 PCIC_IF_STATUS_CARDDETECT_PRESENT) {
694 if (!(h->flags & PCIC_FLAG_CARDP))
695 pcic_attach_card(h);
696 } else {
697 if (h->flags & PCIC_FLAG_CARDP)
698 pcic_detach_card(h);
699 }
700 }
701 if (cscreg & PCIC_CSC_READY) {
702 DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock));
703 /* shouldn't happen */
704 }
705 if (cscreg & PCIC_CSC_BATTWARN) {
706 DPRINTF(("%s: %02x BATTWARN\n", h->sc->dev.dv_xname, h->sock));
707 }
708 if (cscreg & PCIC_CSC_BATTDEAD) {
709 DPRINTF(("%s: %02x BATTDEAD\n", h->sc->dev.dv_xname, h->sock));
710 }
711
712 #if 0
713 /* ack the interrupt */
714
715 pcic_write(h, PCIC_CSC, cscreg);
716 #endif
717
718 return(cscreg?1:0);
719 }
720
721 void
722 pcic_attach_card(h)
723 struct pcic_handle *h;
724 {
725 int iftype;
726 int reg;
727
728 if (h->flags & PCIC_FLAG_CARDP)
729 panic("pcic_attach_card: already attached");
730
731 /* power down the socket to reset it, clear the card reset pin */
732
733 pcic_write(h, PCIC_PWRCTL, 0);
734
735 /* power up the socket */
736
737 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE);
738 delay(10000);
739 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_OE);
740
741 /* clear the reset flag */
742
743 pcic_write(h, PCIC_INTR, PCIC_INTR_RESET);
744
745 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
746
747 delay(20000);
748
749 /* wait for the chip to finish initializing */
750
751 pcic_wait_ready(h);
752
753 /* zero out the address windows */
754
755 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
756
757 #if 1
758 pcic_write(h, PCIC_INTR, PCIC_INTR_RESET | PCIC_INTR_CARDTYPE_IO);
759 #endif
760
761 reg = pcic_read(h, PCIC_INTR);
762
763 DPRINTF(("%s: %02x PCIC_INTR = %02x\n", h->sc->dev.dv_xname,
764 h->sock, reg));
765
766 /* call the MI attach function */
767
768 pcmcia_attach_card(h->pcmcia, &iftype);
769
770 /* set the card type */
771
772 DPRINTF(("%s: %02x cardtype %s\n", h->sc->dev.dv_xname, h->sock,
773 ((iftype == PCMCIA_IFTYPE_IO)?"io":"mem")));
774
775 #if 0
776 reg = pcic_read(h, PCIC_INTR);
777 reg &= PCIC_INTR_CARDTYPE_MASK;
778 reg |= ((iftype == PCMCIA_IFTYPE_IO)?
779 PCIC_INTR_CARDTYPE_IO:
780 PCIC_INTR_CARDTYPE_MEM);
781 pcic_write(h, PCIC_INTR, reg);
782 #endif
783
784 h->flags |= PCIC_FLAG_CARDP;
785 }
786
787 void
788 pcic_detach_card(h)
789 struct pcic_handle *h;
790 {
791 if (!(h->flags & PCIC_FLAG_CARDP))
792 panic("pcic_attach_card: already attached");
793
794 h->flags &= ~PCIC_FLAG_CARDP;
795
796 /* call the MI attach function */
797
798 pcmcia_detach_card(h->pcmcia);
799
800 /* disable card detect resume and configuration reset */
801
802 #if 0
803 pcic_write(h, PCIC_CARD_DETECT, 0);
804 #endif
805
806 /* power down the socket */
807
808 pcic_write(h, PCIC_PWRCTL, 0);
809
810 /* reset the card */
811
812 pcic_write(h, PCIC_INTR, 0);
813 }
814
815 int pcic_chip_mem_alloc(pch, size, memt, memh, mhandle, realsize)
816 pcmcia_chipset_handle_t pch;
817 bus_size_t size;
818 bus_space_tag_t *memt;
819 bus_space_handle_t *memh;
820 pcmcia_mem_handle_t *mhandle;
821 bus_size_t *realsize;
822 {
823 struct pcic_handle *h = (struct pcic_handle *) pch;
824 int i, mask;
825
826 /* out of sc->memh, allocate as many pages as necessary */
827
828 size += (PCIC_MEM_ALIGN-1);
829 size /= PCIC_MEM_ALIGN;
830
831 /* size is now in pages */
832
833 mask = (1<<size)-1;
834
835 for (i=0; i<(PCIC_MEM_PAGES+1-size); i++) {
836 if ((h->sc->subregionmask & (mask<<i)) == (mask<<i)) {
837 if (bus_space_subregion(h->sc->memt, h->sc->memh,
838 i*PCIC_MEM_PAGESIZE,
839 size*PCIC_MEM_PAGESIZE, memh))
840 return(1);
841 *mhandle = mask<<i;
842 h->sc->subregionmask &= ~(*mhandle);
843 break;
844 }
845 }
846
847 if (i == (PCIC_MEM_PAGES+1-size))
848 return(1);
849
850 DPRINTF(("pcic_chip_mem_alloc paddr %lx+%lx at vaddr %lx\n",
851 (u_long) pmap_extract(pmap_kernel(), (vm_offset_t) *memh),
852 (u_long) (size-1), (u_long) *memh));
853
854 *memt = h->sc->memt;
855 if (realsize)
856 *realsize = size*PCIC_MEM_PAGESIZE;
857
858 return(0);
859 }
860
861 void pcic_chip_mem_free(pch, size, memt, memh, mhandle)
862 pcmcia_chipset_handle_t pch;
863 bus_size_t size;
864 bus_space_tag_t memt;
865 bus_space_handle_t memh;
866 pcmcia_mem_handle_t mhandle;
867 {
868 struct pcic_handle *h = (struct pcic_handle *) pch;
869
870 h->sc->subregionmask |= mhandle;
871 }
872
873 static struct mem_map_index_st {
874 int sysmem_start_lsb;
875 int sysmem_start_msb;
876 int sysmem_stop_lsb;
877 int sysmem_stop_msb;
878 int cardmem_lsb;
879 int cardmem_msb;
880 int memenable;
881 } mem_map_index[] = {
882 {
883 PCIC_SYSMEM_ADDR0_START_LSB,
884 PCIC_SYSMEM_ADDR0_START_MSB,
885 PCIC_SYSMEM_ADDR0_STOP_LSB,
886 PCIC_SYSMEM_ADDR0_STOP_MSB,
887 PCIC_CARDMEM_ADDR0_LSB,
888 PCIC_CARDMEM_ADDR0_MSB,
889 PCIC_ADDRWIN_ENABLE_MEM0,
890 },
891 {
892 PCIC_SYSMEM_ADDR1_START_LSB,
893 PCIC_SYSMEM_ADDR1_START_MSB,
894 PCIC_SYSMEM_ADDR1_STOP_LSB,
895 PCIC_SYSMEM_ADDR1_STOP_MSB,
896 PCIC_CARDMEM_ADDR1_LSB,
897 PCIC_CARDMEM_ADDR1_MSB,
898 PCIC_ADDRWIN_ENABLE_MEM1,
899 },
900 {
901 PCIC_SYSMEM_ADDR2_START_LSB,
902 PCIC_SYSMEM_ADDR2_START_MSB,
903 PCIC_SYSMEM_ADDR2_STOP_LSB,
904 PCIC_SYSMEM_ADDR2_STOP_MSB,
905 PCIC_CARDMEM_ADDR2_LSB,
906 PCIC_CARDMEM_ADDR2_MSB,
907 PCIC_ADDRWIN_ENABLE_MEM2,
908 },
909 {
910 PCIC_SYSMEM_ADDR3_START_LSB,
911 PCIC_SYSMEM_ADDR3_START_MSB,
912 PCIC_SYSMEM_ADDR3_STOP_LSB,
913 PCIC_SYSMEM_ADDR3_STOP_MSB,
914 PCIC_CARDMEM_ADDR3_LSB,
915 PCIC_CARDMEM_ADDR3_MSB,
916 PCIC_ADDRWIN_ENABLE_MEM3,
917 },
918 {
919 PCIC_SYSMEM_ADDR4_START_LSB,
920 PCIC_SYSMEM_ADDR4_START_MSB,
921 PCIC_SYSMEM_ADDR4_STOP_LSB,
922 PCIC_SYSMEM_ADDR4_STOP_MSB,
923 PCIC_CARDMEM_ADDR4_LSB,
924 PCIC_CARDMEM_ADDR4_MSB,
925 PCIC_ADDRWIN_ENABLE_MEM4,
926 },
927 };
928
929 int pcic_chip_mem_map(pch, kind, size, memt, memh, card_addr, offset, window)
930 pcmcia_chipset_handle_t pch;
931 int kind;
932 bus_size_t size;
933 bus_space_tag_t memt;
934 bus_space_handle_t memh;
935 u_long card_addr;
936 u_long *offset;
937 int *window;
938 {
939 struct pcic_handle *h = (struct pcic_handle *) pch;
940 int reg;
941 vm_offset_t physaddr;
942 long card_offset;
943 int i, win;
944
945 win = -1;
946 for (i=0; i<(sizeof(mem_map_index)/sizeof(mem_map_index[0])); i++) {
947 if ((h->memalloc & (1<<i)) == 0) {
948 win = i;
949 h->memalloc |= (1<<i);
950 break;
951 }
952 }
953
954 if (win == -1)
955 return(1);
956
957 *window = win;
958
959 /* XXX this is pretty gross */
960
961 if (h->sc->memt != memt)
962 panic("pcic_chip_mem_map memt is bogus");
963
964 /* convert the memh to a physical address */
965 physaddr = pmap_extract(pmap_kernel(), (vm_offset_t) memh);
966
967 /* compute the address offset to the pcmcia address space for the
968 pcic. this is intentionally signed. The masks and shifts
969 below will cause TRT to happen in the pcic registers. Deal with
970 making sure the address is aligned, and return the alignment
971 offset. */
972
973 *offset = card_addr % PCIC_MEM_ALIGN;
974 card_addr -= *offset;
975
976 DPRINTF(("pcic_chip_mem_map window %d sys %lx+%lx+%lx at card addr %lx\n",
977 win, physaddr, *offset, size, card_addr));
978
979 /* include the offset in the size, and decrement size by one,
980 since the hw wants start/stop */
981 size += *offset - 1;
982
983 card_offset = (((long) card_addr) - ((long) physaddr));
984
985 pcic_write(h, mem_map_index[win].sysmem_start_lsb,
986 (physaddr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
987 pcic_write(h, mem_map_index[win].sysmem_start_msb,
988 ((physaddr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
989 PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK));
990
991 #if 0
992 /* XXX do I want 16 bit all the time? */
993 PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT;
994 #endif
995
996 pcic_write(h, mem_map_index[win].sysmem_stop_lsb,
997 ((physaddr + size) >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
998 pcic_write(h, mem_map_index[win].sysmem_stop_msb,
999 (((physaddr + size) >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
1000 PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
1001 PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
1002
1003
1004 pcic_write(h, mem_map_index[win].cardmem_lsb,
1005 (card_offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
1006 pcic_write(h, mem_map_index[win].cardmem_msb,
1007 ((card_offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) &
1008 PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) |
1009 ((kind == PCMCIA_MEM_ATTR)?
1010 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR:0));
1011
1012 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1013 reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16 );
1014 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1015
1016 #ifdef PCICDEBUG
1017 {
1018 int r1,r2,r3,r4,r5,r6;
1019
1020 r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb);
1021 r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb);
1022 r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb);
1023 r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb);
1024 r5 = pcic_read(h, mem_map_index[win].cardmem_msb);
1025 r6 = pcic_read(h, mem_map_index[win].cardmem_lsb);
1026
1027 DPRINTF(("pcic_chip_mem_map window %d: %02x%02x %02x%02x %02x%02x\n",
1028 win, r1, r2, r3, r4, r5, r6));
1029 }
1030 #endif
1031
1032 return(0);
1033 }
1034
1035 void pcic_chip_mem_unmap(pch, window)
1036 pcmcia_chipset_handle_t pch;
1037 int window;
1038 {
1039 struct pcic_handle *h = (struct pcic_handle *) pch;
1040 int reg;
1041
1042 if (window >= (sizeof(mem_map_index)/sizeof(mem_map_index[0])))
1043 panic("pcic_chip_mem_unmap: window out of range");
1044
1045 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1046 reg &= ~mem_map_index[window].memenable;
1047 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1048
1049 h->memalloc &= ~(1<<window);
1050 }
1051
1052
1053 int pcic_chip_io_alloc(pch, start, size, iot, ioh)
1054 pcmcia_chipset_handle_t pch;
1055 bus_addr_t start;
1056 bus_size_t size;
1057 bus_space_tag_t *iot;
1058 bus_space_handle_t *ioh;
1059 {
1060 struct pcic_handle *h = (struct pcic_handle *) pch;
1061 bus_addr_t ioaddr;
1062
1063 /*
1064 * Allocate some arbitrary I/O space. XXX There really should be a
1065 * generic isa interface to this, but there isn't currently one
1066 */
1067
1068 /* XXX mycroft recommends this I/O space range. I should put this
1069 in a header somewhere */
1070
1071 *iot = h->sc->iot;
1072
1073 if (start) {
1074 if (bus_space_map(h->sc->iot, start, size, 0, ioh))
1075 return(1);
1076 DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
1077 (u_long) start, (u_long) size));
1078 } else {
1079 if (bus_space_alloc(h->sc->iot, 0x400, 0xfff, size, size,
1080 EX_NOBOUNDARY, 0, &ioaddr, ioh))
1081 return(1);
1082 DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
1083 (u_long) ioaddr, (u_long) size));
1084 }
1085
1086 return(0);
1087 }
1088
1089 void pcic_chip_io_free(pch, size, iot, ioh)
1090 pcmcia_chipset_handle_t pch;
1091 bus_size_t size;
1092 bus_space_tag_t iot;
1093 bus_space_handle_t ioh;
1094 {
1095 bus_space_free(iot, ioh, size);
1096 }
1097
1098
1099 static struct io_map_index_st {
1100 int start_lsb;
1101 int start_msb;
1102 int stop_lsb;
1103 int stop_msb;
1104 int ioenable;
1105 int ioctlmask;
1106 int ioctl8;
1107 int ioctl16;
1108 } io_map_index[] = {
1109 {
1110 PCIC_IOADDR0_START_LSB,
1111 PCIC_IOADDR0_START_MSB,
1112 PCIC_IOADDR0_STOP_LSB,
1113 PCIC_IOADDR0_STOP_MSB,
1114 PCIC_ADDRWIN_ENABLE_IO0,
1115 PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
1116 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK,
1117 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_8BIT,
1118 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO0_DATASIZE_16BIT,
1119 },
1120 {
1121 PCIC_IOADDR1_START_LSB,
1122 PCIC_IOADDR1_START_MSB,
1123 PCIC_IOADDR1_STOP_LSB,
1124 PCIC_IOADDR1_STOP_MSB,
1125 PCIC_ADDRWIN_ENABLE_IO1,
1126 PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
1127 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK,
1128 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO1_DATASIZE_8BIT,
1129 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE | PCIC_IOCTL_IO1_DATASIZE_16BIT,
1130 },
1131 };
1132
1133 int pcic_chip_io_map(pch, width, size, iot, ioh, window)
1134 pcmcia_chipset_handle_t pch;
1135 int width;
1136 bus_size_t size;
1137 bus_space_tag_t iot;
1138 bus_space_handle_t ioh;
1139 int *window;
1140 {
1141 struct pcic_handle *h = (struct pcic_handle *) pch;
1142 int reg;
1143 int i, win;
1144
1145 win = -1;
1146 for (i=0; i<(sizeof(io_map_index)/sizeof(io_map_index[0])); i++) {
1147 if ((h->ioalloc & (1<<i)) == 0) {
1148 win = i;
1149 h->ioalloc |= (1<<i);
1150 break;
1151 }
1152 }
1153
1154 if (win == -1)
1155 return(1);
1156
1157 *window = win;
1158
1159 /* XXX this is pretty gross */
1160
1161 if (h->sc->iot != iot)
1162 panic("pcic_chip_io_map iot is bogus");
1163
1164 DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
1165 win, (width == PCMCIA_WIDTH_IO8)?"io8":"io16",
1166 (u_long) ioh, (u_long) size));
1167
1168 pcic_write(h, io_map_index[win].start_lsb, ioh & 0xff);
1169 pcic_write(h, io_map_index[win].start_msb, (ioh >> 8) & 0xff);
1170
1171 pcic_write(h, io_map_index[win].stop_lsb, (ioh + size - 1) & 0xff);
1172 pcic_write(h, io_map_index[win].stop_msb, ((ioh + size - 1) >> 8) & 0xff);
1173
1174 reg = pcic_read(h, PCIC_IOCTL);
1175 reg &= ~io_map_index[win].ioctlmask;
1176 if (width == PCMCIA_WIDTH_IO8)
1177 reg |= io_map_index[win].ioctl8;
1178 else
1179 reg |= io_map_index[win].ioctl16;
1180 pcic_write(h, PCIC_IOCTL, reg);
1181
1182 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1183 reg |= io_map_index[win].ioenable;
1184 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1185
1186 return(0);
1187 }
1188
1189 void pcic_chip_io_unmap(pch, window)
1190 pcmcia_chipset_handle_t pch;
1191 int window;
1192 {
1193 struct pcic_handle *h = (struct pcic_handle *) pch;
1194 int reg;
1195
1196 if (window >= (sizeof(io_map_index)/sizeof(io_map_index[0])))
1197 panic("pcic_chip_io_unmap: window out of range");
1198
1199 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1200 reg &= ~io_map_index[window].ioenable;
1201 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1202
1203 h->ioalloc &= ~(1<<window);
1204 }
1205
1206 void *
1207 pcic_chip_intr_establish(pch, irqmask, ipl, fct, arg)
1208 pcmcia_chipset_handle_t pch;
1209 u_int16_t irqmask;
1210 int ipl;
1211 int (*fct)(void *);
1212 void *arg;
1213 {
1214 struct pcic_handle *h = (struct pcic_handle *) pch;
1215 int irq;
1216 void *ih;
1217 int reg;
1218
1219 /* Mask out IRQs which we shouldn't allocate. */
1220 irqmask &= PCIC_INTR_IRQ_VALIDMASK;
1221 if (irqmask == 0)
1222 return(NULL);
1223
1224 isa_intr_alloc(h->sc->ic, irqmask, IST_PULSE, &irq);
1225 if (!(ih = isa_intr_establish(h->sc->ic, irq, IST_PULSE, ipl, fct, arg)))
1226 return(NULL);
1227
1228 reg = pcic_read(h, PCIC_INTR);
1229 reg &= ~PCIC_INTR_IRQ_MASK;
1230 reg |= PCIC_INTR_ENABLE;
1231 reg |= irq;
1232 pcic_write(h, PCIC_INTR, reg);
1233
1234 printf("%s: card irq %d\n", h->pcmcia->dv_xname, irq);
1235
1236 return(ih);
1237 }
1238
1239 void pcic_chip_intr_disestablish(pch, ih)
1240 pcmcia_chipset_handle_t pch;
1241 void *ih;
1242 {
1243 struct pcic_handle *h = (struct pcic_handle *) pch;
1244 int reg;
1245
1246 reg = pcic_read(h, PCIC_INTR);
1247 reg &= ~(PCIC_INTR_IRQ_MASK|PCIC_INTR_ENABLE);
1248 pcic_write(h, PCIC_INTR, reg);
1249
1250 isa_intr_disestablish(h->sc->ic, ih);
1251 }
1252