root/dev/ic/tcic2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tcic_check_reserved_bits
  2. tcic_chipid
  3. tcic_chipid_known
  4. tcic_chipid_to_string
  5. tcic_validirqs
  6. tcic_attach
  7. tcic_attach_sockets
  8. tcic_attach_socket
  9. tcic_create_event_thread
  10. tcic_event_thread
  11. tcic_init_socket
  12. tcic_submatch
  13. tcic_print
  14. tcic_intr
  15. tcic_intr_socket
  16. tcic_queue_event
  17. tcic_attach_card
  18. tcic_detach_card
  19. tcic_deactivate_card
  20. tcic_chip_mem_alloc
  21. tcic_chip_mem_free
  22. tcic_chip_do_mem_map
  23. tcic_chip_mem_map
  24. tcic_chip_mem_unmap
  25. tcic_chip_io_alloc
  26. tcic_chip_io_free
  27. tcic_chip_do_io_map
  28. tcic_chip_io_map
  29. tcic_chip_io_unmap
  30. tcic_chip_socket_enable
  31. tcic_chip_socket_disable
  32. tcic_ns2wscnt
  33. tcic_log2

    1 /*      $OpenBSD: tcic2.c,v 1.7 2005/11/23 11:39:37 mickey 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
  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 reserved. */
  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
  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
  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 *
  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
  301 tcic_validirqs(chipid)
  302         int chipid;
  303 {
  304         switch (chipid) {
  305         case TCIC_CHIPID_DB86082_1:
  306         case TCIC_CHIPID_DB86082A:
  307         case TCIC_CHIPID_DB86082B_ES:
  308         case TCIC_CHIPID_DB86082B:
  309         case TCIC_CHIPID_DB86084_1:
  310         case TCIC_CHIPID_DB86084A:
  311         case TCIC_CHIPID_DB86184_1:
  312         case TCIC_CHIPID_DB86072_1_ES:
  313         case TCIC_CHIPID_DB86072_1:
  314                 return tcic_valid_irqs;
  315         }
  316         return 0;
  317 }
  318 
  319 void
  320 tcic_attach(sc)
  321         struct tcic_softc *sc;
  322 {
  323         int i, reg;
  324 
  325         /* 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
  402 tcic_attach_sockets(sc)
  403         struct tcic_softc *sc;
  404 {
  405         int i;
  406 
  407         for (i = 0; i < TCIC_NSLOTS; i++)
  408                 if (sc->handle[i].flags & TCIC_FLAG_SOCKETP)
  409                         tcic_attach_socket(&sc->handle[i]);
  410 }
  411 
  412 void
  413 tcic_attach_socket(h)
  414         struct tcic_handle *h;
  415 {
  416         struct pcmciabus_attach_args paa;
  417 
  418         /* 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
  445 tcic_create_event_thread(arg)
  446         void *arg;
  447 {
  448         struct tcic_handle *h = arg;
  449         const char *cs;
  450 
  451         switch (h->sock) {
  452         case 0:
  453                 cs = "0";
  454                 break;
  455         case 1:
  456                 cs = "1";
  457                 break;
  458         default:
  459                 panic("tcic_create_event_thread: unknown tcic socket");
  460         }
  461 
  462         if (kthread_create(tcic_event_thread, h, &h->event_thread,
  463             "%s,%s", h->sc->dev.dv_xname, cs)) {
  464                 printf("%s: unable to create event thread for sock 0x%02x\n",
  465                     h->sc->dev.dv_xname, h->sock);
  466                 panic("tcic_create_event_thread");
  467         }
  468 }
  469 
  470 void
  471 tcic_event_thread(arg)
  472         void *arg;
  473 {
  474         struct tcic_handle *h = arg;
  475         struct tcic_event *pe;
  476         int s;
  477 
  478         while (h->shutdown == 0) {
  479                 s = splhigh();
  480                 if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) {
  481                         splx(s);
  482                         (void) tsleep(&h->events, PWAIT, "tcicev", 0);
  483                         continue;
  484                 }
  485                 SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
  486                 splx(s);
  487 
  488                 switch (pe->pe_type) {
  489                 case TCIC_EVENT_INSERTION:
  490                         DPRINTF(("%s: insertion event\n", h->sc->dev.dv_xname));
  491                         tcic_attach_card(h);
  492                         break;
  493 
  494                 case TCIC_EVENT_REMOVAL:
  495                         DPRINTF(("%s: removal event\n", h->sc->dev.dv_xname));
  496                         tcic_detach_card(h, DETACH_FORCE);
  497                         break;
  498 
  499                 default:
  500                         panic("tcic_event_thread: unknown event %d",
  501                             pe->pe_type);
  502                 }
  503                 free(pe, M_TEMP);
  504         }
  505 
  506         h->event_thread = NULL;
  507 
  508         /* In case parent is waiting for us to exit. */
  509         wakeup(h->sc);
  510 
  511         kthread_exit(0);
  512 }
  513 
  514 
  515 void
  516 tcic_init_socket(h)
  517         struct tcic_handle *h;
  518 {
  519         int reg;
  520 
  521         /* 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
  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
  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
  605 tcic_intr(arg)
  606         void *arg;
  607 {
  608         struct tcic_softc *sc = arg;
  609         int i, ret = 0;
  610 
  611         DPRINTF(("%s: intr\n", sc->dev.dv_xname));
  612 
  613         for (i = 0; i < TCIC_NSLOTS; i++)
  614                 if (sc->handle[i].flags & TCIC_FLAG_SOCKETP)
  615                         ret += tcic_intr_socket(&sc->handle[i]);
  616 
  617         return (ret ? 1 : 0);
  618 }
  619 
  620 int
  621 tcic_intr_socket(h)
  622         struct tcic_handle *h;
  623 {
  624         int icsr, rv;
  625 
  626         rv = 0;
  627         tcic_sel_sock(h);
  628         icsr = tcic_read_1(h, TCIC_R_ICSR);
  629 
  630         DPRINTF(("%s: %d icsr: 0x%02x \n", h->sc->dev.dv_xname, h->sock, icsr));
  631 
  632         /* 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
  703 tcic_queue_event(h, event)
  704         struct tcic_handle *h;
  705         int event;
  706 {
  707         struct tcic_event *pe;
  708         int s;
  709 
  710         pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
  711         if (pe == NULL)
  712                 panic("tcic_queue_event: can't allocate event");
  713 
  714         pe->pe_type = event;
  715         s = splhigh();
  716         SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q);
  717         splx(s);
  718         wakeup(&h->events);
  719 }
  720 void
  721 tcic_attach_card(h)
  722         struct tcic_handle *h;
  723 {
  724         DPRINTF(("tcic_attach_card\n"));
  725 
  726         if (h->flags & TCIC_FLAG_CARDP)
  727                 panic("tcic_attach_card: already attached");
  728 
  729         /* call the MI attach function */
  730 
  731         pcmcia_card_attach(h->pcmcia);
  732 
  733         h->flags |= TCIC_FLAG_CARDP;
  734 }
  735 
  736 void
  737 tcic_detach_card(h, flags)
  738         struct tcic_handle *h;
  739         int flags;              /* 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
  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 
  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 
  853 tcic_chip_mem_free(pch, pcmhp)
  854         pcmcia_chipset_handle_t pch;
  855         struct pcmcia_mem_handle *pcmhp;
  856 {
  857         struct tcic_handle *h = (struct tcic_handle *) pch;
  858 
  859         h->sc->subregionmask |= pcmhp->mhandle;
  860 }
  861 
  862 void 
  863 tcic_chip_do_mem_map(h, win)
  864         struct tcic_handle *h;
  865         int win;
  866 {
  867         int reg, hwwin, wscnt;
  868 
  869         int kind = h->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
  870         int mem8 = (h->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8;
  871         DPRINTF(("tcic_chip_do_mem_map window %d: 0x%lx+0x%lx 0x%lx\n",
  872                 win, (u_long)h->mem[win].addr, (u_long)h->mem[win].size,
  873                 (u_long)h->mem[win].offset));
  874         /*
  875          * 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 
  944 tcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
  945         pcmcia_chipset_handle_t pch;
  946         int kind;
  947         bus_addr_t card_addr;
  948         bus_size_t size;
  949         struct pcmcia_mem_handle *pcmhp;
  950         bus_size_t *offsetp;
  951         int *windowp;
  952 {
  953         struct tcic_handle *h = (struct tcic_handle *) pch;
  954         bus_addr_t busaddr;
  955         long card_offset;
  956         int i, win;
  957 
  958         win = -1;
  959         for (i = 0; i < h->memwins; i++) {
  960                 if ((h->memalloc & (1 << i)) == 0) {
  961                         win = i;
  962                         h->memalloc |= (1 << i);
  963                         break;
  964                 }
  965         }
  966 
  967         if (win == -1)
  968                 return (1);
  969 
  970         *windowp = win;
  971 
  972         /* 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 
 1017 tcic_chip_mem_unmap(pch, window)
 1018         pcmcia_chipset_handle_t pch;
 1019         int window;
 1020 {
 1021         struct tcic_handle *h = (struct tcic_handle *) pch;
 1022         int reg, hwwin;
 1023 
 1024         if (window >= h->memwins)
 1025                 panic("tcic_chip_mem_unmap: window out of range");
 1026 
 1027         hwwin = (window << 1) + h->sock;
 1028         reg = tcic_read_ind_2(h, TCIC_WR_MCTL_N(hwwin));
 1029         reg &= ~TCIC_MCTL_ENA;
 1030         tcic_write_ind_2(h, TCIC_WR_MCTL_N(hwwin), reg);
 1031 
 1032         h->memalloc &= ~(1 << window);
 1033 }
 1034 
 1035 int 
 1036 tcic_chip_io_alloc(pch, start, size, align, pcihp)
 1037         pcmcia_chipset_handle_t pch;
 1038         bus_addr_t start;
 1039         bus_size_t size;
 1040         bus_size_t align;
 1041         struct pcmcia_io_handle *pcihp;
 1042 {
 1043         struct tcic_handle *h = (struct tcic_handle *) pch;
 1044         bus_space_tag_t iot;
 1045         bus_space_handle_t ioh;
 1046         bus_addr_t ioaddr;
 1047         int size2, flags = 0;
 1048 
 1049         /*
 1050          * 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 
 1102 tcic_chip_io_free(pch, pcihp)
 1103         pcmcia_chipset_handle_t pch;
 1104         struct pcmcia_io_handle *pcihp;
 1105 {
 1106         bus_space_tag_t iot = pcihp->iot;
 1107         bus_space_handle_t ioh = pcihp->ioh;
 1108         bus_size_t size = pcihp->size;
 1109 
 1110         if (pcihp->flags & PCMCIA_IO_ALLOCATED)
 1111                 bus_space_free(iot, ioh, size);
 1112         else
 1113                 bus_space_unmap(iot, ioh, size);
 1114 }
 1115 
 1116 static int tcic_iowidth_map[] =
 1117     { TCIC_ICTL_AUTOSZ, TCIC_ICTL_B8, TCIC_ICTL_B16 };
 1118 
 1119 void 
 1120 tcic_chip_do_io_map(h, win)
 1121         struct tcic_handle *h;
 1122         int win;
 1123 {
 1124         int reg, size2, iotiny, wbase, hwwin, wscnt;
 1125 
 1126         DPRINTF(("tcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
 1127             win, (long) h->io[win].addr, (long) h->io[win].size,
 1128             h->io[win].width * 8));
 1129 
 1130         /*
 1131          * 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 
 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 
 1233 tcic_chip_io_unmap(pch, window)
 1234         pcmcia_chipset_handle_t pch;
 1235         int window;
 1236 {
 1237         struct tcic_handle *h = (struct tcic_handle *) pch;
 1238         int reg, hwwin;
 1239 
 1240         if (window >= TCIC_IO_WINS)
 1241                 panic("tcic_chip_io_unmap: window out of range");
 1242 
 1243         hwwin = (window << 1) + h->sock;
 1244         reg = tcic_read_ind_2(h, TCIC_WR_ICTL_N(hwwin));
 1245         reg &= ~TCIC_ICTL_ENA;
 1246         tcic_write_ind_2(h, TCIC_WR_ICTL_N(hwwin), reg);
 1247 
 1248         h->ioalloc &= ~(1 << window);
 1249 }
 1250 
 1251 void
 1252 tcic_chip_socket_enable(pch)
 1253         pcmcia_chipset_handle_t pch;
 1254 {
 1255         struct tcic_handle *h = (struct tcic_handle *) pch;
 1256         int cardtype, reg, win;
 1257 
 1258         tcic_sel_sock(h);
 1259 
 1260         /*
 1261          * 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
 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
 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
 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 }

/* [<][>][^][v][top][bottom][index][help] */