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