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