i82365.c revision 1.1.2.12 1 /* $NetBSD: i82365.c,v 1.1.2.12 1997/10/16 02:50:25 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
289 h->pcmcia = config_found_sm(&h->sc->dev, &paa, pcic_print,
290 pcic_submatch);
291
292 /* if there's actually a pcmcia device attached, initialize the slot */
293
294 if (h->pcmcia)
295 pcic_init_socket(h);
296 }
297
298 void
299 pcic_init_socket(h)
300 struct pcic_handle *h;
301 {
302 int reg;
303
304 /* set up the card to interrupt on card detect */
305
306 pcic_write(h, PCIC_CSC_INTR, (h->sc->irq << PCIC_CSC_INTR_IRQ_SHIFT) |
307 PCIC_CSC_INTR_CD_ENABLE);
308 pcic_write(h, PCIC_INTR, 0);
309 pcic_read(h, PCIC_CSC);
310
311 /* unsleep the cirrus controller */
312
313 if ((h->vendor == PCIC_VENDOR_CIRRUS_PD6710) ||
314 (h->vendor == PCIC_VENDOR_CIRRUS_PD672X)) {
315 reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
316 if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
317 DPRINTF(("%s: socket %02x was suspended\n",
318 h->sc->dev.dv_xname, h->sock));
319 reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
320 pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
321 }
322 }
323 /* if there's a card there, then attach it. */
324
325 reg = pcic_read(h, PCIC_IF_STATUS);
326
327 if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
328 PCIC_IF_STATUS_CARDDETECT_PRESENT)
329 pcic_attach_card(h);
330 }
331
332 int
333 #ifdef __BROKEN_INDIRECT_CONFIG
334 pcic_submatch(parent, match, aux)
335 #else
336 pcic_submatch(parent, cf, aux)
337 #endif
338 struct device *parent;
339 #ifdef __BROKEN_INDIRECT_CONFIG
340 void *match;
341 #else
342 struct cfdata *cf;
343 #endif
344 void *aux;
345 {
346 #ifdef __BROKEN_INDIRECT_CONFIG
347 struct cfdata *cf = match;
348 #endif
349
350 struct pcmciabus_attach_args *paa =
351 (struct pcmciabus_attach_args *) aux;
352 struct pcic_handle *h = (struct pcic_handle *) paa->pch;
353
354 switch (h->sock) {
355 case C0SA:
356 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
357 return 0;
358 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
359 return 0;
360
361 break;
362 case C0SB:
363 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 0)
364 return 0;
365 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
366 return 0;
367
368 break;
369 case C1SA:
370 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
371 return 0;
372 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 0)
373 return 0;
374
375 break;
376 case C1SB:
377 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != 1)
378 return 0;
379 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != 1)
380 return 0;
381
382 break;
383 default:
384 panic("unknown pcic socket");
385 }
386
387 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
388 }
389
390 int
391 pcic_print(arg, pnp)
392 void *arg;
393 const char *pnp;
394 {
395 struct pcmciabus_attach_args *paa =
396 (struct pcmciabus_attach_args *) arg;
397 struct pcic_handle *h = (struct pcic_handle *) paa->pch;
398
399 /* Only "pcmcia"s can attach to "pcic"s... easy. */
400 if (pnp)
401 printf("pcmcia at %s", pnp);
402
403 switch (h->sock) {
404 case C0SA:
405 printf(" controller 0 socket 0");
406 break;
407 case C0SB:
408 printf(" controller 0 socket 1");
409 break;
410 case C1SA:
411 printf(" controller 1 socket 0");
412 break;
413 case C1SB:
414 printf(" controller 1 socket 1");
415 break;
416 default:
417 panic("unknown pcic socket");
418 }
419
420 return (UNCONF);
421 }
422
423 int
424 pcic_intr(arg)
425 void *arg;
426 {
427 struct pcic_softc *sc = (struct pcic_softc *) arg;
428 int i, ret = 0;
429
430 DPRINTF(("%s: intr\n", sc->dev.dv_xname));
431
432 for (i = 0; i < PCIC_NSLOTS; i++)
433 if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
434 ret += pcic_intr_socket(&sc->handle[i]);
435
436 return (ret ? 1 : 0);
437 }
438
439 int
440 pcic_intr_socket(h)
441 struct pcic_handle *h;
442 {
443 int cscreg;
444
445 cscreg = pcic_read(h, PCIC_CSC);
446
447 cscreg &= (PCIC_CSC_GPI |
448 PCIC_CSC_CD |
449 PCIC_CSC_READY |
450 PCIC_CSC_BATTWARN |
451 PCIC_CSC_BATTDEAD);
452
453 if (cscreg & PCIC_CSC_GPI) {
454 DPRINTF(("%s: %02x GPI\n", h->sc->dev.dv_xname, h->sock));
455 }
456 if (cscreg & PCIC_CSC_CD) {
457 int statreg;
458
459 statreg = pcic_read(h, PCIC_IF_STATUS);
460
461 DPRINTF(("%s: %02x CD %x\n", h->sc->dev.dv_xname, h->sock,
462 statreg));
463
464 /*
465 * XXX This should probably schedule something to happen
466 * after the interrupt handler completes
467 */
468
469 if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
470 PCIC_IF_STATUS_CARDDETECT_PRESENT) {
471 if (!(h->flags & PCIC_FLAG_CARDP))
472 pcic_attach_card(h);
473 } else {
474 if (h->flags & PCIC_FLAG_CARDP)
475 pcic_detach_card(h);
476 }
477 }
478 if (cscreg & PCIC_CSC_READY) {
479 DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock));
480 /* shouldn't happen */
481 }
482 if (cscreg & PCIC_CSC_BATTWARN) {
483 DPRINTF(("%s: %02x BATTWARN\n", h->sc->dev.dv_xname, h->sock));
484 }
485 if (cscreg & PCIC_CSC_BATTDEAD) {
486 DPRINTF(("%s: %02x BATTDEAD\n", h->sc->dev.dv_xname, h->sock));
487 }
488 return (cscreg ? 1 : 0);
489 }
490
491 void
492 pcic_attach_card(h)
493 struct pcic_handle *h;
494 {
495 if (h->flags & PCIC_FLAG_CARDP)
496 panic("pcic_attach_card: already attached");
497
498 /* call the MI attach function */
499
500 pcmcia_card_attach(h->pcmcia);
501
502 h->flags |= PCIC_FLAG_CARDP;
503 }
504
505 void
506 pcic_detach_card(h)
507 struct pcic_handle *h;
508 {
509 if (!(h->flags & PCIC_FLAG_CARDP))
510 panic("pcic_attach_card: already detached");
511
512 h->flags &= ~PCIC_FLAG_CARDP;
513
514 /* call the MI attach function */
515
516 pcmcia_card_detach(h->pcmcia);
517
518 /* disable card detect resume and configuration reset */
519
520 /* power down the socket */
521
522 pcic_write(h, PCIC_PWRCTL, 0);
523
524 /* reset the card */
525
526 pcic_write(h, PCIC_INTR, 0);
527 }
528
529 int
530 pcic_chip_mem_alloc(pch, size, pcmhp)
531 pcmcia_chipset_handle_t pch;
532 bus_size_t size;
533 struct pcmcia_mem_handle *pcmhp;
534 {
535 struct pcic_handle *h = (struct pcic_handle *) pch;
536 bus_space_handle_t memh;
537 bus_addr_t addr;
538 bus_size_t sizepg;
539 int i, mask, mhandle;
540
541 /* out of sc->memh, allocate as many pages as necessary */
542
543 /* convert size to PCIC pages */
544 sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN;
545
546 mask = (1 << sizepg) - 1;
547
548 addr = 0; /* XXX gcc -Wuninitialized */
549 mhandle = 0; /* XXX gcc -Wuninitialized */
550
551 for (i = 0; i < (PCIC_MEM_PAGES + 1 - sizepg); i++) {
552 if ((h->sc->subregionmask & (mask << i)) == (mask << i)) {
553 if (bus_space_subregion(h->sc->memt, h->sc->memh,
554 i * PCIC_MEM_PAGESIZE,
555 sizepg * PCIC_MEM_PAGESIZE, &memh))
556 return (1);
557 mhandle = mask << i;
558 addr = h->sc->membase + (i * PCIC_MEM_PAGESIZE);
559 h->sc->subregionmask &= ~(mhandle);
560 break;
561 }
562 }
563
564 if (i == (PCIC_MEM_PAGES + 1 - size))
565 return (1);
566
567 DPRINTF(("pcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n", (u_long) addr,
568 (u_long) size));
569
570 pcmhp->memt = h->sc->memt;
571 pcmhp->memh = memh;
572 pcmhp->addr = addr;
573 pcmhp->size = size;
574 pcmhp->mhandle = mhandle;
575 pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
576
577 return (0);
578 }
579
580 void
581 pcic_chip_mem_free(pch, pcmhp)
582 pcmcia_chipset_handle_t pch;
583 struct pcmcia_mem_handle *pcmhp;
584 {
585 struct pcic_handle *h = (struct pcic_handle *) pch;
586
587 h->sc->subregionmask |= pcmhp->mhandle;
588 }
589
590 static struct mem_map_index_st {
591 int sysmem_start_lsb;
592 int sysmem_start_msb;
593 int sysmem_stop_lsb;
594 int sysmem_stop_msb;
595 int cardmem_lsb;
596 int cardmem_msb;
597 int memenable;
598 } mem_map_index[] = {
599 {
600 PCIC_SYSMEM_ADDR0_START_LSB,
601 PCIC_SYSMEM_ADDR0_START_MSB,
602 PCIC_SYSMEM_ADDR0_STOP_LSB,
603 PCIC_SYSMEM_ADDR0_STOP_MSB,
604 PCIC_CARDMEM_ADDR0_LSB,
605 PCIC_CARDMEM_ADDR0_MSB,
606 PCIC_ADDRWIN_ENABLE_MEM0,
607 },
608 {
609 PCIC_SYSMEM_ADDR1_START_LSB,
610 PCIC_SYSMEM_ADDR1_START_MSB,
611 PCIC_SYSMEM_ADDR1_STOP_LSB,
612 PCIC_SYSMEM_ADDR1_STOP_MSB,
613 PCIC_CARDMEM_ADDR1_LSB,
614 PCIC_CARDMEM_ADDR1_MSB,
615 PCIC_ADDRWIN_ENABLE_MEM1,
616 },
617 {
618 PCIC_SYSMEM_ADDR2_START_LSB,
619 PCIC_SYSMEM_ADDR2_START_MSB,
620 PCIC_SYSMEM_ADDR2_STOP_LSB,
621 PCIC_SYSMEM_ADDR2_STOP_MSB,
622 PCIC_CARDMEM_ADDR2_LSB,
623 PCIC_CARDMEM_ADDR2_MSB,
624 PCIC_ADDRWIN_ENABLE_MEM2,
625 },
626 {
627 PCIC_SYSMEM_ADDR3_START_LSB,
628 PCIC_SYSMEM_ADDR3_START_MSB,
629 PCIC_SYSMEM_ADDR3_STOP_LSB,
630 PCIC_SYSMEM_ADDR3_STOP_MSB,
631 PCIC_CARDMEM_ADDR3_LSB,
632 PCIC_CARDMEM_ADDR3_MSB,
633 PCIC_ADDRWIN_ENABLE_MEM3,
634 },
635 {
636 PCIC_SYSMEM_ADDR4_START_LSB,
637 PCIC_SYSMEM_ADDR4_START_MSB,
638 PCIC_SYSMEM_ADDR4_STOP_LSB,
639 PCIC_SYSMEM_ADDR4_STOP_MSB,
640 PCIC_CARDMEM_ADDR4_LSB,
641 PCIC_CARDMEM_ADDR4_MSB,
642 PCIC_ADDRWIN_ENABLE_MEM4,
643 },
644 };
645
646 void
647 pcic_chip_do_mem_map(h, win)
648 struct pcic_handle *h;
649 int win;
650 {
651 int reg;
652
653 pcic_write(h, mem_map_index[win].sysmem_start_lsb,
654 (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
655 pcic_write(h, mem_map_index[win].sysmem_start_msb,
656 ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
657 PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK));
658
659 #if 0
660 /* XXX do I want 16 bit all the time? */
661 PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT;
662 #endif
663
664 pcic_write(h, mem_map_index[win].sysmem_stop_lsb,
665 ((h->mem[win].addr + h->mem[win].size) >>
666 PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
667 pcic_write(h, mem_map_index[win].sysmem_stop_msb,
668 (((h->mem[win].addr + h->mem[win].size) >>
669 (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
670 PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
671 PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
672
673 pcic_write(h, mem_map_index[win].cardmem_lsb,
674 (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
675 pcic_write(h, mem_map_index[win].cardmem_msb,
676 ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) &
677 PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) |
678 ((h->mem[win].kind == PCMCIA_MEM_ATTR) ?
679 PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0));
680
681 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
682 reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16);
683 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
684
685 #ifdef PCICDEBUG
686 {
687 int r1, r2, r3, r4, r5, r6;
688
689 r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb);
690 r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb);
691 r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb);
692 r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb);
693 r5 = pcic_read(h, mem_map_index[win].cardmem_msb);
694 r6 = pcic_read(h, mem_map_index[win].cardmem_lsb);
695
696 DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x "
697 "%02x%02x\n", win, r1, r2, r3, r4, r5, r6));
698 }
699 #endif
700 }
701
702 int
703 pcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
704 pcmcia_chipset_handle_t pch;
705 int kind;
706 bus_addr_t card_addr;
707 bus_size_t size;
708 struct pcmcia_mem_handle *pcmhp;
709 bus_addr_t *offsetp;
710 int *windowp;
711 {
712 struct pcic_handle *h = (struct pcic_handle *) pch;
713 bus_addr_t busaddr;
714 long card_offset;
715 int i, win;
716
717 win = -1;
718 for (i = 0; i < (sizeof(mem_map_index) / sizeof(mem_map_index[0]));
719 i++) {
720 if ((h->memalloc & (1 << i)) == 0) {
721 win = i;
722 h->memalloc |= (1 << i);
723 break;
724 }
725 }
726
727 if (win == -1)
728 return (1);
729
730 *windowp = win;
731
732 /* XXX this is pretty gross */
733
734 if (h->sc->memt != pcmhp->memt)
735 panic("pcic_chip_mem_map memt is bogus");
736
737 busaddr = pcmhp->addr;
738
739 /*
740 * compute the address offset to the pcmcia address space for the
741 * pcic. this is intentionally signed. The masks and shifts below
742 * will cause TRT to happen in the pcic registers. Deal with making
743 * sure the address is aligned, and return the alignment offset.
744 */
745
746 *offsetp = card_addr % PCIC_MEM_ALIGN;
747 card_addr -= *offsetp;
748
749 DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr "
750 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
751 (u_long) card_addr));
752
753 /*
754 * include the offset in the size, and decrement size by one, since
755 * the hw wants start/stop
756 */
757 size += *offsetp - 1;
758
759 card_offset = (((long) card_addr) - ((long) busaddr));
760
761 h->mem[win].addr = busaddr;
762 h->mem[win].size = size;
763 h->mem[win].offset = card_offset;
764 h->mem[win].kind = kind;
765
766 pcic_chip_do_mem_map(h, win);
767
768 return (0);
769 }
770
771 void
772 pcic_chip_mem_unmap(pch, window)
773 pcmcia_chipset_handle_t pch;
774 int window;
775 {
776 struct pcic_handle *h = (struct pcic_handle *) pch;
777 int reg;
778
779 if (window >= (sizeof(mem_map_index) / sizeof(mem_map_index[0])))
780 panic("pcic_chip_mem_unmap: window out of range");
781
782 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
783 reg &= ~mem_map_index[window].memenable;
784 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
785
786 h->memalloc &= ~(1 << window);
787 }
788
789 int
790 pcic_chip_io_alloc(pch, start, size, align, pcihp)
791 pcmcia_chipset_handle_t pch;
792 bus_addr_t start;
793 bus_size_t size;
794 bus_size_t align;
795 struct pcmcia_io_handle *pcihp;
796 {
797 struct pcic_handle *h = (struct pcic_handle *) pch;
798 bus_space_tag_t iot;
799 bus_space_handle_t ioh;
800 bus_addr_t ioaddr;
801 int flags = 0;
802
803 /*
804 * Allocate some arbitrary I/O space.
805 */
806
807 iot = h->sc->iot;
808
809 if (start) {
810 ioaddr = start;
811 if (bus_space_map(iot, start, size, 0, &ioh))
812 return (1);
813 DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
814 (u_long) ioaddr, (u_long) size));
815 } else {
816 flags |= PCMCIA_IO_ALLOCATED;
817 if (bus_space_alloc(iot, h->sc->iobase,
818 h->sc->iobase + h->sc->iosize, size, align, 0, 0,
819 &ioaddr, &ioh))
820 return (1);
821 DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
822 (u_long) ioaddr, (u_long) size));
823 }
824
825 pcihp->iot = iot;
826 pcihp->ioh = ioh;
827 pcihp->addr = ioaddr;
828 pcihp->size = size;
829 pcihp->flags = flags;
830
831 return (0);
832 }
833
834 void
835 pcic_chip_io_free(pch, pcihp)
836 pcmcia_chipset_handle_t pch;
837 struct pcmcia_io_handle *pcihp;
838 {
839 bus_space_tag_t iot = pcihp->iot;
840 bus_space_handle_t ioh = pcihp->ioh;
841 bus_size_t size = pcihp->size;
842
843 if (pcihp->flags & PCMCIA_IO_ALLOCATED)
844 bus_space_free(iot, ioh, size);
845 else
846 bus_space_unmap(iot, ioh, size);
847 }
848
849
850 static struct io_map_index_st {
851 int start_lsb;
852 int start_msb;
853 int stop_lsb;
854 int stop_msb;
855 int ioenable;
856 int ioctlmask;
857 int ioctl8;
858 int ioctl16;
859 } io_map_index[] = {
860 {
861 PCIC_IOADDR0_START_LSB,
862 PCIC_IOADDR0_START_MSB,
863 PCIC_IOADDR0_STOP_LSB,
864 PCIC_IOADDR0_STOP_MSB,
865 PCIC_ADDRWIN_ENABLE_IO0,
866 PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
867 PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK,
868 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
869 PCIC_IOCTL_IO0_DATASIZE_8BIT,
870 PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
871 PCIC_IOCTL_IO0_DATASIZE_16BIT,
872 },
873 {
874 PCIC_IOADDR1_START_LSB,
875 PCIC_IOADDR1_START_MSB,
876 PCIC_IOADDR1_STOP_LSB,
877 PCIC_IOADDR1_STOP_MSB,
878 PCIC_ADDRWIN_ENABLE_IO1,
879 PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
880 PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK,
881 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
882 PCIC_IOCTL_IO1_DATASIZE_8BIT,
883 PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
884 PCIC_IOCTL_IO1_DATASIZE_16BIT,
885 },
886 };
887
888 void
889 pcic_chip_do_io_map(h, win)
890 struct pcic_handle *h;
891 int win;
892 {
893 int reg;
894
895 DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
896 win, (long) h->io[win].addr, (long) h->io[win].size,
897 h->io[win].width * 8));
898
899 pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff);
900 pcic_write(h, io_map_index[win].start_msb,
901 (h->io[win].addr >> 8) & 0xff);
902
903 pcic_write(h, io_map_index[win].stop_lsb,
904 (h->io[win].addr + h->io[win].size - 1) & 0xff);
905 pcic_write(h, io_map_index[win].stop_msb,
906 ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff);
907
908 reg = pcic_read(h, PCIC_IOCTL);
909 reg &= ~io_map_index[win].ioctlmask;
910 if (h->io[win].width == PCMCIA_WIDTH_IO8)
911 reg |= io_map_index[win].ioctl8;
912 else
913 reg |= io_map_index[win].ioctl16;
914 pcic_write(h, PCIC_IOCTL, reg);
915
916 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
917 reg |= io_map_index[win].ioenable;
918 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
919 }
920
921 int
922 pcic_chip_io_map(pch, width, offset, size, pcihp, windowp)
923 pcmcia_chipset_handle_t pch;
924 int width;
925 bus_addr_t offset;
926 bus_size_t size;
927 struct pcmcia_io_handle *pcihp;
928 int *windowp;
929 {
930 struct pcic_handle *h = (struct pcic_handle *) pch;
931 bus_addr_t ioaddr = pcihp->addr + offset;
932 int i, win;
933
934 /* XXX Sanity check offset/size. */
935
936 win = -1;
937 for (i = 0; i < (sizeof(io_map_index) / sizeof(io_map_index[0])); i++) {
938 if ((h->ioalloc & (1 << i)) == 0) {
939 win = i;
940 h->ioalloc |= (1 << i);
941 break;
942 }
943 }
944
945 if (win == -1)
946 return (1);
947
948 *windowp = win;
949
950 /* XXX this is pretty gross */
951
952 if (h->sc->iot != pcihp->iot)
953 panic("pcic_chip_io_map iot is bogus");
954
955 DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
956 win, (width == PCMCIA_WIDTH_IO8) ? "io8" : "io16",
957 (u_long) ioaddr, (u_long) size));
958
959 /* XXX wtf is this doing here? */
960
961 printf(" port 0x%lx", (u_long) ioaddr);
962 if (size > 1)
963 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
964
965 h->io[win].addr = ioaddr;
966 h->io[win].size = size;
967 h->io[win].width = width;
968
969 pcic_chip_do_io_map(h, win);
970
971 return (0);
972 }
973
974 void
975 pcic_chip_io_unmap(pch, window)
976 pcmcia_chipset_handle_t pch;
977 int window;
978 {
979 struct pcic_handle *h = (struct pcic_handle *) pch;
980 int reg;
981
982 if (window >= (sizeof(io_map_index) / sizeof(io_map_index[0])))
983 panic("pcic_chip_io_unmap: window out of range");
984
985 reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
986 reg &= ~io_map_index[window].ioenable;
987 pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
988
989 h->ioalloc &= ~(1 << window);
990 }
991
992 void
993 pcic_chip_socket_enable(pch)
994 pcmcia_chipset_handle_t pch;
995 {
996 struct pcic_handle *h = (struct pcic_handle *) pch;
997 int cardtype, reg, win;
998
999 /* this bit is mostly stolen from pcic_attach_card */
1000
1001 /* power down the socket to reset it, clear the card reset pin */
1002
1003 pcic_write(h, PCIC_PWRCTL, 0);
1004
1005 /* power up the socket */
1006
1007 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE);
1008 delay(10000);
1009 pcic_write(h, PCIC_PWRCTL, PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_OE);
1010
1011 /* clear the reset flag */
1012
1013 pcic_write(h, PCIC_INTR, PCIC_INTR_RESET);
1014
1015 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
1016
1017 delay(20000);
1018
1019 /* wait for the chip to finish initializing */
1020
1021 pcic_wait_ready(h);
1022
1023 /* zero out the address windows */
1024
1025 pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
1026
1027 /* set the card type */
1028
1029 cardtype = pcmcia_card_gettype(h->pcmcia);
1030
1031 reg = pcic_read(h, PCIC_INTR);
1032 reg &= ~PCIC_INTR_CARDTYPE_MASK;
1033 reg |= ((cardtype == PCMCIA_IFTYPE_IO) ?
1034 PCIC_INTR_CARDTYPE_IO :
1035 PCIC_INTR_CARDTYPE_MEM);
1036 reg |= h->ih_irq;
1037 pcic_write(h, PCIC_INTR, reg);
1038
1039 DPRINTF(("%s: pcic_chip_socket_enable %02x cardtype %s %02x\n",
1040 h->sc->dev.dv_xname, h->sock,
1041 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), reg));
1042
1043 /* reinstall all the memory and io mappings */
1044
1045 for (win = 0; win < PCIC_MEM_WINS; win++)
1046 if (h->memalloc & (1 << win))
1047 pcic_chip_do_mem_map(h, win);
1048
1049 for (win = 0; win < PCIC_IO_WINS; win++)
1050 if (h->ioalloc & (1 << win))
1051 pcic_chip_do_io_map(h, win);
1052 }
1053
1054 void
1055 pcic_chip_socket_disable(pch)
1056 pcmcia_chipset_handle_t pch;
1057 {
1058 struct pcic_handle *h = (struct pcic_handle *) pch;
1059
1060 DPRINTF(("pcic_chip_socket_disable\n"));
1061
1062 /* power down the socket */
1063
1064 pcic_write(h, PCIC_PWRCTL, 0);
1065 }
1066