i82365.c revision 1.1.2.14 1 /* $NetBSD: i82365.c,v 1.1.2.14 1997/10/16 19:41:51 thorpej Exp $ */
2
3 #define PCICDEBUG
4
5 #include <sys/types.h>
6 #include <sys/param.h>
7 #include <sys/systm.h>
8 #include <sys/device.h>
9 #include <sys/extent.h>
10 #include <sys/malloc.h>
11
12 #include <vm/vm.h>
13
14 #include <machine/bus.h>
15 #include <machine/intr.h>
16
17 #include <dev/pcmcia/pcmciareg.h>
18 #include <dev/pcmcia/pcmciavar.h>
19
20 #include <dev/ic/i82365reg.h>
21 #include <dev/ic/i82365var.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 #define PCIC_VENDOR_UNKNOWN 0
31 #define PCIC_VENDOR_I82365SLR0 1
32 #define PCIC_VENDOR_I82365SLR1 2
33 #define PCIC_VENDOR_CIRRUS_PD6710 3
34 #define PCIC_VENDOR_CIRRUS_PD672X 4
35
36 /*
37 * Individual drivers will allocate their own memory and io regions. Memory
38 * regions must be a multiple of 4k, aligned on a 4k boundary.
39 */
40
41 #define PCIC_MEM_ALIGN PCIC_MEM_PAGESIZE
42
43 void pcic_attach_socket __P((struct pcic_handle *));
44 void pcic_init_socket __P((struct pcic_handle *));
45
46 #ifdef __BROKEN_INDIRECT_CONFIG
47 int pcic_submatch __P((struct device *, void *, void *));
48 #else
49 int pcic_submatch __P((struct device *, struct cfdata *, void *));
50 #endif
51 int pcic_print __P((void *arg, const char *pnp));
52 int pcic_intr_socket __P((struct pcic_handle *));
53
54 void pcic_attach_card __P((struct pcic_handle *));
55 void pcic_detach_card __P((struct pcic_handle *));
56
57 void pcic_chip_do_mem_map __P((struct pcic_handle *, int));
58 void pcic_chip_do_io_map __P((struct pcic_handle *, int));
59
60 struct cfdriver pcic_cd = {
61 NULL, "pcic", DV_DULL
62 };
63
64 int
65 pcic_ident_ok(ident)
66 int ident;
67 {
68 /* this is very empirical and heuristic */
69
70 if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO))
71 return (0);
72
73 if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) {
74 #ifdef DIAGNOSTIC
75 printf("pcic: does not support memory and I/O cards, "
76 "ignored (ident=%0x)\n", ident);
77 #endif
78 return (0);
79 }
80 return (1);
81 }
82
83 int
84 pcic_vendor(h)
85 struct pcic_handle *h;
86 {
87 int reg;
88
89 /*
90 * the chip_id of the cirrus toggles between 11 and 00 after a write.
91 * weird.
92 */
93
94 pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0);
95 reg = pcic_read(h, -1);
96
97 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) ==
98 PCIC_CIRRUS_CHIP_INFO_CHIP_ID) {
99 reg = pcic_read(h, -1);
100 if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0) {
101 if (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS)
102 return (PCIC_VENDOR_CIRRUS_PD672X);
103 else
104 return (PCIC_VENDOR_CIRRUS_PD6710);
105 }
106 }
107 /* XXX how do I identify the GD6729? */
108
109 reg = pcic_read(h, PCIC_IDENT);
110
111 if ((reg & PCIC_IDENT_REV_MASK) == PCIC_IDENT_REV_I82365SLR0)
112 return (PCIC_VENDOR_I82365SLR0);
113 else
114 return (PCIC_VENDOR_I82365SLR1);
115
116 return (PCIC_VENDOR_UNKNOWN);
117 }
118
119 char *
120 pcic_vendor_to_string(vendor)
121 int vendor;
122 {
123 switch (vendor) {
124 case PCIC_VENDOR_I82365SLR0:
125 return ("Intel 82365SL Revision 0");
126 case PCIC_VENDOR_I82365SLR1:
127 return ("Intel 82365SL Revision 1");
128 case PCIC_VENDOR_CIRRUS_PD6710:
129 return ("Cirrus PD6710");
130 case PCIC_VENDOR_CIRRUS_PD672X:
131 return ("Cirrus PD672X");
132 }
133
134 return ("Unknown controller");
135 }
136
137 void
138 pcic_attach(sc)
139 struct pcic_softc *sc;
140 {
141 int vendor, count, i, reg;
142
143 /* now check for each controller/socket */
144
145 /*
146 * this could be done with a loop, but it would violate the
147 * abstraction
148 */
149
150 count = 0;
151
152 DPRINTF(("pcic ident regs:"));
153
154 sc->handle[0].sc = sc;
155 sc->handle[0].sock = C0SA;
156 if (pcic_ident_ok(reg = pcic_read(&sc->handle[0], PCIC_IDENT))) {
157 sc->handle[0].flags = PCIC_FLAG_SOCKETP;
158 count++;
159 } else {
160 sc->handle[0].flags = 0;
161 }
162
163 DPRINTF((" 0x%02x", reg));
164
165 sc->handle[1].sc = sc;
166 sc->handle[1].sock = C0SB;
167 if (pcic_ident_ok(reg = pcic_read(&sc->handle[1], PCIC_IDENT))) {
168 sc->handle[1].flags = PCIC_FLAG_SOCKETP;
169 count++;
170 } else {
171 sc->handle[1].flags = 0;
172 }
173
174 DPRINTF((" 0x%02x", reg));
175
176 sc->handle[2].sc = sc;
177 sc->handle[2].sock = C1SA;
178 if (pcic_ident_ok(reg = pcic_read(&sc->handle[2], PCIC_IDENT))) {
179 sc->handle[2].flags = PCIC_FLAG_SOCKETP;
180 count++;
181 } else {
182 sc->handle[2].flags = 0;
183 }
184
185 DPRINTF((" 0x%02x", reg));
186
187 sc->handle[3].sc = sc;
188 sc->handle[3].sock = C1SB;
189 if (pcic_ident_ok(reg = pcic_read(&sc->handle[3], PCIC_IDENT))) {
190 sc->handle[3].flags = PCIC_FLAG_SOCKETP;
191 count++;
192 } else {
193 sc->handle[3].flags = 0;
194 }
195
196 DPRINTF((" 0x%02x\n", reg));
197
198 if (count == 0)
199 panic("pcic_attach: attach found no sockets");
200
201 /* establish the interrupt */
202
203 /* XXX block interrupts? */
204
205 for (i = 0; i < PCIC_NSLOTS; i++) {
206 #if 0
207 /*
208 * this should work, but w/o it, setting tty flags hangs at
209 * boot time.
210 */
211 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
212 #endif
213 {
214 pcic_write(&sc->handle[i], PCIC_CSC_INTR, 0);
215 pcic_read(&sc->handle[i], PCIC_CSC);
216 }
217 }
218
219 if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) ||
220 (sc->handle[1].flags & PCIC_FLAG_SOCKETP)) {
221 vendor = pcic_vendor(&sc->handle[0]);
222
223 printf("%s: controller 0 (%s) has ", sc->dev.dv_xname,
224 pcic_vendor_to_string(vendor));
225
226 if ((sc->handle[0].flags & PCIC_FLAG_SOCKETP) &&
227 (sc->handle[1].flags & PCIC_FLAG_SOCKETP))
228 printf("sockets A and B\n");
229 else if (sc->handle[0].flags & PCIC_FLAG_SOCKETP)
230 printf("socket A only\n");
231 else
232 printf("socket B only\n");
233
234 if (sc->handle[0].flags & PCIC_FLAG_SOCKETP)
235 sc->handle[0].vendor = vendor;
236 if (sc->handle[1].flags & PCIC_FLAG_SOCKETP)
237 sc->handle[1].vendor = vendor;
238 }
239 if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) ||
240 (sc->handle[3].flags & PCIC_FLAG_SOCKETP)) {
241 vendor = pcic_vendor(&sc->handle[2]);
242
243 printf("%s: controller 1 (%s) has ", sc->dev.dv_xname,
244 pcic_vendor_to_string(vendor));
245
246 if ((sc->handle[2].flags & PCIC_FLAG_SOCKETP) &&
247 (sc->handle[3].flags & PCIC_FLAG_SOCKETP))
248 printf("sockets A and B\n");
249 else if (sc->handle[2].flags & PCIC_FLAG_SOCKETP)
250 printf("socket A only\n");
251 else
252 printf("socket B only\n");
253
254 if (sc->handle[2].flags & PCIC_FLAG_SOCKETP)
255 sc->handle[2].vendor = vendor;
256 if (sc->handle[3].flags & PCIC_FLAG_SOCKETP)
257 sc->handle[3].vendor = vendor;
258 }
259 }
260
261 void
262 pcic_attach_sockets(sc)
263 struct pcic_softc *sc;
264 {
265 int i;
266
267 for (i = 0; i < PCIC_NSLOTS; i++)
268 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
269 pcic_attach_socket(&sc->handle[i]);
270 }
271
272 void
273 pcic_attach_socket(h)
274 struct pcic_handle *h;
275 {
276 struct pcmciabus_attach_args paa;
277
278 /* initialize the rest of the handle */
279
280 h->memalloc = 0;
281 h->ioalloc = 0;
282 h->ih_irq = 0;
283
284 /* now, config one pcmcia device per socket */
285
286 paa.pct = (pcmcia_chipset_tag_t) h->sc->pct;
287 paa.pch = (pcmcia_chipset_handle_t) h;
288 paa.iobase = h->sc->iobase;
289 paa.iosize = h->sc->iosize;
290
291 h->pcmcia = config_found_sm(&h->sc->dev, &paa, pcic_print,
292 pcic_submatch);
293
294 /* if there's actually a pcmcia device attached, initialize the slot */
295
296 if (h->pcmcia)
297 pcic_init_socket(h);
298 }
299
300 void
301 pcic_init_socket(h)
302 struct pcic_handle *h;
303 {
304 int reg;
305
306 /* set up the card to interrupt on card detect */
307
308 pcic_write(h, PCIC_CSC_INTR, (h->sc->irq << PCIC_CSC_INTR_IRQ_SHIFT) |
309 PCIC_CSC_INTR_CD_ENABLE);
310 pcic_write(h, PCIC_INTR, 0);
311 pcic_read(h, PCIC_CSC);
312
313 /* unsleep the cirrus controller */
314
315 if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) ||
316 (h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) {
317 reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
318 if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
319 DPRINTF(("%s: socket %02x was suspended\n",
320 h->sc->dev.dv_xname, h->sock));
321 reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
322 pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
323 }
324 }
325 /* if there's a card there, then attach it. */
326
327 reg = pcic_read(h, PCIC_IF_STATUS);
328
329 if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
330 PCIC_IF_STATUS_CARDDETECT_PRESENT)
331 pcic_attach_card(h);
332 }
333
334 int
335 #ifdef __BROKEN_INDIRECT_CONFIG
336 pcic_submatch(parent, match, aux)
337 #else
338 pcic_submatch(parent, cf, aux)
339 #endif
340 struct device *parent;
341 #ifdef __BROKEN_INDIRECT_CONFIG
342 void *match;
343 #else
344 struct cfdata *cf;
345 #endif
346 void *aux;
347 {
348 #ifdef __BROKEN_INDIRECT_CONFIG
349 struct cfdata *cf = match;
350 #endif
351
352 struct pcmciabus_attach_args *paa =
353 (struct pcmciabus_attach_args *) aux;
354 struct pcic_handle *h = (struct pcic_handle *) paa->pch;
355
356 switch (h->sock) {
357 case C0SA:
358 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
359 return 0;
360 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
361 return 0;
362
363 break;
364 case C0SB:
365 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
366 return 0;
367 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
368 return 0;
369
370 break;
371 case C1SA:
372 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
373 return 0;
374 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
375 return 0;
376
377 break;
378 case C1SB:
379 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
380 return 0;
381 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
382 return 0;
383
384 break;
385 default:
386 panic("unknown pcic socket");
387 }
388
389 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
390 }
391
392 int
393 pcic_print(arg, pnp)
394 void *arg;
395 const char *pnp;
396 {
397 struct pcmciabus_attach_args *paa =
398 (struct pcmciabus_attach_args *) arg;
399 struct pcic_handle *h = (struct pcic_handle *) paa->pch;
400
401 /* Only "pcmcia"s can attach to "pcic"s... easy. */
402 if (pnp)
403 printf("pcmcia at %s", pnp);
404
405 switch (h->sock) {
406 case C0SA:
407 printf(" controller 0 socket 0");
408 break;
409 case C0SB:
410 printf(" controller 0 socket 1");
411 break;
412 case C1SA:
413 printf(" controller 1 socket 0");
414 break;
415 case C1SB:
416 printf(" controller 1 socket 1");
417 break;
418 default:
419 panic("unknown pcic socket");
420 }
421
422 return (UNCONF);
423 }
424
425 int
426 pcic_intr(arg)
427 void *arg;
428 {
429 struct pcic_softc *sc = (struct pcic_softc *) arg;
430 int i, ret = 0;
431
432 DPRINTF(("%s: intr\n", sc->dev.dv_xname));
433
434 for (i = 0; i < PCIC_NSLOTS; i++)
435 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
436 ret += pcic_intr_socket(&sc->handle[i]);
437
438 return (ret ? 1 : 0);
439 }
440
441 int
442 pcic_intr_socket(h)
443 struct pcic_handle *h;
444 {
445 int cscreg;
446
447 cscreg = pcic_read(h, PCIC_CSC);
448
449 cscreg &= (PCIC_CSC_GPI |
450 PCIC_CSC_CD |
451 PCIC_CSC_READY |
452 PCIC_CSC_BATTWARN |
453 PCIC_CSC_BATTDEAD);
454
455 if (cscreg & PCIC_CSC_GPI) {
456 DPRINTF(("%s: %02x GPI\n", h->sc->dev.dv_xname, h->sock));
457 }
458 if (cscreg & PCIC_CSC_CD) {
459 int statreg;
460
461 statreg = pcic_read(h, PCIC_IF_STATUS);
462
463 DPRINTF(("%s: %02x CD %x\n", h->sc->dev.dv_xname, h->sock,
464 statreg));
465
466 /*
467 * XXX This should probably schedule something to happen
468 * after the interrupt handler completes
469 */
470
471 if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
472 PCIC_IF_STATUS_CARDDETECT_PRESENT) {
473 if (!(h->flags & PCIC_FLAG_CARDP))
474 pcic_attach_card(h);
475 } else {
476 if (h->flags & PCIC_FLAG_CARDP)
477 pcic_detach_card(h);
478 }
479 }
480 if (cscreg & PCIC_CSC_READY) {
481 DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock));
482 /* shouldn't happen */
483 }
484 if (cscreg & PCIC_CSC_BATTWARN) {
485 DPRINTF(("%s: %02x BATTWARN\n", h->sc->dev.dv_xname, h->sock));
486 }
487 if (cscreg & PCIC_CSC_BATTDEAD) {
488 DPRINTF(("%s: %02x BATTDEAD\n", h->sc->dev.dv_xname, h->sock));
489 }
490 return (cscreg ? 1 : 0);
491 }
492
493 void
494 pcic_attach_card(h)
495 struct pcic_handle *h;
496 {
497 if (h->flags & PCIC_FLAG_CARDP)
498 panic("pcic_attach_card: already attached");
499
500 /* call the MI attach function */
501
502 pcmcia_card_attach(h->pcmcia);
503
504 h->flags |= PCIC_FLAG_CARDP;
505 }
506
507 void
508 pcic_detach_card(h)
509 struct pcic_handle *h;
510 {
511 if (!(h->flags & PCIC_FLAG_CARDP))
512 panic("pcic_attach_card: already detached");
513
514 h->flags &= ~PCIC_FLAG_CARDP;
515
516 /* call the MI attach function */
517
518 pcmcia_card_detach(h->pcmcia);
519
520 /* disable card detect resume and configuration reset */
521
522 /* power down the socket */
523
524 pcic_write(h, PCIC_PWRCTL, 0);
525
526 /* reset the card */
527
528 pcic_write(h, PCIC_INTR, 0);
529 }
530
531 int
532 pcic_chip_mem_alloc(pch, size, pcmhp)
533 pcmcia_chipset_handle_t pch;
534 bus_size_t size;
535 struct pcmcia_mem_handle *pcmhp;
536 {
537 struct pcic_handle *h = (struct pcic_handle *) pch;
538 bus_space_handle_t memh;
539 bus_addr_t addr;
540 bus_size_t sizepg;
541 int i, mask, mhandle;
542
543 /* out of sc->memh, allocate as many pages as necessary */
544
545 /* convert size to PCIC pages */
546 sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN;
547
548 mask = (1 << sizepg) - 1;
549
550 addr = 0; /* XXX gcc -Wuninitialized */
551 mhandle = 0; /* XXX gcc -Wuninitialized */
552
553 for (i = 0; i < (PCIC_MEM_PAGES + 1 - sizepg); i++) {
554 if ((h->sc->subregionmask & (mask << i)) == (mask << i)) {
555 if (bus_space_subregion(h->sc->memt, h->sc->memh,
556 i * PCIC_MEM_PAGESIZE,
557 sizepg * PCIC_MEM_PAGESIZE, &memh))
558 return (1);
559 mhandle = mask << i;
560 addr = h->sc->membase + (i * PCIC_MEM_PAGESIZE);
561 h->sc->subregionmask &= ~(mhandle);
562 break;
563 }
564 }
565
566 if (i == (PCIC_MEM_PAGES + 1 - size))
567 return (1);
568
569 DPRINTF(("pcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n", (u_long) addr,
570 (u_long) size));
571
572 pcmhp->memt = h->sc->memt;
573 pcmhp->memh = memh;
574 pcmhp->addr = addr;
575 pcmhp->size = size;
576 pcmhp->mhandle = mhandle;
577 pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
578
579 return (0);
580 }
581
582 void
583 pcic_chip_mem_free(pch, pcmhp)
584 pcmcia_chipset_handle_t pch;
585 struct pcmcia_mem_handle *pcmhp;
586 {
587 struct pcic_handle *h = (struct pcic_handle *) pch;
588
589 h->sc->subregionmask |= pcmhp->mhandle;
590 }
591
592 static struct mem_map_index_st {
593 int sysmem_start_lsb;
594 int sysmem_start_msb;
595 int sysmem_stop_lsb;
596 int sysmem_stop_msb;
597 int cardmem_lsb;
598 int cardmem_msb;
599 int memenable;
600 } mem_map_index[] = {
601 {
602 PCIC_SYSMEM_ADDR0_START_LSB,
603 PCIC_SYSMEM_ADDR0_START_MSB,
604 PCIC_SYSMEM_ADDR0_STOP_LSB,
605 PCIC_SYSMEM_ADDR0_STOP_MSB,
606 PCIC_CARDMEM_ADDR0_LSB,
607 PCIC_CARDMEM_ADDR0_MSB,
608 PCIC_ADDRWIN_ENABLE_MEM0,
609 },
610 {
611 PCIC_SYSMEM_ADDR1_START_LSB,
612 PCIC_SYSMEM_ADDR1_START_MSB,
613 PCIC_SYSMEM_ADDR1_STOP_LSB,
614 PCIC_SYSMEM_ADDR1_STOP_MSB,
615 PCIC_CARDMEM_ADDR1_LSB,
616 PCIC_CARDMEM_ADDR1_MSB,
617 PCIC_ADDRWIN_ENABLE_MEM1,
618 },
619 {
620 PCIC_SYSMEM_ADDR2_START_LSB,
621 PCIC_SYSMEM_ADDR2_START_MSB,
622 PCIC_SYSMEM_ADDR2_STOP_LSB,
623 PCIC_SYSMEM_ADDR2_STOP_MSB,
624 PCIC_CARDMEM_ADDR2_LSB,
625 PCIC_CARDMEM_ADDR2_MSB,
626 PCIC_ADDRWIN_ENABLE_MEM2,
627 },
628 {
629 PCIC_SYSMEM_ADDR3_START_LSB,
630 PCIC_SYSMEM_ADDR3_START_MSB,
631 PCIC_SYSMEM_ADDR3_STOP_LSB,
632 PCIC_SYSMEM_ADDR3_STOP_MSB,
633 PCIC_CARDMEM_ADDR3_LSB,
634 PCIC_CARDMEM_ADDR3_MSB,
635 PCIC_ADDRWIN_ENABLE_MEM3,
636 },
637 {
638 PCIC_SYSMEM_ADDR4_START_LSB,
639 PCIC_SYSMEM_ADDR4_START_MSB,
640 PCIC_SYSMEM_ADDR4_STOP_LSB,
641 PCIC_SYSMEM_ADDR4_STOP_MSB,
642 PCIC_CARDMEM_ADDR4_LSB,
643 PCIC_CARDMEM_ADDR4_MSB,
644 PCIC_ADDRWIN_ENABLE_MEM4,
645 },
646 };
647
648 void
649 pcic_chip_do_mem_map(h, win)
650 struct pcic_handle *h;
651 int win;
652 {
653 int reg;
654
655 pcic_write(h, mem_map_index[win].sysmem_start_lsb,
656 (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
657 pcic_write(h, mem_map_index[win].sysmem_start_msb,
658 ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
659 PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK));
660
661 #if 0
662 /* XXX do I want 16 bit all the time? */
663 PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT;
664 #endif
665
666 pcic_write(h, mem_map_index[win].sysmem_stop_lsb,
667 ((h->mem[win].addr + h->mem[win].size) >>
668 PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
669 pcic_write(h, mem_map_index[win].sysmem_stop_msb,
670 (((h->mem[win].addr + h->mem[win].size) >>
671 (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
672 PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
673 PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
674
675 pcic_write(h, mem_map_index[win].cardmem_lsb,
676 (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
677 pcic_write(h, mem_map_index[win].cardmem_msb,
678 ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) &
679 PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) |
680 ((h->mem[win].kind == PCMCIA_MEM_ATTR) ?
681 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0));
682
683 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
684 reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16);
685 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
686
687 #ifdef PCICDEBUG
688 {
689 int r1, r2, r3, r4, r5, r6;
690
691 r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb);
692 r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb);
693 r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb);
694 r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb);
695 r5 = pcic_read(h, mem_map_index[win].cardmem_msb);
696 r6 = pcic_read(h, mem_map_index[win].cardmem_lsb);
697
698 DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x "
699 "%02x%02x\n", win, r1, r2, r3, r4, r5, r6));
700 }
701 #endif
702 }
703
704 int
705 pcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
706 pcmcia_chipset_handle_t pch;
707 int kind;
708 bus_addr_t card_addr;
709 bus_size_t size;
710 struct pcmcia_mem_handle *pcmhp;
711 bus_addr_t *offsetp;
712 int *windowp;
713 {
714 struct pcic_handle *h = (struct pcic_handle *) pch;
715 bus_addr_t busaddr;
716 long card_offset;
717 int i, win;
718
719 win = -1;
720 for (i = 0; i < (sizeof(mem_map_index) / sizeof(mem_map_index[0]));
721 i++) {
722 if ((h->memalloc & (1 << i)) == 0) {
723 win = i;
724 h->memalloc |= (1 << i);
725 break;
726 }
727 }
728
729 if (win == -1)
730 return (1);
731
732 *windowp = win;
733
734 /* XXX this is pretty gross */
735
736 if (h->sc->memt != pcmhp->memt)
737 panic("pcic_chip_mem_map memt is bogus");
738
739 busaddr = pcmhp->addr;
740
741 /*
742 * compute the address offset to the pcmcia address space for the
743 * pcic. this is intentionally signed. The masks and shifts below
744 * will cause TRT to happen in the pcic registers. Deal with making
745 * sure the address is aligned, and return the alignment offset.
746 */
747
748 *offsetp = card_addr % PCIC_MEM_ALIGN;
749 card_addr -= *offsetp;
750
751 DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr "
752 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
753 (u_long) card_addr));
754
755 /*
756 * include the offset in the size, and decrement size by one, since
757 * the hw wants start/stop
758 */
759 size += *offsetp - 1;
760
761 card_offset = (((long) card_addr) - ((long) busaddr));
762
763 h->mem[win].addr = busaddr;
764 h->mem[win].size = size;
765 h->mem[win].offset = card_offset;
766 h->mem[win].kind = kind;
767
768 pcic_chip_do_mem_map(h, win);
769
770 return (0);
771 }
772
773 void
774 pcic_chip_mem_unmap(pch, window)
775 pcmcia_chipset_handle_t pch;
776 int window;
777 {
778 struct pcic_handle *h = (struct pcic_handle *) pch;
779 int reg;
780
781 if (window >= (sizeof(mem_map_index) / sizeof(mem_map_index[0])))
782 panic("pcic_chip_mem_unmap: window out of range");
783
784 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
785 reg &= ~mem_map_index[window].memenable;
786 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
787
788 h->memalloc &= ~(1 << window);
789 }
790
791 int
792 pcic_chip_io_alloc(pch, start, size, align, pcihp)
793 pcmcia_chipset_handle_t pch;
794 bus_addr_t start;
795 bus_size_t size;
796 bus_size_t align;
797 struct pcmcia_io_handle *pcihp;
798 {
799 struct pcic_handle *h = (struct pcic_handle *) pch;
800 bus_space_tag_t iot;
801 bus_space_handle_t ioh;
802 bus_addr_t ioaddr;
803 int flags = 0;
804
805 /*
806 * Allocate some arbitrary I/O space.
807 */
808
809 iot = h->sc->iot;
810
811 if (start) {
812 ioaddr = start;
813 if (bus_space_map(iot, start, size, 0, &ioh))
814 return (1);
815 DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
816 (u_long) ioaddr, (u_long) size));
817 } else {
818 flags |= PCMCIA_IO_ALLOCATED;
819 if (bus_space_alloc(iot, h->sc->iobase,
820 h->sc->iobase + h->sc->iosize, size, align, 0, 0,
821 &ioaddr, &ioh))
822 return (1);
823 DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
824 (u_long) ioaddr, (u_long) size));
825 }
826
827 pcihp->iot = iot;
828 pcihp->ioh = ioh;
829 pcihp->addr = ioaddr;
830 pcihp->size = size;
831 pcihp->flags = flags;
832
833 return (0);
834 }
835
836 void
837 pcic_chip_io_free(pch, pcihp)
838 pcmcia_chipset_handle_t pch;
839 struct pcmcia_io_handle *pcihp;
840 {
841 bus_space_tag_t iot = pcihp->iot;
842 bus_space_handle_t ioh = pcihp->ioh;
843 bus_size_t size = pcihp->size;
844
845 if (pcihp->flags & PCMCIA_IO_ALLOCATED)
846 bus_space_free(iot, ioh, size);
847 else
848 bus_space_unmap(iot, ioh, size);
849 }
850
851
852 static struct io_map_index_st {
853 int start_lsb;
854 int start_msb;
855 int stop_lsb;
856 int stop_msb;
857 int ioenable;
858 int ioctlmask;
859 int ioctlbits[3]; /* indexed by PCMCIA_WIDTH_* */
860 } io_map_index[] = {
861 {
862 PCIC_IOADDR0_START_LSB,
863 PCIC_IOADDR0_START_MSB,
864 PCIC_IOADDR0_STOP_LSB,
865 PCIC_IOADDR0_STOP_MSB,
866 PCIC_ADDRWIN_ENABLE_IO0,
867 PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
868 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK,
869 {
870 PCIC_IOCTL_IO0_IOCS16SRC_CARD,
871 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE
872 | PCIC_IOCTL_IO0_DATASIZE_8BIT,
873 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE
874 | PCIC_IOCTL_IO0_DATASIZE_16BIT,
875 },
876 },
877 {
878 PCIC_IOADDR1_START_LSB,
879 PCIC_IOADDR1_START_MSB,
880 PCIC_IOADDR1_STOP_LSB,
881 PCIC_IOADDR1_STOP_MSB,
882 PCIC_ADDRWIN_ENABLE_IO1,
883 PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
884 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK,
885 {
886 PCIC_IOCTL_IO1_IOCS16SRC_CARD,
887 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
888 PCIC_IOCTL_IO1_DATASIZE_8BIT,
889 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
890 PCIC_IOCTL_IO1_DATASIZE_16BIT,
891 },
892 },
893 };
894
895 void
896 pcic_chip_do_io_map(h, win)
897 struct pcic_handle *h;
898 int win;
899 {
900 int reg;
901
902 DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
903 win, (long) h->io[win].addr, (long) h->io[win].size,
904 h->io[win].width * 8));
905
906 pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff);
907 pcic_write(h, io_map_index[win].start_msb,
908 (h->io[win].addr >> 8) & 0xff);
909
910 pcic_write(h, io_map_index[win].stop_lsb,
911 (h->io[win].addr + h->io[win].size - 1) & 0xff);
912 pcic_write(h, io_map_index[win].stop_msb,
913 ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff);
914
915 reg = pcic_read(h, PCIC_IOCTL);
916 reg &= ~io_map_index[win].ioctlmask;
917 reg |= io_map_index[win].ioctlbits[h->io[win].width];
918 pcic_write(h, PCIC_IOCTL, reg);
919
920 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
921 reg |= io_map_index[win].ioenable;
922 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
923 }
924
925 int
926 pcic_chip_io_map(pch, width, offset, size, pcihp, windowp)
927 pcmcia_chipset_handle_t pch;
928 int width;
929 bus_addr_t offset;
930 bus_size_t size;
931 struct pcmcia_io_handle *pcihp;
932 int *windowp;
933 {
934 struct pcic_handle *h = (struct pcic_handle *) pch;
935 bus_addr_t ioaddr = pcihp->addr + offset;
936 static char *width_names[] = { "auto", "io8", "io16" };
937 int i, win;
938
939 /* XXX Sanity check offset/size. */
940
941 win = -1;
942 for (i = 0; i < (sizeof(io_map_index) / sizeof(io_map_index[0])); i++) {
943 if ((h->ioalloc & (1 << i)) == 0) {
944 win = i;
945 h->ioalloc |= (1 << i);
946 break;
947 }
948 }
949
950 if (win == -1)
951 return (1);
952
953 *windowp = win;
954
955 /* XXX this is pretty gross */
956
957 if (h->sc->iot != pcihp->iot)
958 panic("pcic_chip_io_map iot is bogus");
959
960 DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
961 win, width_names[width], (u_long) ioaddr, (u_long) size));
962
963 /* XXX wtf is this doing here? */
964
965 printf(" port 0x%lx", (u_long) ioaddr);
966 if (size > 1)
967 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
968
969 h->io[win].addr = ioaddr;
970 h->io[win].size = size;
971 h->io[win].width = width;
972
973 pcic_chip_do_io_map(h, win);
974
975 return (0);
976 }
977
978 void
979 pcic_chip_io_unmap(pch, window)
980 pcmcia_chipset_handle_t pch;
981 int window;
982 {
983 struct pcic_handle *h = (struct pcic_handle *) pch;
984 int reg;
985
986 if (window >= (sizeof(io_map_index) / sizeof(io_map_index[0])))
987 panic("pcic_chip_io_unmap: window out of range");
988
989 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
990 reg &= ~io_map_index[window].ioenable;
991 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
992
993 h->ioalloc &= ~(1 << window);
994 }
995
996 void
997 pcic_chip_socket_enable(pch)
998 pcmcia_chipset_handle_t pch;
999 {
1000 struct pcic_handle *h = (struct pcic_handle *) pch;
1001 int cardtype, reg, win;
1002
1003 /* this bit is mostly stolen from pcic_attach_card */
1004
1005 /* power down the socket to reset it, clear the card reset pin */
1006
1007 pcic_write(h, PCIC_PWRCTL, 0);
1008
1009 /* power up the socket */
1010
1011 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE);
1012 delay(10000);
1013 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_OE);
1014
1015 /* clear the reset flag */
1016
1017 pcic_write(h, PCIC_INTR, PCIC_INTR_RESET);
1018
1019 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
1020
1021 delay(20000);
1022
1023 /* wait for the chip to finish initializing */
1024
1025 pcic_wait_ready(h);
1026
1027 /* zero out the address windows */
1028
1029 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
1030
1031 /* set the card type */
1032
1033 cardtype = pcmcia_card_gettype(h->pcmcia);
1034
1035 reg = pcic_read(h, PCIC_INTR);
1036 reg &= ~PCIC_INTR_CARDTYPE_MASK;
1037 reg |= ((cardtype == PCMCIA_IFTYPE_IO) ?
1038 PCIC_INTR_CARDTYPE_IO :
1039 PCIC_INTR_CARDTYPE_MEM);
1040 reg |= h->ih_irq;
1041 pcic_write(h, PCIC_INTR, reg);
1042
1043 DPRINTF(("%s: pcic_chip_socket_enable %02x cardtype %s %02x\n",
1044 h->sc->dev.dv_xname, h->sock,
1045 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), reg));
1046
1047 /* reinstall all the memory and io mappings */
1048
1049 for (win = 0; win < PCIC_MEM_WINS; win++)
1050 if (h->memalloc & (1 << win))
1051 pcic_chip_do_mem_map(h, win);
1052
1053 for (win = 0; win < PCIC_IO_WINS; win++)
1054 if (h->ioalloc & (1 << win))
1055 pcic_chip_do_io_map(h, win);
1056 }
1057
1058 void
1059 pcic_chip_socket_disable(pch)
1060 pcmcia_chipset_handle_t pch;
1061 {
1062 struct pcic_handle *h = (struct pcic_handle *) pch;
1063
1064 DPRINTF(("pcic_chip_socket_disable\n"));
1065
1066 /* power down the socket */
1067
1068 pcic_write(h, PCIC_PWRCTL, 0);
1069 }
1070