This source file includes following definitions.
- tcic_check_reserved_bits
- tcic_chipid
- tcic_chipid_known
- tcic_chipid_to_string
- tcic_validirqs
- tcic_attach
- tcic_attach_sockets
- tcic_attach_socket
- tcic_create_event_thread
- tcic_event_thread
- tcic_init_socket
- tcic_submatch
- tcic_print
- tcic_intr
- tcic_intr_socket
- tcic_queue_event
- tcic_attach_card
- tcic_detach_card
- tcic_deactivate_card
- tcic_chip_mem_alloc
- tcic_chip_mem_free
- tcic_chip_do_mem_map
- tcic_chip_mem_map
- tcic_chip_mem_unmap
- tcic_chip_io_alloc
- tcic_chip_io_free
- tcic_chip_do_io_map
- tcic_chip_io_map
- tcic_chip_io_unmap
- tcic_chip_socket_enable
- tcic_chip_socket_disable
- tcic_ns2wscnt
- tcic_log2
1
2
3
4 #undef TCICDEBUG
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
40 #include <sys/extent.h>
41 #include <sys/malloc.h>
42 #include <sys/kthread.h>
43
44 #include <uvm/uvm_extern.h>
45
46 #include <machine/bus.h>
47 #include <machine/intr.h>
48
49 #include <dev/pcmcia/pcmciareg.h>
50 #include <dev/pcmcia/pcmciavar.h>
51
52 #include <dev/ic/tcic2reg.h>
53 #include <dev/ic/tcic2var.h>
54
55 #ifdef TCICDEBUG
56 int tcic_debug = 1;
57 #define DPRINTF(arg) if (tcic_debug) printf arg;
58 #else
59 #define DPRINTF(arg)
60 #endif
61
62
63
64
65
66
67 #define TCIC_MEM_ALIGN TCIC_MEM_PAGESIZE
68
69 void tcic_attach_socket(struct tcic_handle *);
70 void tcic_init_socket(struct tcic_handle *);
71
72 int tcic_submatch(struct device *, void *, void *);
73 int tcic_print(void *arg, const char *pnp);
74 int tcic_intr_socket(struct tcic_handle *);
75
76 void tcic_attach_card(struct tcic_handle *);
77 void tcic_detach_card(struct tcic_handle *, int);
78 void tcic_deactivate_card(struct tcic_handle *);
79
80 void tcic_chip_do_mem_map(struct tcic_handle *, int);
81 void tcic_chip_do_io_map(struct tcic_handle *, int);
82
83 void tcic_create_event_thread(void *);
84 void tcic_event_thread(void *);
85
86 void tcic_queue_event(struct tcic_handle *, int);
87
88 struct cfdriver tcic_cd = {
89 NULL, "tcic", DV_DULL
90 };
91
92
93 #if 1
94 int tcic_irqmap[] =
95 { 0, 0, 0, 3, 4, 5, 6, 7, 0, 0, 10, 1, 0, 0, 14, 0 };
96 int tcic_valid_irqs = 0x4cf8;
97 #else
98 int tcic_irqmap[] =
99 { 0, 0, 0, 3, 4, 5, 0, 7, 0, 6, 10, 1, 0, 0, 14, 0 };
100 int tcic_valid_irqs = 0x4eb8;
101 #endif
102
103 int tcic_mem_speed = 250;
104 int tcic_io_speed = 165;
105
106
107
108
109 int
110 tcic_check_reserved_bits(iot, ioh)
111 bus_space_tag_t iot;
112 bus_space_handle_t ioh;
113 {
114 int val, auxreg;
115
116 DPRINTF(("tcic: chkrsvd 1\n"));
117
118 val = (bus_space_read_2(iot, ioh, TCIC_R_ADDR2) & TCIC_SS_MASK)
119 >> TCIC_SS_SHIFT;
120 if (val > 1)
121 return 0;
122
123 DPRINTF(("tcic: chkrsvd 2\n"));
124
125 val = bus_space_read_1(iot, ioh, TCIC_R_SCTRL);
126 if (val & TCIC_SCTRL_RSVD)
127 return 0;
128
129 DPRINTF(("tcic: chkrsvd 3\n"));
130
131 val = bus_space_read_1(iot, ioh, TCIC_R_ICSR);
132 if (((val >> 1) & 1) != ((val >> 2) & 1))
133 return 0;
134
135 DPRINTF(("tcic: chkrsvd 4\n"));
136
137 val = bus_space_read_1(iot, ioh, TCIC_R_IENA);
138 if (val & TCIC_IENA_RSVD)
139 return 0;
140
141 DPRINTF(("tcic: chkrsvd 5\n"));
142
143
144 auxreg = bus_space_read_1(iot, ioh, TCIC_R_MODE)
145 & TCIC_AR_MASK;
146 val = bus_space_read_2(iot, ioh, TCIC_R_AUX);
147 DPRINTF(("tcic: auxreg 0x%02x val 0x%04x\n", auxreg, val));
148 switch (auxreg) {
149 case TCIC_AR_SYSCFG:
150 if (INVALID_AR_SYSCFG(val))
151 return 0;
152 break;
153 case TCIC_AR_ILOCK:
154 if (INVALID_AR_ILOCK(val))
155 return 0;
156 break;
157 case TCIC_AR_TEST:
158 if (INVALID_AR_TEST(val))
159 return 0;
160 break;
161 }
162
163 DPRINTF(("tcic: chkrsvd 6\n"));
164
165
166 val = bus_space_read_1(iot, ioh, TCIC_R_SCTRL);
167 if (val & TCIC_SCTRL_RESET) {
168 DPRINTF(("tcic: chkrsvd 7\n"));
169
170 val = bus_space_read_2(iot, ioh, TCIC_R_ADDR);
171 if (val != 0)
172 return 0;
173 val = bus_space_read_2(iot, ioh, TCIC_R_ADDR2);
174 if (val != 0)
175 return 0;
176 DPRINTF(("tcic: chkrsvd 8\n"));
177
178 val = bus_space_read_2(iot, ioh, TCIC_R_EDC);
179 if (val != 0)
180 return 0;
181
182 bus_space_write_1(iot, ioh, TCIC_R_SCTRL, 0);
183 }
184 else {
185 int omode;
186 int val1, val2;
187 DPRINTF(("tcic: chkrsvd 9\n"));
188
189 val = bus_space_read_1(iot, ioh, TCIC_R_SSTAT);
190 if ((val & (TCIC_SSTAT_6US|TCIC_SSTAT_10US|TCIC_SSTAT_PROGTIME))
191 != (TCIC_SSTAT_6US|TCIC_SSTAT_10US|TCIC_SSTAT_PROGTIME))
192 return 0;
193 DPRINTF(("tcic: chkrsvd 10\n"));
194
195
196
197
198 if ((bus_space_read_2(iot, ioh, TCIC_R_ADDR2)
199 & TCIC_ADDR2_INDREG) != 0) {
200 val1 = bus_space_read_2(iot, ioh, TCIC_R_EDC);
201 val2 = bus_space_read_2(iot, ioh, TCIC_R_DATA);
202 if (val1 | val2) {
203 val1 = bus_space_read_2(iot, ioh, TCIC_R_EDC);
204 if (val1 == val2)
205 return 0;
206 }
207 }
208 DPRINTF(("tcic: chkrsvd 11\n"));
209
210 omode = bus_space_read_1(iot, ioh, TCIC_R_MODE);
211 val1 = omode ^ TCIC_AR_MASK;
212 bus_space_write_1(iot, ioh, TCIC_R_MODE, val1);
213 val2 = bus_space_read_1(iot, ioh, TCIC_R_MODE);
214 bus_space_write_1(iot, ioh, TCIC_R_MODE, omode);
215 if ( val1 != val2)
216 return 0;
217 }
218
219 return 1;
220 }
221
222
223
224
225 int
226 tcic_chipid(iot, ioh)
227 bus_space_tag_t iot;
228 bus_space_handle_t ioh;
229 {
230 unsigned id, otest;
231
232 otest = tcic_read_aux_2(iot, ioh, TCIC_AR_TEST);
233 tcic_write_aux_2(iot, ioh, TCIC_AR_TEST, TCIC_TEST_DIAG);
234 id = tcic_read_aux_2(iot, ioh, TCIC_AR_ILOCK);
235 tcic_write_aux_2(iot, ioh, TCIC_AR_TEST, otest);
236 id &= TCIC_ILOCKTEST_ID_MASK;
237 id >>= TCIC_ILOCKTEST_ID_SHFT;
238
239
240 while (bus_space_read_1(iot, ioh, TCIC_R_ICSR))
241 bus_space_write_1(iot, ioh, TCIC_R_ICSR, TCIC_ICSR_JAM);
242
243 return id;
244 }
245
246
247
248 int
249 tcic_chipid_known(id)
250 int id;
251 {
252
253 switch (id) {
254 case TCIC_CHIPID_DB86082_1:
255 case TCIC_CHIPID_DB86082A:
256 case TCIC_CHIPID_DB86082B_ES:
257 case TCIC_CHIPID_DB86082B:
258 case TCIC_CHIPID_DB86084_1:
259 case TCIC_CHIPID_DB86084A:
260 case TCIC_CHIPID_DB86184_1:
261 case TCIC_CHIPID_DB86072_1_ES:
262 case TCIC_CHIPID_DB86072_1:
263 return 1;
264 }
265
266 return 0;
267 }
268
269 char *
270 tcic_chipid_to_string(id)
271 int id;
272 {
273 switch (id) {
274 case TCIC_CHIPID_DB86082_1:
275 return ("Databook DB86082");
276 case TCIC_CHIPID_DB86082A:
277 return ("Databook DB86082A");
278 case TCIC_CHIPID_DB86082B_ES:
279 return ("Databook DB86082B-es");
280 case TCIC_CHIPID_DB86082B:
281 return ("Databook DB86082B");
282 case TCIC_CHIPID_DB86084_1:
283 return ("Databook DB86084");
284 case TCIC_CHIPID_DB86084A:
285 return ("Databook DB86084A");
286 case TCIC_CHIPID_DB86184_1:
287 return ("Databook DB86184");
288 case TCIC_CHIPID_DB86072_1_ES:
289 return ("Databook DB86072-es");
290 case TCIC_CHIPID_DB86072_1:
291 return ("Databook DB86072");
292 }
293
294 return ("Unknown controller");
295 }
296
297
298
299
300 int
301 tcic_validirqs(chipid)
302 int chipid;
303 {
304 switch (chipid) {
305 case TCIC_CHIPID_DB86082_1:
306 case TCIC_CHIPID_DB86082A:
307 case TCIC_CHIPID_DB86082B_ES:
308 case TCIC_CHIPID_DB86082B:
309 case TCIC_CHIPID_DB86084_1:
310 case TCIC_CHIPID_DB86084A:
311 case TCIC_CHIPID_DB86184_1:
312 case TCIC_CHIPID_DB86072_1_ES:
313 case TCIC_CHIPID_DB86072_1:
314 return tcic_valid_irqs;
315 }
316 return 0;
317 }
318
319 void
320 tcic_attach(sc)
321 struct tcic_softc *sc;
322 {
323 int i, reg;
324
325
326 switch (sc->chipid) {
327 case TCIC_CHIPID_DB86084_1:
328 case TCIC_CHIPID_DB86084A:
329 case TCIC_CHIPID_DB86184_1:
330 sc->pwrena = TCIC_PWR_ENA;
331 break;
332 default:
333 sc->pwrena = 0;
334 break;
335 }
336
337
338 reg = TCIC_WAIT_SYNC | TCIC_WAIT_CCLK | TCIC_WAIT_RISING;
339 reg |= (tcic_ns2wscnt(250) & TCIC_WAIT_COUNT_MASK);
340 tcic_write_aux_1(sc->iot, sc->ioh, TCIC_AR_WCTL, TCIC_R_WCTL_WAIT, reg);
341 reg = TCIC_SYSCFG_MPSEL_RI | TCIC_SYSCFG_MCSFULL;
342 tcic_write_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG, reg);
343 reg = tcic_read_aux_2(sc->iot, sc->ioh, TCIC_AR_ILOCK);
344 reg |= TCIC_ILOCK_HOLD_CCLK;
345 tcic_write_aux_2(sc->iot, sc->ioh, TCIC_AR_ILOCK, reg);
346
347
348
349 for (i = 0; i < TCIC_NSLOTS; i++) {
350 sc->handle[i].sc = sc;
351 sc->handle[i].sock = i;
352 sc->handle[i].flags = TCIC_FLAG_SOCKETP;
353 sc->handle[i].memwins
354 = sc->chipid == TCIC_CHIPID_DB86082_1 ? 4 : 5;
355 }
356
357
358 reg = tcic_read_1(&sc->handle[0], TCIC_R_IENA);
359 tcic_write_1(&sc->handle[0], TCIC_R_IENA,
360 (reg & ~TCIC_IENA_CFG_MASK) | TCIC_IENA_CFG_HIGH);
361 reg = tcic_read_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG);
362 tcic_write_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG,
363 (reg & ~TCIC_SYSCFG_IRQ_MASK) | tcic_irqmap[sc->irq]);
364
365
366
367 for (i = 0; i < TCIC_NSLOTS; i++) {
368
369 tcic_sel_sock(&sc->handle[i]);
370 tcic_write_ind_2(&sc->handle[i], TCIC_IR_SCF1_N(i), 0);
371 tcic_write_ind_2(&sc->handle[i], TCIC_IR_SCF2_N(i),
372 (TCIC_SCF2_MCD|TCIC_SCF2_MWP|TCIC_SCF2_MRDY
373 #if 1
374 |TCIC_SCF2_MLBAT2|TCIC_SCF2_MLBAT1|TCIC_SCF2_IDBR));
375 #else
376 |TCIC_SCF2_MLBAT2|TCIC_SCF2_MLBAT1));
377 #endif
378 tcic_write_1(&sc->handle[i], TCIC_R_MODE, 0);
379 reg = tcic_read_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG);
380 reg &= ~TCIC_SYSCFG_AUTOBUSY;
381 tcic_write_aux_2(sc->iot, sc->ioh, TCIC_AR_SYSCFG, reg);
382 SIMPLEQ_INIT(&sc->handle[i].events);
383 }
384
385 if ((sc->handle[0].flags & TCIC_FLAG_SOCKETP) ||
386 (sc->handle[1].flags & TCIC_FLAG_SOCKETP)) {
387 printf("%s: %s has ", sc->dev.dv_xname,
388 tcic_chipid_to_string(sc->chipid));
389
390 if ((sc->handle[0].flags & TCIC_FLAG_SOCKETP) &&
391 (sc->handle[1].flags & TCIC_FLAG_SOCKETP))
392 printf("sockets A and B\n");
393 else if (sc->handle[0].flags & TCIC_FLAG_SOCKETP)
394 printf("socket A only\n");
395 else
396 printf("socket B only\n");
397
398 }
399 }
400
401 void
402 tcic_attach_sockets(sc)
403 struct tcic_softc *sc;
404 {
405 int i;
406
407 for (i = 0; i < TCIC_NSLOTS; i++)
408 if (sc->handle[i].flags & TCIC_FLAG_SOCKETP)
409 tcic_attach_socket(&sc->handle[i]);
410 }
411
412 void
413 tcic_attach_socket(h)
414 struct tcic_handle *h;
415 {
416 struct pcmciabus_attach_args paa;
417
418
419
420 h->shutdown = 0;
421 h->memalloc = 0;
422 h->ioalloc = 0;
423 h->ih_irq = 0;
424
425
426
427 paa.paa_busname = "pcmcia";
428 paa.pct = (pcmcia_chipset_tag_t) h->sc->pct;
429 paa.pch = (pcmcia_chipset_handle_t) h;
430 paa.iobase = h->sc->iobase;
431 paa.iosize = h->sc->iosize;
432
433 h->pcmcia = config_found_sm(&h->sc->dev, &paa, tcic_print,
434 tcic_submatch);
435
436
437
438 if (h->pcmcia)
439 tcic_init_socket(h);
440 else
441 h->flags &= ~TCIC_FLAG_SOCKETP;
442 }
443
444 void
445 tcic_create_event_thread(arg)
446 void *arg;
447 {
448 struct tcic_handle *h = arg;
449 const char *cs;
450
451 switch (h->sock) {
452 case 0:
453 cs = "0";
454 break;
455 case 1:
456 cs = "1";
457 break;
458 default:
459 panic("tcic_create_event_thread: unknown tcic socket");
460 }
461
462 if (kthread_create(tcic_event_thread, h, &h->event_thread,
463 "%s,%s", h->sc->dev.dv_xname, cs)) {
464 printf("%s: unable to create event thread for sock 0x%02x\n",
465 h->sc->dev.dv_xname, h->sock);
466 panic("tcic_create_event_thread");
467 }
468 }
469
470 void
471 tcic_event_thread(arg)
472 void *arg;
473 {
474 struct tcic_handle *h = arg;
475 struct tcic_event *pe;
476 int s;
477
478 while (h->shutdown == 0) {
479 s = splhigh();
480 if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) {
481 splx(s);
482 (void) tsleep(&h->events, PWAIT, "tcicev", 0);
483 continue;
484 }
485 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
486 splx(s);
487
488 switch (pe->pe_type) {
489 case TCIC_EVENT_INSERTION:
490 DPRINTF(("%s: insertion event\n", h->sc->dev.dv_xname));
491 tcic_attach_card(h);
492 break;
493
494 case TCIC_EVENT_REMOVAL:
495 DPRINTF(("%s: removal event\n", h->sc->dev.dv_xname));
496 tcic_detach_card(h, DETACH_FORCE);
497 break;
498
499 default:
500 panic("tcic_event_thread: unknown event %d",
501 pe->pe_type);
502 }
503 free(pe, M_TEMP);
504 }
505
506 h->event_thread = NULL;
507
508
509 wakeup(h->sc);
510
511 kthread_exit(0);
512 }
513
514
515 void
516 tcic_init_socket(h)
517 struct tcic_handle *h;
518 {
519 int reg;
520
521
522 tcic_sel_sock(h);
523
524
525 reg = tcic_read_ind_2(h, TCIC_IR_SCF2_N(h->sock));
526 tcic_write_ind_2(h, TCIC_IR_SCF2_N(h->sock), reg & ~TCIC_SCF2_MCD);
527
528
529 reg = tcic_read_2(h, TCIC_R_IENA);
530 tcic_write_2(h, TCIC_R_IENA, reg |= TCIC_IENA_CDCHG);
531
532
533 h->sstat = reg = tcic_read_1(h, TCIC_R_SSTAT) & TCIC_SSTAT_STAT_MASK;
534 if (reg & TCIC_SSTAT_CD)
535 tcic_attach_card(h);
536 }
537
538 int
539 tcic_submatch(parent, match, aux)
540 struct device *parent;
541 void *match;
542 void *aux;
543 {
544 struct cfdata *cf = match;
545
546 struct pcmciabus_attach_args *paa = aux;
547 struct tcic_handle *h = (struct tcic_handle *) paa->pch;
548
549 switch (h->sock) {
550 case 0:
551 if (cf->cf_loc[0 ] !=
552 -1 &&
553 cf->cf_loc[0 ] != 0)
554 return 0;
555 if (cf->cf_loc[1 ] !=
556 -1 &&
557 cf->cf_loc[1 ] != 0)
558 return 0;
559
560 break;
561 case 1:
562 if (cf->cf_loc[0 ] !=
563 -1 &&
564 cf->cf_loc[0 ] != 0)
565 return 0;
566 if (cf->cf_loc[1 ] !=
567 -1 &&
568 cf->cf_loc[1 ] != 1)
569 return 0;
570
571 break;
572 default:
573 panic("unknown tcic socket");
574 }
575
576 return ((*cf->cf_attach->ca_match)(parent, cf, aux));
577 }
578
579 int
580 tcic_print(arg, pnp)
581 void *arg;
582 const char *pnp;
583 {
584 struct pcmciabus_attach_args *paa = arg;
585 struct tcic_handle *h = (struct tcic_handle *) paa->pch;
586
587
588 if (pnp)
589 printf("pcmcia at %s", pnp);
590
591 switch (h->sock) {
592 case 0:
593 printf(" socket 0");
594 break;
595 case 1:
596 printf(" socket 1");
597 break;
598 default:
599 panic("unknown tcic socket");
600 }
601 return (UNCONF);
602 }
603
604 int
605 tcic_intr(arg)
606 void *arg;
607 {
608 struct tcic_softc *sc = arg;
609 int i, ret = 0;
610
611 DPRINTF(("%s: intr\n", sc->dev.dv_xname));
612
613 for (i = 0; i < TCIC_NSLOTS; i++)
614 if (sc->handle[i].flags & TCIC_FLAG_SOCKETP)
615 ret += tcic_intr_socket(&sc->handle[i]);
616
617 return (ret ? 1 : 0);
618 }
619
620 int
621 tcic_intr_socket(h)
622 struct tcic_handle *h;
623 {
624 int icsr, rv;
625
626 rv = 0;
627 tcic_sel_sock(h);
628 icsr = tcic_read_1(h, TCIC_R_ICSR);
629
630 DPRINTF(("%s: %d icsr: 0x%02x \n", h->sc->dev.dv_xname, h->sock, icsr));
631
632
633 if (icsr & TCIC_ICSR_PROGTIME) {
634 DPRINTF(("%s: %02x PROGTIME\n", h->sc->dev.dv_xname, h->sock));
635 rv = 1;
636 }
637 if (icsr & TCIC_ICSR_ILOCK) {
638 DPRINTF(("%s: %02x ILOCK\n", h->sc->dev.dv_xname, h->sock));
639 rv = 1;
640 }
641 if (icsr & TCIC_ICSR_ERR) {
642 DPRINTF(("%s: %02x ERR\n", h->sc->dev.dv_xname, h->sock));
643 rv = 1;
644 }
645 if (icsr & TCIC_ICSR_CDCHG) {
646 int sstat, delta;
647
648
649 sstat = tcic_read_aux_1(h->sc->iot, h->sc->ioh,
650 TCIC_AR_WCTL, TCIC_R_WCTL_XCSR) & TCIC_XCSR_STAT_MASK;
651 delta = h->sstat ^ sstat;
652 h->sstat = sstat;
653
654 if (delta)
655 rv = 1;
656
657 DPRINTF(("%s: %02x CDCHG %x\n", h->sc->dev.dv_xname, h->sock,
658 delta));
659
660
661
662
663
664
665 if (delta & TCIC_SSTAT_CD) {
666 if (sstat & TCIC_SSTAT_CD) {
667 if (!(h->flags & TCIC_FLAG_CARDP)) {
668 DPRINTF(("%s: enqueing INSERTION event\n",
669 h->sc->dev.dv_xname));
670 tcic_queue_event(h, TCIC_EVENT_INSERTION);
671 }
672 } else {
673 if (h->flags & TCIC_FLAG_CARDP) {
674
675 DPRINTF(("%s: deactivating card\n",
676 h->sc->dev.dv_xname));
677 tcic_deactivate_card(h);
678
679 DPRINTF(("%s: enqueing REMOVAL event\n",
680 h->sc->dev.dv_xname));
681 tcic_queue_event(h, TCIC_EVENT_REMOVAL);
682 }
683 }
684 }
685 if (delta & TCIC_SSTAT_RDY) {
686 DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock));
687
688 }
689 if (delta & TCIC_SSTAT_LBAT1) {
690 DPRINTF(("%s: %02x LBAT1\n", h->sc->dev.dv_xname, h->sock));
691 }
692 if (delta & TCIC_SSTAT_LBAT2) {
693 DPRINTF(("%s: %02x LBAT2\n", h->sc->dev.dv_xname, h->sock));
694 }
695 if (delta & TCIC_SSTAT_WP) {
696 DPRINTF(("%s: %02x WP\n", h->sc->dev.dv_xname, h->sock));
697 }
698 }
699 return rv;
700 }
701
702 void
703 tcic_queue_event(h, event)
704 struct tcic_handle *h;
705 int event;
706 {
707 struct tcic_event *pe;
708 int s;
709
710 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
711 if (pe == NULL)
712 panic("tcic_queue_event: can't allocate event");
713
714 pe->pe_type = event;
715 s = splhigh();
716 SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q);
717 splx(s);
718 wakeup(&h->events);
719 }
720 void
721 tcic_attach_card(h)
722 struct tcic_handle *h;
723 {
724 DPRINTF(("tcic_attach_card\n"));
725
726 if (h->flags & TCIC_FLAG_CARDP)
727 panic("tcic_attach_card: already attached");
728
729
730
731 pcmcia_card_attach(h->pcmcia);
732
733 h->flags |= TCIC_FLAG_CARDP;
734 }
735
736 void
737 tcic_detach_card(h, flags)
738 struct tcic_handle *h;
739 int flags;
740 {
741 DPRINTF(("tcic_detach_card\n"));
742
743 if (!(h->flags & TCIC_FLAG_CARDP))
744 panic("tcic_detach_card: already detached");
745
746 h->flags &= ~TCIC_FLAG_CARDP;
747
748
749
750 pcmcia_card_detach(h->pcmcia, flags);
751
752 }
753
754 void
755 tcic_deactivate_card(h)
756 struct tcic_handle *h;
757 {
758 int val, reg;
759
760 if (!(h->flags & TCIC_FLAG_CARDP))
761 panic("tcic_deactivate_card: already detached");
762
763
764 pcmcia_card_deactivate(h->pcmcia);
765
766 tcic_sel_sock(h);
767
768
769
770
771 tcic_write_1(h, TCIC_R_PWR, 0);
772
773
774
775
776 reg = TCIC_IR_SCF1_N(h->sock);
777 val = tcic_read_ind_2(h, reg);
778 tcic_write_ind_2(h, reg, (val & ~TCIC_SCF1_IRQ_MASK)|TCIC_SCF1_IRQOFF);
779 reg = TCIC_IR_SCF2_N(h->sock);
780 val = tcic_read_ind_2(h, reg);
781 tcic_write_ind_2(h, reg,
782 (val | (TCIC_SCF2_MLBAT1|TCIC_SCF2_MLBAT2|TCIC_SCF2_MRDY
783 |TCIC_SCF2_MWP|TCIC_SCF2_MCD)));
784 }
785
786
787 int
788 tcic_chip_mem_alloc(pch, size, pcmhp)
789 pcmcia_chipset_handle_t pch;
790 bus_size_t size;
791 struct pcmcia_mem_handle *pcmhp;
792 {
793 struct tcic_handle *h = (struct tcic_handle *) pch;
794 bus_space_handle_t memh;
795 bus_addr_t addr;
796 bus_size_t sizepg;
797 int i, mask, mhandle;
798
799
800
801
802
803
804
805 i = tcic_log2((u_int)size);
806 if ((1<<i) < size)
807 i++;
808 sizepg = max(i, TCIC_MEM_SHIFT) - (TCIC_MEM_SHIFT-1);
809
810 DPRINTF(("tcic_chip_mem_alloc: size %ld sizepg %ld\n", size, sizepg));
811
812
813 if (sizepg > TCIC_MEM_PAGES)
814 return 1;
815
816 mask = (1 << sizepg) - 1;
817
818 addr = 0;
819 mhandle = 0;
820
821
822 for (i = 0; i < (TCIC_MEM_PAGES + 1 - sizepg); i += sizepg) {
823 if ((h->sc->subregionmask & (mask << i)) == (mask << i)) {
824 if (bus_space_subregion(h->sc->memt, h->sc->memh,
825 i * TCIC_MEM_PAGESIZE,
826 sizepg * TCIC_MEM_PAGESIZE, &memh))
827 return (1);
828 mhandle = mask << i;
829 addr = h->sc->membase + (i * TCIC_MEM_PAGESIZE);
830 h->sc->subregionmask &= ~(mhandle);
831 break;
832 }
833 }
834
835 if (i == (TCIC_MEM_PAGES + 1 - sizepg))
836 return (1);
837
838 DPRINTF(("tcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n", (u_long) addr,
839 (u_long) size));
840
841 pcmhp->memt = h->sc->memt;
842 pcmhp->memh = memh;
843 pcmhp->addr = addr;
844 pcmhp->size = size;
845 pcmhp->mhandle = mhandle;
846 pcmhp->realsize = sizepg * TCIC_MEM_PAGESIZE;
847
848 return (0);
849 }
850
851
852 void
853 tcic_chip_mem_free(pch, pcmhp)
854 pcmcia_chipset_handle_t pch;
855 struct pcmcia_mem_handle *pcmhp;
856 {
857 struct tcic_handle *h = (struct tcic_handle *) pch;
858
859 h->sc->subregionmask |= pcmhp->mhandle;
860 }
861
862 void
863 tcic_chip_do_mem_map(h, win)
864 struct tcic_handle *h;
865 int win;
866 {
867 int reg, hwwin, wscnt;
868
869 int kind = h->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
870 int mem8 = (h->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8;
871 DPRINTF(("tcic_chip_do_mem_map window %d: 0x%lx+0x%lx 0x%lx\n",
872 win, (u_long)h->mem[win].addr, (u_long)h->mem[win].size,
873 (u_long)h->mem[win].offset));
874
875
876
877
878 hwwin = (win << 1) + h->sock;
879
880
881 tcic_write_ind_2(h, TCIC_WR_MEXT_N(hwwin), 0);
882
883
884 if (h->mem[win].size2 <= 1) {
885 reg = ((h->mem[win].addr >> TCIC_MEM_SHIFT) &
886 TCIC_MBASE_ADDR_MASK) | TCIC_MBASE_4K;
887 } else {
888 reg = ((h->mem[win].addr >> TCIC_MEM_SHIFT) &
889 TCIC_MBASE_ADDR_MASK) | (h->mem[win].size2 >> 1);
890 }
891 tcic_write_ind_2(h, TCIC_WR_MBASE_N(hwwin), reg);
892
893
894 reg = 0;
895 reg = ((h->mem[win].offset >> TCIC_MEM_SHIFT) & TCIC_MMAP_ADDR_MASK);
896 reg |= (kind == PCMCIA_MEM_ATTR) ? TCIC_MMAP_ATTR : 0;
897 DPRINTF(("tcic_chip_do_map_mem window %d(%d) mmap 0x%04x\n",
898 win, hwwin, reg));
899 tcic_write_ind_2(h, TCIC_WR_MMAP_N(hwwin), reg);
900
901
902
903
904 reg = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin)) & TCIC_MCTL_WSCNT_MASK;
905 reg |= TCIC_MCTL_ENA|TCIC_MCTL_QUIET;
906 reg |= mem8 ? TCIC_MCTL_B8 : 0;
907 reg |= (h->sock << TCIC_MCTL_SS_SHIFT) & TCIC_MCTL_SS_MASK;
908 #ifdef notyet
909 wscnt = tcic_ns2wscnt(h->mem[win].speed);
910 #else
911 wscnt = tcic_ns2wscnt(tcic_mem_speed);
912 #endif
913 if (h->sc->chipid == TCIC_CHIPID_DB86082_1) {
914
915
916
917
918 int reg2;
919 reg2 = tcic_read_ind_2(h, TCIC_WR_MCTL_N(7-hwwin));
920 reg2 &= ~TCIC_MCTL_WSCNT_MASK;
921 reg2 |= wscnt & TCIC_MCTL_WSCNT_MASK;
922 tcic_write_ind_2(h, TCIC_WR_MCTL_N(7-hwwin), reg2);
923 } else {
924 reg |= wscnt & TCIC_MCTL_WSCNT_MASK;
925 }
926 tcic_write_ind_2(h, TCIC_WR_MCTL_N(hwwin), reg);
927
928 #ifdef TCICDEBUG
929 {
930 int r1, r2, r3;
931
932 r1 = tcic_read_ind_2(h, TCIC_WR_MBASE_N(hwwin));
933 r2 = tcic_read_ind_2(h, TCIC_WR_MMAP_N(hwwin));
934 r3 = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin));
935
936 DPRINTF(("tcic_chip_do_mem_map window %d(%d): %04x %04x %04x\n",
937 win, hwwin, r1, r2, r3));
938 }
939 #endif
940 }
941
942
943 int
944 tcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
945 pcmcia_chipset_handle_t pch;
946 int kind;
947 bus_addr_t card_addr;
948 bus_size_t size;
949 struct pcmcia_mem_handle *pcmhp;
950 bus_size_t *offsetp;
951 int *windowp;
952 {
953 struct tcic_handle *h = (struct tcic_handle *) pch;
954 bus_addr_t busaddr;
955 long card_offset;
956 int i, win;
957
958 win = -1;
959 for (i = 0; i < h->memwins; i++) {
960 if ((h->memalloc & (1 << i)) == 0) {
961 win = i;
962 h->memalloc |= (1 << i);
963 break;
964 }
965 }
966
967 if (win == -1)
968 return (1);
969
970 *windowp = win;
971
972
973
974 if (h->sc->memt != pcmhp->memt)
975 panic("tcic_chip_mem_map memt is bogus");
976
977 busaddr = pcmhp->addr;
978
979
980
981
982
983
984
985
986 *offsetp = card_addr % TCIC_MEM_ALIGN;
987 card_addr -= *offsetp;
988
989 DPRINTF(("tcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr "
990 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
991 (u_long) card_addr));
992
993
994
995
996
997
998 size += *offsetp - 1;
999
1000 card_offset = (((long) card_addr) - ((long) busaddr));
1001
1002 DPRINTF(("tcic_chip_mem_map window %d card_offset 0x%lx\n",
1003 win, (u_long)card_offset));
1004
1005 h->mem[win].addr = busaddr;
1006 h->mem[win].size = size;
1007 h->mem[win].size2 = tcic_log2((u_int)pcmhp->realsize) - TCIC_MEM_SHIFT;
1008 h->mem[win].offset = card_offset;
1009 h->mem[win].kind = kind;
1010
1011 tcic_chip_do_mem_map(h, win);
1012
1013 return (0);
1014 }
1015
1016 void
1017 tcic_chip_mem_unmap(pch, window)
1018 pcmcia_chipset_handle_t pch;
1019 int window;
1020 {
1021 struct tcic_handle *h = (struct tcic_handle *) pch;
1022 int reg, hwwin;
1023
1024 if (window >= h->memwins)
1025 panic("tcic_chip_mem_unmap: window out of range");
1026
1027 hwwin = (window << 1) + h->sock;
1028 reg = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin));
1029 reg &= ~TCIC_MCTL_ENA;
1030 tcic_write_ind_2(h, TCIC_WR_MCTL_N(hwwin), reg);
1031
1032 h->memalloc &= ~(1 << window);
1033 }
1034
1035 int
1036 tcic_chip_io_alloc(pch, start, size, align, pcihp)
1037 pcmcia_chipset_handle_t pch;
1038 bus_addr_t start;
1039 bus_size_t size;
1040 bus_size_t align;
1041 struct pcmcia_io_handle *pcihp;
1042 {
1043 struct tcic_handle *h = (struct tcic_handle *) pch;
1044 bus_space_tag_t iot;
1045 bus_space_handle_t ioh;
1046 bus_addr_t ioaddr;
1047 int size2, flags = 0;
1048
1049
1050
1051
1052
1053 DPRINTF(("tcic_chip_io_alloc req 0x%lx %ld %ld\n",
1054 (u_long) start, (u_long) size, (u_long) align));
1055
1056
1057
1058
1059 size2 = tcic_log2((u_int)size);
1060 if ((1 << size2) < size)
1061 size2++;
1062
1063 if (size2 > 16)
1064 return 1;
1065 if (align) {
1066 if ((1 << size2) != align)
1067 return 1;
1068 } else {
1069 align = 1 << size2;
1070 }
1071 if (start & (align - 1))
1072 return 1;
1073
1074 iot = h->sc->iot;
1075
1076 if (start) {
1077 ioaddr = start;
1078 if (bus_space_map(iot, start, size, 0, &ioh))
1079 return (1);
1080 DPRINTF(("tcic_chip_io_alloc map port %lx+%lx\n",
1081 (u_long) ioaddr, (u_long) size));
1082 } else {
1083 flags |= PCMCIA_IO_ALLOCATED;
1084 if (bus_space_alloc(iot, h->sc->iobase,
1085 h->sc->iobase + h->sc->iosize, size, align, 0, 0,
1086 &ioaddr, &ioh))
1087 return (1);
1088 DPRINTF(("tcic_chip_io_alloc alloc port %lx+%lx\n",
1089 (u_long) ioaddr, (u_long) size));
1090 }
1091
1092 pcihp->iot = iot;
1093 pcihp->ioh = ioh;
1094 pcihp->addr = ioaddr;
1095 pcihp->size = size;
1096 pcihp->flags = flags;
1097
1098 return (0);
1099 }
1100
1101 void
1102 tcic_chip_io_free(pch, pcihp)
1103 pcmcia_chipset_handle_t pch;
1104 struct pcmcia_io_handle *pcihp;
1105 {
1106 bus_space_tag_t iot = pcihp->iot;
1107 bus_space_handle_t ioh = pcihp->ioh;
1108 bus_size_t size = pcihp->size;
1109
1110 if (pcihp->flags & PCMCIA_IO_ALLOCATED)
1111 bus_space_free(iot, ioh, size);
1112 else
1113 bus_space_unmap(iot, ioh, size);
1114 }
1115
1116 static int tcic_iowidth_map[] =
1117 { TCIC_ICTL_AUTOSZ, TCIC_ICTL_B8, TCIC_ICTL_B16 };
1118
1119 void
1120 tcic_chip_do_io_map(h, win)
1121 struct tcic_handle *h;
1122 int win;
1123 {
1124 int reg, size2, iotiny, wbase, hwwin, wscnt;
1125
1126 DPRINTF(("tcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
1127 win, (long) h->io[win].addr, (long) h->io[win].size,
1128 h->io[win].width * 8));
1129
1130
1131
1132
1133
1134 hwwin = (win << 1) + h->sock;
1135
1136
1137
1138 size2 = tcic_log2((u_int)h->io[win].size);
1139 DPRINTF(("tcic_chip_do_io_map win %d size2 %d\n", win, size2));
1140 if (size2 < 1) {
1141 iotiny = TCIC_ICTL_TINY;
1142 wbase = h->io[win].addr;
1143 } else {
1144 iotiny = 0;
1145
1146 wbase = h->io[win].addr | (1 << (size2 - 1));
1147 }
1148 tcic_write_ind_2(h, TCIC_WR_IBASE_N(hwwin), wbase);
1149
1150
1151 reg = TCIC_ICTL_ENA | TCIC_ICTL_QUIET;
1152 reg |= (h->sock << TCIC_ICTL_SS_SHIFT) & TCIC_ICTL_SS_MASK;
1153 reg |= iotiny | tcic_iowidth_map[h->io[win].width];
1154 if (h->sc->chipid != TCIC_CHIPID_DB86082_1)
1155 reg |= TCIC_ICTL_PASS16;
1156 #ifdef notyet
1157 wscnt = tcic_ns2wscnt(h->io[win].speed);
1158 #else
1159 wscnt = tcic_ns2wscnt(tcic_io_speed);
1160 #endif
1161 reg |= wscnt & TCIC_ICTL_WSCNT_MASK;
1162 tcic_write_ind_2(h, TCIC_WR_ICTL_N(hwwin), reg);
1163
1164 #ifdef TCICDEBUG
1165 {
1166 int r1, r2;
1167
1168 r1 = tcic_read_ind_2(h, TCIC_WR_IBASE_N(hwwin));
1169 r2 = tcic_read_ind_2(h, TCIC_WR_ICTL_N(hwwin));
1170
1171 DPRINTF(("tcic_chip_do_io_map window %d(%d): %04x %04x\n",
1172 win, hwwin, r1, r2));
1173 }
1174 #endif
1175 }
1176
1177 int
1178 tcic_chip_io_map(pch, width, offset, size, pcihp, windowp)
1179 pcmcia_chipset_handle_t pch;
1180 int width;
1181 bus_addr_t offset;
1182 bus_size_t size;
1183 struct pcmcia_io_handle *pcihp;
1184 int *windowp;
1185 {
1186 struct tcic_handle *h = (struct tcic_handle *) pch;
1187 bus_addr_t ioaddr = pcihp->addr + offset;
1188 int i, win;
1189 #ifdef TCICDEBUG
1190 static char *width_names[] = { "auto", "io8", "io16" };
1191 #endif
1192
1193
1194
1195 win = -1;
1196 for (i = 0; i < TCIC_IO_WINS; i++) {
1197 if ((h->ioalloc & (1 << i)) == 0) {
1198 win = i;
1199 h->ioalloc |= (1 << i);
1200 break;
1201 }
1202 }
1203
1204 if (win == -1)
1205 return (1);
1206
1207 *windowp = win;
1208
1209
1210
1211 if (h->sc->iot != pcihp->iot)
1212 panic("tcic_chip_io_map iot is bogus");
1213
1214 DPRINTF(("tcic_chip_io_map window %d %s port %lx+%lx\n",
1215 win, width_names[width], (u_long) ioaddr, (u_long) size));
1216
1217
1218
1219 printf(" port 0x%lx", (u_long) ioaddr);
1220 if (size > 1)
1221 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
1222
1223 h->io[win].addr = ioaddr;
1224 h->io[win].size = size;
1225 h->io[win].width = width;
1226
1227 tcic_chip_do_io_map(h, win);
1228
1229 return (0);
1230 }
1231
1232 void
1233 tcic_chip_io_unmap(pch, window)
1234 pcmcia_chipset_handle_t pch;
1235 int window;
1236 {
1237 struct tcic_handle *h = (struct tcic_handle *) pch;
1238 int reg, hwwin;
1239
1240 if (window >= TCIC_IO_WINS)
1241 panic("tcic_chip_io_unmap: window out of range");
1242
1243 hwwin = (window << 1) + h->sock;
1244 reg = tcic_read_ind_2(h, TCIC_WR_ICTL_N(hwwin));
1245 reg &= ~TCIC_ICTL_ENA;
1246 tcic_write_ind_2(h, TCIC_WR_ICTL_N(hwwin), reg);
1247
1248 h->ioalloc &= ~(1 << window);
1249 }
1250
1251 void
1252 tcic_chip_socket_enable(pch)
1253 pcmcia_chipset_handle_t pch;
1254 {
1255 struct tcic_handle *h = (struct tcic_handle *) pch;
1256 int cardtype, reg, win;
1257
1258 tcic_sel_sock(h);
1259
1260
1261
1262
1263
1264
1265 tcic_write_1(h, TCIC_R_PWR, 0);
1266 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK);
1267 reg |= TCIC_ILOCK_CWAIT;
1268 reg &= ~(TCIC_ILOCK_CRESET|TCIC_ILOCK_CRESENA);
1269 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1270 tcic_write_1(h, TCIC_R_SCTRL, 0);
1271
1272
1273
1274
1275 reg = TCIC_PWR_VCC_N(h->sock) | TCIC_PWR_VPP_N(h->sock) | h->sc->pwrena;
1276 if (h->sc->pwrena)
1277 reg |= TCIC_PWR_VCC5V;
1278 tcic_write_1(h, TCIC_R_PWR, reg);
1279 delay(10000);
1280
1281
1282 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK);
1283 reg |= TCIC_ILOCK_CRESENA;
1284 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1285
1286 reg |= TCIC_ILOCK_CRESET;
1287 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1288
1289 tcic_write_1(h, TCIC_R_SCTRL, TCIC_SCTRL_ENA);
1290 delay(10);
1291
1292
1293 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK);
1294 reg &= ~(TCIC_ILOCK_CRESET);
1295 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1296
1297
1298 delay(20000);
1299
1300
1301 tcic_wait_ready(h);
1302
1303
1304
1305
1306
1307 for (win = 0; win < h->memwins; win++) {
1308 tcic_write_ind_2(h, TCIC_WR_MBASE_N((win<<1)+h->sock), 0);
1309 }
1310
1311 for (win = 0; win < TCIC_IO_WINS; win++) {
1312 tcic_write_ind_2(h, TCIC_WR_IBASE_N((win<<1)+h->sock), 0);
1313 }
1314
1315
1316
1317 cardtype = pcmcia_card_gettype(h->pcmcia);
1318
1319 #if 0
1320 reg = tcic_read_ind_2(h, TCIC_IR_SCF1_N(h->sock));
1321 reg &= ~TCIC_SCF1_IRQ_MASK;
1322 #else
1323 reg = 0;
1324 #endif
1325 reg |= ((cardtype == PCMCIA_IFTYPE_IO) ?
1326 TCIC_SCF1_IOSTS : 0);
1327 reg |= tcic_irqmap[h->ih_irq];
1328 reg &= ~TCIC_SCF1_IRQOD;
1329 tcic_write_ind_2(h, TCIC_IR_SCF1_N(h->sock), reg);
1330
1331 DPRINTF(("%s: tcic_chip_socket_enable %d cardtype %s 0x%02x\n",
1332 h->sc->dev.dv_xname, h->sock,
1333 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), reg));
1334
1335
1336
1337 for (win = 0; win < h->memwins; win++)
1338 if (h->memalloc & (1 << win))
1339 tcic_chip_do_mem_map(h, win);
1340
1341 for (win = 0; win < TCIC_IO_WINS; win++)
1342 if (h->ioalloc & (1 << win))
1343 tcic_chip_do_io_map(h, win);
1344 }
1345
1346 void
1347 tcic_chip_socket_disable(pch)
1348 pcmcia_chipset_handle_t pch;
1349 {
1350 struct tcic_handle *h = (struct tcic_handle *) pch;
1351 int val;
1352
1353 DPRINTF(("tcic_chip_socket_disable\n"));
1354
1355 tcic_sel_sock(h);
1356
1357
1358 val = tcic_read_ind_2(h, TCIC_IR_SCF1_N(h->sock));
1359 val &= TCIC_SCF1_IRQ_MASK;
1360 tcic_write_ind_2(h, TCIC_IR_SCF1_N(h->sock), val);
1361
1362
1363 tcic_write_1(h, TCIC_R_SCTRL, 0);
1364 val = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK);
1365 val &= ~TCIC_ILOCK_CRESENA;
1366 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, val);
1367
1368
1369 tcic_write_1(h, TCIC_R_PWR, 0);
1370 }
1371
1372
1373
1374
1375
1376 int
1377 tcic_ns2wscnt(ns)
1378 int ns;
1379 {
1380 if (ns < 14) {
1381 return 0;
1382 } else {
1383 return (2*(ns-14))/70;
1384 }
1385 }
1386
1387 int
1388 tcic_log2(val)
1389 u_int val;
1390 {
1391 int i, l2;
1392
1393 l2 = i = 0;
1394 while (val) {
1395 if (val & 1)
1396 l2 = i;
1397 i++;
1398 val >>= 1;
1399 }
1400 return l2;
1401 }