1 /* $OpenBSD: tcic2.c,v 1.5 2004/05/04 16:59:31 grange Exp $ */
2 /* $NetBSD: tcic2.c,v 1.3 2000/01/13 09:38:17 joda Exp $ */
3
4 #undef TCICDEBUG
5
6 /*
7 * Copyright (c) 1998, 1999 Christoph Badura. All rights reserved.
8 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by Marc Horowitz.
21 * 4. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 * Individual drivers will allocate their own memory and io regions. Memory
64 * regions must be a multiple of 4k, aligned on a 4k boundary.
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 /* Map between irq numbers and internal representation */
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[] = /* irqs 9 and 6 switched, some ISA cards */
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; /* memory access time in nanoseconds */
104 int tcic_io_speed = 165; /* io access time in nanoseconds */
105
106 /*
107 * Check various reserved and otherwise in their value restricted bits.
108 */
109 int
tcic_check_reserved_bits(iot,ioh)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 /* R_ADDR bit 30:28 have a restricted range. */
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 /* R_SCTRL bits 6,2,1 are reserved. */
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 /* R_ICSR bit 2 must be same as bit 3. */
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 /* R_IENA bits 7,2 are reserverd. */
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 /* Some aux registers have reserved bits. */
143 /* Which are we looking at? */
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 /* XXX fails if pcmcia bios is enabled. */
165 /* Various bits set or not depending if in RESET mode. */
166 val = bus_space_read_1(iot, ioh, TCIC_R_SCTRL);
167 if (val & TCIC_SCTRL_RESET) {
168 DPRINTF(("tcic: chkrsvd 7\n"));
169 /* Address bits must be 0 */
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 /* EDC bits must be 0 */
178 val = bus_space_read_2(iot, ioh, TCIC_R_EDC);
179 if (val != 0)
180 return 0;
181 /* We're OK, so take it out of reset. XXX -chb */
182 bus_space_write_1(iot, ioh, TCIC_R_SCTRL, 0);
183 }
184 else { /* not in RESET mode */
185 int omode;
186 int val1, val2;
187 DPRINTF(("tcic: chkrsvd 9\n"));
188 /* Programming timers must have expired. */
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 * EDC bits should change on read from data space
196 * as long as either EDC or the data are nonzero.
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 /* XXX what does this check? -chb */
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 /* All tests passed */
219 return 1;
220 }
221
222 /*
223 * Read chip ID from AR_ILOCK in test mode.
224 */
225 int
tcic_chipid(iot,ioh)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 /* clear up IRQs inside tcic. XXX -chb */
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 * Indicate whether the driver can handle the chip.
247 */
248 int
tcic_chipid_known(id)249 tcic_chipid_known(id)
250 int id;
251 {
252 /* XXX only know how to handle DB86082 -chb */
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 *
tcic_chipid_to_string(id)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 * Return bitmask of IRQs that the chip can handle.
298 * XXX should be table driven.
299 */
300 int
tcic_validirqs(chipid)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
tcic_attach(sc)320 tcic_attach(sc)
321 struct tcic_softc *sc;
322 {
323 int i, reg;
324
325 /* set more chipset-dependent parameters in the softc. */
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 /* set up global config registers */
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 /* the TCIC has two sockets */
348 /* XXX should i check for actual presence of sockets? -chb */
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 /* establish the interrupt */
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 /* XXX block interrupts? */
366
367 for (i = 0; i < TCIC_NSLOTS; i++) {
368 /* XXX make more clear what happens here -chb */
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 /* XXX explain byte routing issue */
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
tcic_attach_sockets(sc)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
tcic_attach_socket(h)413 tcic_attach_socket(h)
414 struct tcic_handle *h;
415 {
416 struct pcmciabus_attach_args paa;
417
418 /* initialize the rest of the handle */
419
420 h->shutdown = 0;
421 h->memalloc = 0;
422 h->ioalloc = 0;
423 h->ih_irq = 0;
424
425 /* now, config one pcmcia device per socket */
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 /* if there's actually a pcmcia device attached, initialize the slot */
437
438 if (h->pcmcia)
439 tcic_init_socket(h);
440 else
441 h->flags &= ~TCIC_FLAG_SOCKETP;
442 }
443
444 void
tcic_create_event_thread(arg)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
tcic_event_thread(arg)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 /* In case parent is waiting for us to exit. */
509 wakeup(h->sc);
510
511 kthread_exit(0);
512 }
513
514
515 void
tcic_init_socket(h)516 tcic_init_socket(h)
517 struct tcic_handle *h;
518 {
519 int reg;
520
521 /* select this socket's config registers */
522 tcic_sel_sock(h);
523
524 /* set up the socket to interrupt on card detect */
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 /* enable CD irq in R_IENA */
529 reg = tcic_read_2(h, TCIC_R_IENA);
530 tcic_write_2(h, TCIC_R_IENA, reg |= TCIC_IENA_CDCHG);
531
532 /* if there's a card there, then attach it. also save sstat */
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
tcic_submatch(parent,match,aux)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 /* PCMCIABUSCF_CONTROLLER */] !=
552 -1 /* PCMCIABUSCF_CONTROLLER_DEFAULT */ &&
553 cf->cf_loc[0 /* PCMCIABUSCF_CONTROLLER */] != 0)
554 return 0;
555 if (cf->cf_loc[1 /* PCMCIABUSCF_SOCKET */] !=
556 -1 /* PCMCIABUSCF_SOCKET_DEFAULT */ &&
557 cf->cf_loc[1 /* PCMCIABUSCF_SOCKET */] != 0)
558 return 0;
559
560 break;
561 case 1:
562 if (cf->cf_loc[0 /* PCMCIABUSCF_CONTROLLER */] !=
563 -1 /* PCMCIABUSCF_CONTROLLER_DEFAULT */ &&
564 cf->cf_loc[0 /* PCMCIABUSCF_CONTROLLER */] != 0)
565 return 0;
566 if (cf->cf_loc[1 /* PCMCIABUSCF_SOCKET */] !=
567 -1 /* PCMCIABUSCF_SOCKET_DEFAULT */ &&
568 cf->cf_loc[1 /* PCMCIABUSCF_SOCKET */] != 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
tcic_print(arg,pnp)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 /* Only "pcmcia"s can attach to "tcic"s... easy. */
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
tcic_intr(arg)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
tcic_intr_socket(h)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 /* XXX or should the next three be handled in tcic_intr? -chb */
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 /* compute what changed since last interrupt */
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 * XXX This should probably schedule something to happen
662 * after the interrupt handler completes
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 /* Deactivate the card now. */
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 /* shouldn't happen */
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
tcic_queue_event(h,event)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
tcic_attach_card(h)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 /* call the MI attach function */
730
731 pcmcia_card_attach(h->pcmcia);
732
733 h->flags |= TCIC_FLAG_CARDP;
734 }
735
736 void
tcic_detach_card(h,flags)737 tcic_detach_card(h, flags)
738 struct tcic_handle *h;
739 int flags; /* DETACH_* */
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 /* call the MI detach function */
749
750 pcmcia_card_detach(h->pcmcia, flags);
751
752 }
753
754 void
tcic_deactivate_card(h)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 /* call the MI deactivate function */
764 pcmcia_card_deactivate(h->pcmcia);
765
766 tcic_sel_sock(h);
767
768 /* XXX disable card detect resume and configuration reset??? */
769
770 /* power down the socket */
771 tcic_write_1(h, TCIC_R_PWR, 0);
772
773 /* reset the card XXX ? -chb */
774
775 /* turn off irq's for this socket */
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 /* XXX the following routine may need to be rewritten. -chb */
787 int
tcic_chip_mem_alloc(pch,size,pcmhp)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 /* out of sc->memh, allocate as many pages as necessary */
800
801 /*
802 * The TCIC can map memory only in sizes that are
803 * powers of two, aligned at the natural boundary for the size.
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 /* can't allocate that much anyway */
813 if (sizepg > TCIC_MEM_PAGES) /* XXX -chb */
814 return 1;
815
816 mask = (1 << sizepg) - 1;
817
818 addr = 0; /* XXX gcc -Wuninitialized */
819 mhandle = 0; /* XXX gcc -Wuninitialized */
820
821 /* XXX i should be initialised to always lay on boundary. -chb */
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 /* XXX the following routine may need to be rewritten. -chb */
852 void
tcic_chip_mem_free(pch,pcmhp)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
tcic_chip_do_mem_map(h,win)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 * the even windows are used for socket 0,
876 * the odd ones for socket 1.
877 */
878 hwwin = (win << 1) + h->sock;
879
880 /* the WR_MEXT register is MBZ */
881 tcic_write_ind_2(h, TCIC_WR_MEXT_N(hwwin), 0);
882
883 /* set the host base address and window size */
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 /* set the card address and address space */
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 /* set the MCTL register */
902 /* must save WSCNT field in case this is a DB86082 rev 0 */
903 /* XXX why can't I do the following two in one statement? */
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 /* XXX must get speed from CIS somehow. -chb */
909 wscnt = tcic_ns2wscnt(h->mem[win].speed);
910 #else
911 wscnt = tcic_ns2wscnt(tcic_mem_speed); /* 300 is "save" default for CIS memory */
912 #endif
913 if (h->sc->chipid == TCIC_CHIPID_DB86082_1) {
914 /*
915 * this chip has the wait state count in window
916 * register 7 - hwwin.
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 /* XXX needs work */
943 int
tcic_chip_mem_map(pch,kind,card_addr,size,pcmhp,offsetp,windowp)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_addr_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 /* XXX this is pretty gross */
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 * compute the address offset to the pcmcia address space for the
981 * tcic. this is intentionally signed. The masks and shifts below
982 * will cause TRT to happen in the tcic registers. Deal with making
983 * sure the address is aligned, and return the alignment offset.
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 /* XXX we can't use size. -chb */
994 /*
995 * include the offset in the size, and decrement size by one, since
996 * the hw wants start/stop
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
tcic_chip_mem_unmap(pch,window)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
tcic_chip_io_alloc(pch,start,size,align,pcihp)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 * Allocate some arbitrary I/O space.
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 * The TCIC can map I/O space only in sizes that are
1057 * powers of two, aligned at the natural boundary for the size.
1058 */
1059 size2 = tcic_log2((u_int)size);
1060 if ((1 << size2) < size)
1061 size2++;
1062 /* can't allocate that much anyway */
1063 if (size2 > 16) /* XXX 64K -chb */
1064 return 1;
1065 if (align) {
1066 if ((1 << size2) != align)
1067 return 1; /* not suitably aligned */
1068 } else {
1069 align = 1 << size2; /* no alignment given, make it natural */
1070 }
1071 if (start & (align - 1))
1072 return 1; /* not suitably aligned */
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
tcic_chip_io_free(pch,pcihp)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
tcic_chip_do_io_map(h,win)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 * the even windows are used for socket 0,
1132 * the odd ones for socket 1.
1133 */
1134 hwwin = (win << 1) + h->sock;
1135
1136 /* set the WR_BASE register */
1137 /* XXX what if size isn't power of 2? -chb */
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 /* XXX we should do better -chb */
1146 wbase = h->io[win].addr | (1 << (size2 - 1));
1147 }
1148 tcic_write_ind_2(h, TCIC_WR_IBASE_N(hwwin), wbase);
1149
1150 /* set the WR_ICTL register */
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 /* XXX must get speed from CIS somehow. -chb */
1157 wscnt = tcic_ns2wscnt(h->io[win].speed);
1158 #else
1159 wscnt = tcic_ns2wscnt(tcic_io_speed); /* linux uses 0 as default */
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
tcic_chip_io_map(pch,width,offset,size,pcihp,windowp)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 /* XXX Sanity check offset/size. */
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 /* XXX this is pretty gross */
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 /* XXX wtf is this doing here? */
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
tcic_chip_io_unmap(pch,window)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
tcic_chip_socket_enable(pch)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 * power down the socket to reset it.
1262 * put card reset into high-z, put chip outputs to card into high-z
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); /* clear TCIC_SCTRL_ENA */
1271
1272 /* power up the socket */
1273
1274 /* turn on VCC, turn of VPP */
1275 reg = TCIC_PWR_VCC_N(h->sock) | TCIC_PWR_VPP_N(h->sock) | h->sc->pwrena;
1276 if (h->sc->pwrena) /* this is a '84 type chip */
1277 reg |= TCIC_PWR_VCC5V;
1278 tcic_write_1(h, TCIC_R_PWR, reg);
1279 delay(10000);
1280
1281 /* enable reset and wiggle it to reset the card */
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 /* XXX need bus_space_barrier here */
1286 reg |= TCIC_ILOCK_CRESET;
1287 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1288 /* enable card signals */
1289 tcic_write_1(h, TCIC_R_SCTRL, TCIC_SCTRL_ENA);
1290 delay(10); /* wait 10 us */
1291
1292 /* clear the reset flag */
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 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
1298 delay(20000);
1299
1300 /* wait for the chip to finish initializing */
1301 tcic_wait_ready(h);
1302
1303 /* WWW */
1304 /* zero out the address windows */
1305
1306 /* writing to WR_MBASE_N disables the window */
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 /* writing to WR_IBASE_N disables the window */
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 /* set the card type */
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]; /* enable interrupts */
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 /* reinstall all the memory and io mappings */
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
tcic_chip_socket_disable(pch)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 /* disable interrupts */
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 /* disable the output signals */
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 /* power down the socket */
1369 tcic_write_1(h, TCIC_R_PWR, 0);
1370 }
1371
1372 /*
1373 * XXX The following is Linux driver but doesn't match the table
1374 * in the manual.
1375 */
1376 int
tcic_ns2wscnt(ns)1377 tcic_ns2wscnt(ns)
1378 int ns;
1379 {
1380 if (ns < 14) {
1381 return 0;
1382 } else {
1383 return (2*(ns-14))/70; /* XXX assumes 14.31818 MHz clock. */
1384 }
1385 }
1386
1387 int
tcic_log2(val)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 }
1402