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