FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/tcic2.c
1 /* $NetBSD: tcic2.c,v 1.14 2003/12/28 01:21:37 christos Exp $ */
2
3 /*
4 * Copyright (c) 1998, 1999 Christoph Badura. All rights reserved.
5 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Marc Horowitz.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: tcic2.c,v 1.14 2003/12/28 01:21:37 christos Exp $");
35
36 #undef TCICDEBUG
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/device.h>
41 #include <sys/extent.h>
42 #include <sys/malloc.h>
43 #include <sys/kthread.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 dependent 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 = "";
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_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 tcic_submatch(parent, cf, aux)
535 struct device *parent;
536 struct cfdata *cf;
537 void *aux;
538 {
539
540 struct pcmciabus_attach_args *paa = aux;
541 struct tcic_handle *h = (struct tcic_handle *) paa->pch;
542
543 switch (h->sock) {
544 case 0:
545 if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] !=
546 PCMCIABUSCF_CONTROLLER_DEFAULT &&
547 cf->cf_loc[PCMCIABUSCF_CONTROLLER] != 0)
548 return 0;
549 if (cf->cf_loc[PCMCIABUSCF_SOCKET] !=
550 PCMCIABUSCF_SOCKET_DEFAULT &&
551 cf->cf_loc[PCMCIABUSCF_SOCKET] != 0)
552 return 0;
553
554 break;
555 case 1:
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] != 1)
563 return 0;
564
565 break;
566 default:
567 panic("unknown tcic socket");
568 }
569
570 return (config_match(parent, cf, aux));
571 }
572
573 int
574 tcic_print(arg, pnp)
575 void *arg;
576 const char *pnp;
577 {
578 struct pcmciabus_attach_args *paa = arg;
579 struct tcic_handle *h = (struct tcic_handle *) paa->pch;
580
581 /* Only "pcmcia"s can attach to "tcic"s... easy. */
582 if (pnp)
583 aprint_normal("pcmcia at %s", pnp);
584
585 switch (h->sock) {
586 case 0:
587 aprint_normal(" socket 0");
588 break;
589 case 1:
590 aprint_normal(" socket 1");
591 break;
592 default:
593 panic("unknown tcic socket");
594 }
595 return (UNCONF);
596 }
597
598 int
599 tcic_intr(arg)
600 void *arg;
601 {
602 struct tcic_softc *sc = arg;
603 int i, ret = 0;
604
605 DPRINTF(("%s: intr\n", sc->dev.dv_xname));
606
607 for (i = 0; i < TCIC_NSLOTS; i++)
608 if (sc->handle[i].flags & TCIC_FLAG_SOCKETP)
609 ret += tcic_intr_socket(&sc->handle[i]);
610
611 return (ret ? 1 : 0);
612 }
613
614 int
615 tcic_intr_socket(h)
616 struct tcic_handle *h;
617 {
618 int icsr, rv;
619
620 rv = 0;
621 tcic_sel_sock(h);
622 icsr = tcic_read_1(h, TCIC_R_ICSR);
623
624 DPRINTF(("%s: %d icsr: 0x%02x \n", h->sc->dev.dv_xname, h->sock, icsr));
625
626 /* XXX or should the next three be handled in tcic_intr? -chb */
627 if (icsr & TCIC_ICSR_PROGTIME) {
628 DPRINTF(("%s: %02x PROGTIME\n", h->sc->dev.dv_xname, h->sock));
629 rv = 1;
630 }
631 if (icsr & TCIC_ICSR_ILOCK) {
632 DPRINTF(("%s: %02x ILOCK\n", h->sc->dev.dv_xname, h->sock));
633 rv = 1;
634 }
635 if (icsr & TCIC_ICSR_ERR) {
636 DPRINTF(("%s: %02x ERR\n", h->sc->dev.dv_xname, h->sock));
637 rv = 1;
638 }
639 if (icsr & TCIC_ICSR_CDCHG) {
640 int sstat, delta;
641
642 /* compute what changed since last interrupt */
643 sstat = tcic_read_aux_1(h->sc->iot, h->sc->ioh,
644 TCIC_AR_WCTL, TCIC_R_WCTL_XCSR) & TCIC_XCSR_STAT_MASK;
645 delta = h->sstat ^ sstat;
646 h->sstat = sstat;
647
648 if (delta)
649 rv = 1;
650
651 DPRINTF(("%s: %02x CDCHG %x\n", h->sc->dev.dv_xname, h->sock,
652 delta));
653
654 /*
655 * XXX This should probably schedule something to happen
656 * after the interrupt handler completes
657 */
658
659 if (delta & TCIC_SSTAT_CD) {
660 if (sstat & TCIC_SSTAT_CD) {
661 if (!(h->flags & TCIC_FLAG_CARDP)) {
662 DPRINTF(("%s: enqueing INSERTION event\n",
663 h->sc->dev.dv_xname));
664 tcic_queue_event(h, TCIC_EVENT_INSERTION);
665 }
666 } else {
667 if (h->flags & TCIC_FLAG_CARDP) {
668 /* Deactivate the card now. */
669 DPRINTF(("%s: deactivating card\n",
670 h->sc->dev.dv_xname));
671 tcic_deactivate_card(h);
672
673 DPRINTF(("%s: enqueing REMOVAL event\n",
674 h->sc->dev.dv_xname));
675 tcic_queue_event(h, TCIC_EVENT_REMOVAL);
676 }
677 }
678 }
679 if (delta & TCIC_SSTAT_RDY) {
680 DPRINTF(("%s: %02x READY\n", h->sc->dev.dv_xname, h->sock));
681 /* shouldn't happen */
682 }
683 if (delta & TCIC_SSTAT_LBAT1) {
684 DPRINTF(("%s: %02x LBAT1\n", h->sc->dev.dv_xname, h->sock));
685 }
686 if (delta & TCIC_SSTAT_LBAT2) {
687 DPRINTF(("%s: %02x LBAT2\n", h->sc->dev.dv_xname, h->sock));
688 }
689 if (delta & TCIC_SSTAT_WP) {
690 DPRINTF(("%s: %02x WP\n", h->sc->dev.dv_xname, h->sock));
691 }
692 }
693 return rv;
694 }
695
696 void
697 tcic_queue_event(h, event)
698 struct tcic_handle *h;
699 int event;
700 {
701 struct tcic_event *pe;
702 int s;
703
704 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
705 if (pe == NULL)
706 panic("tcic_queue_event: can't allocate event");
707
708 pe->pe_type = event;
709 s = splhigh();
710 SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q);
711 splx(s);
712 wakeup(&h->events);
713 }
714 void
715 tcic_attach_card(h)
716 struct tcic_handle *h;
717 {
718 DPRINTF(("tcic_attach_card\n"));
719
720 if (h->flags & TCIC_FLAG_CARDP)
721 panic("tcic_attach_card: already attached");
722
723 /* call the MI attach function */
724
725 pcmcia_card_attach(h->pcmcia);
726
727 h->flags |= TCIC_FLAG_CARDP;
728 }
729
730 void
731 tcic_detach_card(h, flags)
732 struct tcic_handle *h;
733 int flags; /* DETACH_* */
734 {
735 DPRINTF(("tcic_detach_card\n"));
736
737 if (!(h->flags & TCIC_FLAG_CARDP))
738 panic("tcic_detach_card: already detached");
739
740 h->flags &= ~TCIC_FLAG_CARDP;
741
742 /* call the MI detach function */
743
744 pcmcia_card_detach(h->pcmcia, flags);
745
746 }
747
748 void
749 tcic_deactivate_card(h)
750 struct tcic_handle *h;
751 {
752 int val, reg;
753
754 if (!(h->flags & TCIC_FLAG_CARDP))
755 panic("tcic_deactivate_card: already detached");
756
757 /* call the MI deactivate function */
758 pcmcia_card_deactivate(h->pcmcia);
759
760 tcic_sel_sock(h);
761
762 /* XXX disable card detect resume and configuration reset??? */
763
764 /* power down the socket */
765 tcic_write_1(h, TCIC_R_PWR, 0);
766
767 /* reset the card XXX ? -chb */
768
769 /* turn off irq's for this socket */
770 reg = TCIC_IR_SCF1_N(h->sock);
771 val = tcic_read_ind_2(h, reg);
772 tcic_write_ind_2(h, reg, (val & ~TCIC_SCF1_IRQ_MASK)|TCIC_SCF1_IRQOFF);
773 reg = TCIC_IR_SCF2_N(h->sock);
774 val = tcic_read_ind_2(h, reg);
775 tcic_write_ind_2(h, reg,
776 (val | (TCIC_SCF2_MLBAT1|TCIC_SCF2_MLBAT2|TCIC_SCF2_MRDY
777 |TCIC_SCF2_MWP|TCIC_SCF2_MCD)));
778 }
779
780 /* XXX the following routine may need to be rewritten. -chb */
781 int
782 tcic_chip_mem_alloc(pch, size, pcmhp)
783 pcmcia_chipset_handle_t pch;
784 bus_size_t size;
785 struct pcmcia_mem_handle *pcmhp;
786 {
787 struct tcic_handle *h = (struct tcic_handle *) pch;
788 bus_space_handle_t memh;
789 bus_addr_t addr;
790 bus_size_t sizepg;
791 int i, mask, mhandle;
792
793 /* out of sc->memh, allocate as many pages as necessary */
794
795 /*
796 * The TCIC can map memory only in sizes that are
797 * powers of two, aligned at the natural boundary for the size.
798 */
799 i = tcic_log2((u_int)size);
800 if ((1<<i) < size)
801 i++;
802 sizepg = max(i, TCIC_MEM_SHIFT) - (TCIC_MEM_SHIFT-1);
803
804 DPRINTF(("tcic_chip_mem_alloc: size %ld sizepg %ld\n", size, sizepg));
805
806 /* can't allocate that much anyway */
807 if (sizepg > TCIC_MEM_PAGES) /* XXX -chb */
808 return 1;
809
810 mask = (1 << sizepg) - 1;
811
812 addr = 0; /* XXX gcc -Wuninitialized */
813 mhandle = 0; /* XXX gcc -Wuninitialized */
814
815 /* XXX i should be initialised to always lay on boundary. -chb */
816 for (i = 0; i < (TCIC_MEM_PAGES + 1 - sizepg); i += sizepg) {
817 if ((h->sc->subregionmask & (mask << i)) == (mask << i)) {
818 if (bus_space_subregion(h->sc->memt, h->sc->memh,
819 i * TCIC_MEM_PAGESIZE,
820 sizepg * TCIC_MEM_PAGESIZE, &memh))
821 return (1);
822 mhandle = mask << i;
823 addr = h->sc->membase + (i * TCIC_MEM_PAGESIZE);
824 h->sc->subregionmask &= ~(mhandle);
825 break;
826 }
827 }
828
829 if (i == (TCIC_MEM_PAGES + 1 - sizepg))
830 return (1);
831
832 DPRINTF(("tcic_chip_mem_alloc bus addr 0x%lx+0x%lx\n", (u_long) addr,
833 (u_long) size));
834
835 pcmhp->memt = h->sc->memt;
836 pcmhp->memh = memh;
837 pcmhp->addr = addr;
838 pcmhp->size = size;
839 pcmhp->mhandle = mhandle;
840 pcmhp->realsize = sizepg * TCIC_MEM_PAGESIZE;
841
842 return (0);
843 }
844
845 /* XXX the following routine may need to be rewritten. -chb */
846 void
847 tcic_chip_mem_free(pch, pcmhp)
848 pcmcia_chipset_handle_t pch;
849 struct pcmcia_mem_handle *pcmhp;
850 {
851 struct tcic_handle *h = (struct tcic_handle *) pch;
852
853 h->sc->subregionmask |= pcmhp->mhandle;
854 }
855
856 void
857 tcic_chip_do_mem_map(h, win)
858 struct tcic_handle *h;
859 int win;
860 {
861 int reg, hwwin, wscnt;
862
863 int kind = h->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
864 int mem8 = (h->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8;
865 DPRINTF(("tcic_chip_do_mem_map window %d: 0x%lx+0x%lx 0x%lx\n",
866 win, (u_long)h->mem[win].addr, (u_long)h->mem[win].size,
867 (u_long)h->mem[win].offset));
868 /*
869 * the even windows are used for socket 0,
870 * the odd ones for socket 1.
871 */
872 hwwin = (win << 1) + h->sock;
873
874 /* the WR_MEXT register is MBZ */
875 tcic_write_ind_2(h, TCIC_WR_MEXT_N(hwwin), 0);
876
877 /* set the host base address and window size */
878 if (h->mem[win].size2 <= 1) {
879 reg = ((h->mem[win].addr >> TCIC_MEM_SHIFT) &
880 TCIC_MBASE_ADDR_MASK) | TCIC_MBASE_4K;
881 } else {
882 reg = ((h->mem[win].addr >> TCIC_MEM_SHIFT) &
883 TCIC_MBASE_ADDR_MASK) | (h->mem[win].size2 >> 1);
884 }
885 tcic_write_ind_2(h, TCIC_WR_MBASE_N(hwwin), reg);
886
887 /* set the card address and address space */
888 reg = 0;
889 reg = ((h->mem[win].offset >> TCIC_MEM_SHIFT) & TCIC_MMAP_ADDR_MASK);
890 reg |= (kind == PCMCIA_MEM_ATTR) ? TCIC_MMAP_ATTR : 0;
891 DPRINTF(("tcic_chip_do_map_mem window %d(%d) mmap 0x%04x\n",
892 win, hwwin, reg));
893 tcic_write_ind_2(h, TCIC_WR_MMAP_N(hwwin), reg);
894
895 /* set the MCTL register */
896 /* must save WSCNT field in case this is a DB86082 rev 0 */
897 /* XXX why can't I do the following two in one statement? */
898 reg = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin)) & TCIC_MCTL_WSCNT_MASK;
899 reg |= TCIC_MCTL_ENA|TCIC_MCTL_QUIET;
900 reg |= mem8 ? TCIC_MCTL_B8 : 0;
901 reg |= (h->sock << TCIC_MCTL_SS_SHIFT) & TCIC_MCTL_SS_MASK;
902 #ifdef notyet /* XXX must get speed from CIS somehow. -chb */
903 wscnt = tcic_ns2wscnt(h->mem[win].speed);
904 #else
905 wscnt = tcic_ns2wscnt(tcic_mem_speed); /* 300 is "save" default for CIS memory */
906 #endif
907 if (h->sc->chipid == TCIC_CHIPID_DB86082_1) {
908 /*
909 * this chip has the wait state count in window
910 * register 7 - hwwin.
911 */
912 int reg2;
913 reg2 = tcic_read_ind_2(h, TCIC_WR_MCTL_N(7-hwwin));
914 reg2 &= ~TCIC_MCTL_WSCNT_MASK;
915 reg2 |= wscnt & TCIC_MCTL_WSCNT_MASK;
916 tcic_write_ind_2(h, TCIC_WR_MCTL_N(7-hwwin), reg2);
917 } else {
918 reg |= wscnt & TCIC_MCTL_WSCNT_MASK;
919 }
920 tcic_write_ind_2(h, TCIC_WR_MCTL_N(hwwin), reg);
921
922 #ifdef TCICDEBUG
923 {
924 int r1, r2, r3;
925
926 r1 = tcic_read_ind_2(h, TCIC_WR_MBASE_N(hwwin));
927 r2 = tcic_read_ind_2(h, TCIC_WR_MMAP_N(hwwin));
928 r3 = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin));
929
930 DPRINTF(("tcic_chip_do_mem_map window %d(%d): %04x %04x %04x\n",
931 win, hwwin, r1, r2, r3));
932 }
933 #endif
934 }
935
936 /* XXX needs work */
937 int
938 tcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
939 pcmcia_chipset_handle_t pch;
940 int kind;
941 bus_addr_t card_addr;
942 bus_size_t size;
943 struct pcmcia_mem_handle *pcmhp;
944 bus_size_t *offsetp;
945 int *windowp;
946 {
947 struct tcic_handle *h = (struct tcic_handle *) pch;
948 bus_addr_t busaddr;
949 long card_offset;
950 int i, win;
951
952 win = -1;
953 for (i = 0; i < h->memwins; i++) {
954 if ((h->memalloc & (1 << i)) == 0) {
955 win = i;
956 h->memalloc |= (1 << i);
957 break;
958 }
959 }
960
961 if (win == -1)
962 return (1);
963
964 *windowp = win;
965
966 /* XXX this is pretty gross */
967
968 if (h->sc->memt != pcmhp->memt)
969 panic("tcic_chip_mem_map memt is bogus");
970
971 busaddr = pcmhp->addr;
972
973 /*
974 * compute the address offset to the pcmcia address space for the
975 * tcic. this is intentionally signed. The masks and shifts below
976 * will cause TRT to happen in the tcic registers. Deal with making
977 * sure the address is aligned, and return the alignment offset.
978 */
979
980 *offsetp = card_addr % TCIC_MEM_ALIGN;
981 card_addr -= *offsetp;
982
983 DPRINTF(("tcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr "
984 "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
985 (u_long) card_addr));
986
987 /* XXX we can't use size. -chb */
988 /*
989 * include the offset in the size, and decrement size by one, since
990 * the hw wants start/stop
991 */
992 size += *offsetp - 1;
993
994 card_offset = (((long) card_addr) - ((long) busaddr));
995
996 DPRINTF(("tcic_chip_mem_map window %d card_offset 0x%lx\n",
997 win, (u_long)card_offset));
998
999 h->mem[win].addr = busaddr;
1000 h->mem[win].size = size;
1001 h->mem[win].size2 = tcic_log2((u_int)pcmhp->realsize) - TCIC_MEM_SHIFT;
1002 h->mem[win].offset = card_offset;
1003 h->mem[win].kind = kind;
1004
1005 tcic_chip_do_mem_map(h, win);
1006
1007 return (0);
1008 }
1009
1010 void
1011 tcic_chip_mem_unmap(pch, window)
1012 pcmcia_chipset_handle_t pch;
1013 int window;
1014 {
1015 struct tcic_handle *h = (struct tcic_handle *) pch;
1016 int reg, hwwin;
1017
1018 if (window >= h->memwins)
1019 panic("tcic_chip_mem_unmap: window out of range");
1020
1021 hwwin = (window << 1) + h->sock;
1022 reg = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin));
1023 reg &= ~TCIC_MCTL_ENA;
1024 tcic_write_ind_2(h, TCIC_WR_MCTL_N(hwwin), reg);
1025
1026 h->memalloc &= ~(1 << window);
1027 }
1028
1029 int
1030 tcic_chip_io_alloc(pch, start, size, align, pcihp)
1031 pcmcia_chipset_handle_t pch;
1032 bus_addr_t start;
1033 bus_size_t size;
1034 bus_size_t align;
1035 struct pcmcia_io_handle *pcihp;
1036 {
1037 struct tcic_handle *h = (struct tcic_handle *) pch;
1038 bus_space_tag_t iot;
1039 bus_space_handle_t ioh;
1040 bus_addr_t ioaddr;
1041 int size2, flags = 0;
1042
1043 /*
1044 * Allocate some arbitrary I/O space.
1045 */
1046
1047 DPRINTF(("tcic_chip_io_alloc req 0x%lx %ld %ld\n",
1048 (u_long) start, (u_long) size, (u_long) align));
1049 /*
1050 * The TCIC can map I/O space only in sizes that are
1051 * powers of two, aligned at the natural boundary for the size.
1052 */
1053 size2 = tcic_log2((u_int)size);
1054 if ((1 << size2) < size)
1055 size2++;
1056 /* can't allocate that much anyway */
1057 if (size2 > 16) /* XXX 64K -chb */
1058 return 1;
1059 if (align) {
1060 if ((1 << size2) != align)
1061 return 1; /* not suitably aligned */
1062 } else {
1063 align = 1 << size2; /* no alignment given, make it natural */
1064 }
1065 if (start & (align - 1))
1066 return 1; /* not suitably aligned */
1067
1068 iot = h->sc->iot;
1069
1070 if (start) {
1071 ioaddr = start;
1072 if (bus_space_map(iot, start, size, 0, &ioh))
1073 return (1);
1074 DPRINTF(("tcic_chip_io_alloc map port %lx+%lx\n",
1075 (u_long) ioaddr, (u_long) size));
1076 } else {
1077 flags |= PCMCIA_IO_ALLOCATED;
1078 if (bus_space_alloc(iot, h->sc->iobase,
1079 h->sc->iobase + h->sc->iosize, size, align, 0, 0,
1080 &ioaddr, &ioh))
1081 return (1);
1082 DPRINTF(("tcic_chip_io_alloc alloc port %lx+%lx\n",
1083 (u_long) ioaddr, (u_long) size));
1084 }
1085
1086 pcihp->iot = iot;
1087 pcihp->ioh = ioh;
1088 pcihp->addr = ioaddr;
1089 pcihp->size = size;
1090 pcihp->flags = flags;
1091
1092 return (0);
1093 }
1094
1095 void
1096 tcic_chip_io_free(pch, pcihp)
1097 pcmcia_chipset_handle_t pch;
1098 struct pcmcia_io_handle *pcihp;
1099 {
1100 bus_space_tag_t iot = pcihp->iot;
1101 bus_space_handle_t ioh = pcihp->ioh;
1102 bus_size_t size = pcihp->size;
1103
1104 if (pcihp->flags & PCMCIA_IO_ALLOCATED)
1105 bus_space_free(iot, ioh, size);
1106 else
1107 bus_space_unmap(iot, ioh, size);
1108 }
1109
1110 static int tcic_iowidth_map[] =
1111 { TCIC_ICTL_AUTOSZ, TCIC_ICTL_B8, TCIC_ICTL_B16 };
1112
1113 void
1114 tcic_chip_do_io_map(h, win)
1115 struct tcic_handle *h;
1116 int win;
1117 {
1118 int reg, size2, iotiny, wbase, hwwin, wscnt;
1119
1120 DPRINTF(("tcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
1121 win, (long) h->io[win].addr, (long) h->io[win].size,
1122 h->io[win].width * 8));
1123
1124 /*
1125 * the even windows are used for socket 0,
1126 * the odd ones for socket 1.
1127 */
1128 hwwin = (win << 1) + h->sock;
1129
1130 /* set the WR_BASE register */
1131 /* XXX what if size isn't power of 2? -chb */
1132 size2 = tcic_log2((u_int)h->io[win].size);
1133 DPRINTF(("tcic_chip_do_io_map win %d size2 %d\n", win, size2));
1134 if (size2 < 1) {
1135 iotiny = TCIC_ICTL_TINY;
1136 wbase = h->io[win].addr;
1137 } else {
1138 iotiny = 0;
1139 /* XXX we should do better -chb */
1140 wbase = h->io[win].addr | (1 << (size2 - 1));
1141 }
1142 tcic_write_ind_2(h, TCIC_WR_IBASE_N(hwwin), wbase);
1143
1144 /* set the WR_ICTL register */
1145 reg = TCIC_ICTL_ENA | TCIC_ICTL_QUIET;
1146 reg |= (h->sock << TCIC_ICTL_SS_SHIFT) & TCIC_ICTL_SS_MASK;
1147 reg |= iotiny | tcic_iowidth_map[h->io[win].width];
1148 if (h->sc->chipid != TCIC_CHIPID_DB86082_1)
1149 reg |= TCIC_ICTL_PASS16;
1150 #ifdef notyet /* XXX must get speed from CIS somehow. -chb */
1151 wscnt = tcic_ns2wscnt(h->io[win].speed);
1152 #else
1153 wscnt = tcic_ns2wscnt(tcic_io_speed); /* linux uses 0 as default */
1154 #endif
1155 reg |= wscnt & TCIC_ICTL_WSCNT_MASK;
1156 tcic_write_ind_2(h, TCIC_WR_ICTL_N(hwwin), reg);
1157
1158 #ifdef TCICDEBUG
1159 {
1160 int r1, r2;
1161
1162 r1 = tcic_read_ind_2(h, TCIC_WR_IBASE_N(hwwin));
1163 r2 = tcic_read_ind_2(h, TCIC_WR_ICTL_N(hwwin));
1164
1165 DPRINTF(("tcic_chip_do_io_map window %d(%d): %04x %04x\n",
1166 win, hwwin, r1, r2));
1167 }
1168 #endif
1169 }
1170
1171 int
1172 tcic_chip_io_map(pch, width, offset, size, pcihp, windowp)
1173 pcmcia_chipset_handle_t pch;
1174 int width;
1175 bus_addr_t offset;
1176 bus_size_t size;
1177 struct pcmcia_io_handle *pcihp;
1178 int *windowp;
1179 {
1180 struct tcic_handle *h = (struct tcic_handle *) pch;
1181 bus_addr_t ioaddr = pcihp->addr + offset;
1182 int i, win;
1183 #ifdef TCICDEBUG
1184 static char *width_names[] = { "auto", "io8", "io16" };
1185 #endif
1186
1187 /* XXX Sanity check offset/size. */
1188
1189 win = -1;
1190 for (i = 0; i < TCIC_IO_WINS; i++) {
1191 if ((h->ioalloc & (1 << i)) == 0) {
1192 win = i;
1193 h->ioalloc |= (1 << i);
1194 break;
1195 }
1196 }
1197
1198 if (win == -1)
1199 return (1);
1200
1201 *windowp = win;
1202
1203 /* XXX this is pretty gross */
1204
1205 if (h->sc->iot != pcihp->iot)
1206 panic("tcic_chip_io_map iot is bogus");
1207
1208 DPRINTF(("tcic_chip_io_map window %d %s port %lx+%lx\n",
1209 win, width_names[width], (u_long) ioaddr, (u_long) size));
1210
1211 /* XXX wtf is this doing here? */
1212
1213 printf("%s: port 0x%lx", h->sc->dev.dv_xname, (u_long) ioaddr);
1214 if (size > 1)
1215 printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
1216 printf("\n");
1217
1218 h->io[win].addr = ioaddr;
1219 h->io[win].size = size;
1220 h->io[win].width = width;
1221
1222 tcic_chip_do_io_map(h, win);
1223
1224 return (0);
1225 }
1226
1227 void
1228 tcic_chip_io_unmap(pch, window)
1229 pcmcia_chipset_handle_t pch;
1230 int window;
1231 {
1232 struct tcic_handle *h = (struct tcic_handle *) pch;
1233 int reg, hwwin;
1234
1235 if (window >= TCIC_IO_WINS)
1236 panic("tcic_chip_io_unmap: window out of range");
1237
1238 hwwin = (window << 1) + h->sock;
1239 reg = tcic_read_ind_2(h, TCIC_WR_ICTL_N(hwwin));
1240 reg &= ~TCIC_ICTL_ENA;
1241 tcic_write_ind_2(h, TCIC_WR_ICTL_N(hwwin), reg);
1242
1243 h->ioalloc &= ~(1 << window);
1244 }
1245
1246 void
1247 tcic_chip_socket_enable(pch)
1248 pcmcia_chipset_handle_t pch;
1249 {
1250 struct tcic_handle *h = (struct tcic_handle *) pch;
1251 int cardtype, reg, win;
1252
1253 tcic_sel_sock(h);
1254
1255 /*
1256 * power down the socket to reset it.
1257 * put card reset into high-z, put chip outputs to card into high-z
1258 */
1259
1260 tcic_write_1(h, TCIC_R_PWR, 0);
1261 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK);
1262 reg |= TCIC_ILOCK_CWAIT;
1263 reg &= ~(TCIC_ILOCK_CRESET|TCIC_ILOCK_CRESENA);
1264 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1265 tcic_write_1(h, TCIC_R_SCTRL, 0); /* clear TCIC_SCTRL_ENA */
1266
1267 /* power up the socket */
1268
1269 /* turn on VCC, turn of VPP */
1270 reg = TCIC_PWR_VCC_N(h->sock) | TCIC_PWR_VPP_N(h->sock) | h->sc->pwrena;
1271 if (h->sc->pwrena) /* this is a '84 type chip */
1272 reg |= TCIC_PWR_VCC5V;
1273 tcic_write_1(h, TCIC_R_PWR, reg);
1274 delay(10000);
1275
1276 /* enable reset and wiggle it to reset the card */
1277 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK);
1278 reg |= TCIC_ILOCK_CRESENA;
1279 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1280 /* XXX need bus_space_barrier here */
1281 reg |= TCIC_ILOCK_CRESET;
1282 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1283 /* enable card signals */
1284 tcic_write_1(h, TCIC_R_SCTRL, TCIC_SCTRL_ENA);
1285 delay(10); /* wait 10 us */
1286
1287 /* clear the reset flag */
1288 reg = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK);
1289 reg &= ~(TCIC_ILOCK_CRESET);
1290 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, reg);
1291
1292 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */
1293 delay(20000);
1294
1295 /* wait for the chip to finish initializing */
1296 tcic_wait_ready(h);
1297
1298 /* WWW */
1299 /* zero out the address windows */
1300
1301 /* writing to WR_MBASE_N disables the window */
1302 for (win = 0; win < h->memwins; win++) {
1303 tcic_write_ind_2(h, TCIC_WR_MBASE_N((win<<1)+h->sock), 0);
1304 }
1305 /* writing to WR_IBASE_N disables the window */
1306 for (win = 0; win < TCIC_IO_WINS; win++) {
1307 tcic_write_ind_2(h, TCIC_WR_IBASE_N((win<<1)+h->sock), 0);
1308 }
1309
1310 /* set the card type */
1311
1312 cardtype = pcmcia_card_gettype(h->pcmcia);
1313
1314 #if 0
1315 reg = tcic_read_ind_2(h, TCIC_IR_SCF1_N(h->sock));
1316 reg &= ~TCIC_SCF1_IRQ_MASK;
1317 #else
1318 reg = 0;
1319 #endif
1320 reg |= ((cardtype == PCMCIA_IFTYPE_IO) ?
1321 TCIC_SCF1_IOSTS : 0);
1322 reg |= tcic_irqmap[h->ih_irq]; /* enable interrupts */
1323 reg &= ~TCIC_SCF1_IRQOD;
1324 tcic_write_ind_2(h, TCIC_IR_SCF1_N(h->sock), reg);
1325
1326 DPRINTF(("%s: tcic_chip_socket_enable %d cardtype %s 0x%02x\n",
1327 h->sc->dev.dv_xname, h->sock,
1328 ((cardtype == PCMCIA_IFTYPE_IO) ? "io" : "mem"), reg));
1329
1330 /* reinstall all the memory and io mappings */
1331
1332 for (win = 0; win < h->memwins; win++)
1333 if (h->memalloc & (1 << win))
1334 tcic_chip_do_mem_map(h, win);
1335
1336 for (win = 0; win < TCIC_IO_WINS; win++)
1337 if (h->ioalloc & (1 << win))
1338 tcic_chip_do_io_map(h, win);
1339 }
1340
1341 void
1342 tcic_chip_socket_disable(pch)
1343 pcmcia_chipset_handle_t pch;
1344 {
1345 struct tcic_handle *h = (struct tcic_handle *) pch;
1346 int val;
1347
1348 DPRINTF(("tcic_chip_socket_disable\n"));
1349
1350 tcic_sel_sock(h);
1351
1352 /* disable interrupts */
1353 val = tcic_read_ind_2(h, TCIC_IR_SCF1_N(h->sock));
1354 val &= TCIC_SCF1_IRQ_MASK;
1355 tcic_write_ind_2(h, TCIC_IR_SCF1_N(h->sock), val);
1356
1357 /* disable the output signals */
1358 tcic_write_1(h, TCIC_R_SCTRL, 0);
1359 val = tcic_read_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK);
1360 val &= ~TCIC_ILOCK_CRESENA;
1361 tcic_write_aux_2(h->sc->iot, h->sc->ioh, TCIC_AR_ILOCK, val);
1362
1363 /* power down the socket */
1364 tcic_write_1(h, TCIC_R_PWR, 0);
1365 }
1366
1367 /*
1368 * XXX The following is Linux driver but doesn't match the table
1369 * in the manual.
1370 */
1371 int
1372 tcic_ns2wscnt(ns)
1373 int ns;
1374 {
1375 if (ns < 14) {
1376 return 0;
1377 } else {
1378 return (2*(ns-14))/70; /* XXX assumes 14.31818 MHz clock. */
1379 }
1380 }
1381
1382 int
1383 tcic_log2(val)
1384 u_int val;
1385 {
1386 int i, l2;
1387
1388 l2 = i = 0;
1389 while (val) {
1390 if (val & 1)
1391 l2 = i;
1392 i++;
1393 val >>= 1;
1394 }
1395 return l2;
1396 }
Cache object: 9e31c20b4307ba4cb13a17a9513cf858
|