1 1.30 thorpej /* $NetBSD: tcic2_isa.c,v 1.30 2022/09/25 17:09:36 thorpej Exp $ */ 2 1.1 bad 3 1.1 bad /* 4 1.1 bad * 5 1.1 bad * Copyright (c) 1998, 1999 Christoph Badura. All rights reserved. 6 1.1 bad * Copyright (c) 1997 Marc Horowitz. All rights reserved. 7 1.1 bad * 8 1.1 bad * Redistribution and use in source and binary forms, with or without 9 1.1 bad * modification, are permitted provided that the following conditions 10 1.1 bad * are met: 11 1.1 bad * 1. Redistributions of source code must retain the above copyright 12 1.1 bad * notice, this list of conditions and the following disclaimer. 13 1.1 bad * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 bad * notice, this list of conditions and the following disclaimer in the 15 1.1 bad * documentation and/or other materials provided with the distribution. 16 1.1 bad * 3. All advertising materials mentioning features or use of this software 17 1.1 bad * must display the following acknowledgement: 18 1.1 bad * This product includes software developed by Marc Horowitz. 19 1.1 bad * 4. The name of the author may not be used to endorse or promote products 20 1.1 bad * derived from this software without specific prior written permission. 21 1.1 bad * 22 1.1 bad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 1.1 bad * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 bad * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 bad * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 1.1 bad * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 1.1 bad * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 1.1 bad * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 1.1 bad * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 1.1 bad * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 1.1 bad * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 bad */ 33 1.1 bad 34 1.4 lukem #include <sys/cdefs.h> 35 1.30 thorpej __KERNEL_RCSID(0, "$NetBSD: tcic2_isa.c,v 1.30 2022/09/25 17:09:36 thorpej Exp $"); 36 1.1 bad 37 1.1 bad #include <sys/param.h> 38 1.1 bad #include <sys/systm.h> 39 1.1 bad #include <sys/device.h> 40 1.1 bad #include <sys/extent.h> 41 1.1 bad 42 1.18 ad #include <sys/bus.h> 43 1.18 ad #include <sys/intr.h> 44 1.1 bad 45 1.1 bad #include <dev/isa/isareg.h> 46 1.1 bad #include <dev/isa/isavar.h> 47 1.1 bad 48 1.1 bad #include <dev/pcmcia/pcmciareg.h> 49 1.1 bad #include <dev/pcmcia/pcmciavar.h> 50 1.1 bad #include <dev/pcmcia/pcmciachip.h> 51 1.1 bad 52 1.1 bad #include <dev/ic/tcic2reg.h> 53 1.1 bad #include <dev/ic/tcic2var.h> 54 1.1 bad 55 1.1 bad /***************************************************************************** 56 1.1 bad * Configurable parameters. 57 1.1 bad *****************************************************************************/ 58 1.1 bad 59 1.1 bad #include "opt_tcic_isa_alloc_iobase.h" 60 1.1 bad #include "opt_tcic_isa_alloc_iosize.h" 61 1.1 bad #include "opt_tcic_isa_intr_alloc_mask.h" 62 1.1 bad 63 1.1 bad /* 64 1.1 bad * Default I/O allocation range. If both are set to non-zero, these 65 1.1 bad * values will be used instead. Otherwise, the code attempts to probe 66 1.1 bad * the bus width. Systems with 10 address bits should use 0x300 and 0xff. 67 1.1 bad * Systems with 12 address bits (most) should use 0x400 and 0xbff. 68 1.1 bad */ 69 1.1 bad 70 1.1 bad #ifndef TCIC_ISA_ALLOC_IOBASE 71 1.1 bad #define TCIC_ISA_ALLOC_IOBASE 0 72 1.1 bad #endif 73 1.1 bad 74 1.1 bad #ifndef TCIC_ISA_ALLOC_IOSIZE 75 1.1 bad #define TCIC_ISA_ALLOC_IOSIZE 0 76 1.1 bad #endif 77 1.1 bad 78 1.1 bad int tcic_isa_alloc_iobase = TCIC_ISA_ALLOC_IOBASE; 79 1.1 bad int tcic_isa_alloc_iosize = TCIC_ISA_ALLOC_IOSIZE; 80 1.1 bad 81 1.1 bad /* 82 1.1 bad * Default IRQ allocation bitmask. This defines the range of allowable 83 1.1 bad * IRQs for PCMCIA slots. Useful if order of probing would screw up other 84 1.1 bad * devices, or if TCIC hardware/cards have trouble with certain interrupt 85 1.1 bad * lines. 86 1.1 bad * 87 1.1 bad * We disable IRQ 10 by default, since some common laptops (namely, the 88 1.1 bad * NEC Versa series) reserve IRQ 10 for the docking station SCSI interface. 89 1.1 bad * 90 1.1 bad * XXX Do we care about this? the Versa doesn't use a tcic. -chb 91 1.1 bad */ 92 1.1 bad 93 1.1 bad #ifndef TCIC_ISA_INTR_ALLOC_MASK 94 1.1 bad #define TCIC_ISA_INTR_ALLOC_MASK 0xffff 95 1.1 bad #endif 96 1.1 bad 97 1.1 bad int tcic_isa_intr_alloc_mask = TCIC_ISA_INTR_ALLOC_MASK; 98 1.1 bad 99 1.1 bad /***************************************************************************** 100 1.1 bad * End of configurable parameters. 101 1.1 bad *****************************************************************************/ 102 1.1 bad 103 1.1 bad #ifdef TCICISADEBUG 104 1.1 bad int tcic_isa_debug = 1; 105 1.1 bad #define DPRINTF(arg) if (tcic_isa_debug) printf arg; 106 1.1 bad #else 107 1.1 bad #define DPRINTF(arg) 108 1.1 bad #endif 109 1.1 bad 110 1.25 cegger int tcic_isa_probe(device_t, cfdata_t, void *); 111 1.25 cegger void tcic_isa_attach(device_t, device_t, void *); 112 1.1 bad 113 1.12 perry void *tcic_isa_chip_intr_establish(pcmcia_chipset_handle_t, 114 1.12 perry struct pcmcia_function *, int, int (*) (void *), void *); 115 1.12 perry void tcic_isa_chip_intr_disestablish(pcmcia_chipset_handle_t, void *); 116 1.1 bad 117 1.26 chs CFATTACH_DECL_NEW(tcic_isa, sizeof(struct tcic_softc), 118 1.9 thorpej tcic_isa_probe, tcic_isa_attach, NULL, NULL); 119 1.1 bad 120 1.21 drochner static const struct pcmcia_chip_functions tcic_isa_functions = { 121 1.1 bad tcic_chip_mem_alloc, 122 1.1 bad tcic_chip_mem_free, 123 1.1 bad tcic_chip_mem_map, 124 1.1 bad tcic_chip_mem_unmap, 125 1.1 bad 126 1.1 bad tcic_chip_io_alloc, 127 1.1 bad tcic_chip_io_free, 128 1.1 bad tcic_chip_io_map, 129 1.1 bad tcic_chip_io_unmap, 130 1.1 bad 131 1.1 bad tcic_isa_chip_intr_establish, 132 1.1 bad tcic_isa_chip_intr_disestablish, 133 1.1 bad 134 1.1 bad tcic_chip_socket_enable, 135 1.1 bad tcic_chip_socket_disable, 136 1.10 mycroft tcic_chip_socket_settype, 137 1.15 christos 138 1.15 christos NULL, /* card_detect */ 139 1.1 bad }; 140 1.1 bad 141 1.1 bad int 142 1.25 cegger tcic_isa_probe(device_t parent, cfdata_t match, void *aux) 143 1.1 bad { 144 1.1 bad struct isa_attach_args *ia = aux; 145 1.1 bad bus_space_tag_t iot = ia->ia_iot; 146 1.1 bad bus_space_handle_t ioh, memh; 147 1.6 thorpej int val, found, msize; 148 1.6 thorpej 149 1.6 thorpej if (ia->ia_nio < 1) 150 1.6 thorpej return (0); 151 1.6 thorpej if (ia->ia_niomem < 1) 152 1.6 thorpej return (0); 153 1.6 thorpej 154 1.6 thorpej if (ISA_DIRECT_CONFIG(ia)) 155 1.6 thorpej return (0); 156 1.1 bad 157 1.1 bad /* Disallow wildcarded i/o address. */ 158 1.11 drochner if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) 159 1.6 thorpej return (0); 160 1.11 drochner if (ia->ia_iomem[0].ir_addr == ISA_UNKNOWN_IOMEM) 161 1.1 bad return (0); 162 1.1 bad 163 1.6 thorpej if (bus_space_map(iot, ia->ia_io[0].ir_addr, TCIC_IOSIZE, 0, &ioh)) 164 1.1 bad return (0); 165 1.1 bad 166 1.11 drochner if (ia->ia_iomem[0].ir_size == ISA_UNKNOWN_IOSIZ) 167 1.6 thorpej msize = TCIC_MEMSIZE; 168 1.6 thorpej else 169 1.6 thorpej msize = ia->ia_iomem[0].ir_size; 170 1.1 bad 171 1.6 thorpej if (bus_space_map(ia->ia_memt, ia->ia_iomem[0].ir_addr, 172 1.6 thorpej msize, 0, &memh)) { 173 1.6 thorpej bus_space_unmap(iot, ioh, TCIC_IOSIZE); 174 1.1 bad return (0); 175 1.6 thorpej } 176 1.1 bad 177 1.19 ad DPRINTF(("tcic probing 0x%03x\n", ia->ia_iomem[0].ir_addr)); 178 1.1 bad found = 0; 179 1.1 bad 180 1.1 bad /* 181 1.1 bad * First, check for the reserved bits to be zero. 182 1.1 bad */ 183 1.1 bad if (tcic_check_reserved_bits(iot, ioh)) { 184 1.1 bad DPRINTF(("tcic: reserved bits checked OK\n")); 185 1.1 bad /* Second, check whether the we know how to handle the chip. */ 186 1.1 bad if ((val = tcic_chipid(iot, ioh))) { 187 1.1 bad DPRINTF(("tcic id: 0x%02x\n", val)); 188 1.1 bad if (tcic_chipid_known(val)) 189 1.1 bad found++; 190 1.1 bad } 191 1.1 bad } 192 1.15 christos else { 193 1.1 bad DPRINTF(("tcic: reserved bits didn't check OK\n")); 194 1.15 christos } 195 1.1 bad 196 1.1 bad bus_space_unmap(iot, ioh, TCIC_IOSIZE); 197 1.6 thorpej bus_space_unmap(ia->ia_memt, memh, msize); 198 1.1 bad 199 1.1 bad if (!found) 200 1.1 bad return (0); 201 1.1 bad 202 1.6 thorpej ia->ia_nio = 1; 203 1.6 thorpej ia->ia_io[0].ir_size = TCIC_IOSIZE; 204 1.6 thorpej 205 1.6 thorpej ia->ia_niomem = 1; 206 1.6 thorpej ia->ia_iomem[0].ir_size = msize; 207 1.6 thorpej 208 1.6 thorpej /* IRQ is special. */ 209 1.6 thorpej 210 1.6 thorpej ia->ia_ndrq = 0; 211 1.1 bad 212 1.1 bad return (1); 213 1.1 bad } 214 1.1 bad 215 1.1 bad void 216 1.25 cegger tcic_isa_attach(device_t parent, device_t self, void *aux) 217 1.1 bad { 218 1.26 chs struct tcic_softc *sc = device_private(self); 219 1.1 bad struct isa_attach_args *ia = aux; 220 1.1 bad isa_chipset_tag_t ic = ia->ia_ic; 221 1.1 bad bus_space_tag_t iot = ia->ia_iot; 222 1.1 bad bus_space_tag_t memt = ia->ia_memt; 223 1.1 bad bus_space_handle_t ioh; 224 1.1 bad bus_space_handle_t memh; 225 1.1 bad 226 1.28 msaitoh sc->sc_dev = self; 227 1.27 msaitoh aprint_naive("\n"); 228 1.27 msaitoh 229 1.1 bad /* Map i/o space. */ 230 1.6 thorpej if (bus_space_map(iot, ia->ia_io[0].ir_addr, TCIC_IOSIZE, 0, &ioh)) { 231 1.27 msaitoh aprint_error(": can't map i/o space\n"); 232 1.1 bad return; 233 1.1 bad } 234 1.1 bad 235 1.1 bad /* Map mem space. */ 236 1.6 thorpej if (bus_space_map(memt, ia->ia_iomem[0].ir_addr, 237 1.6 thorpej ia->ia_iomem[0].ir_size, 0, &memh)) { 238 1.27 msaitoh aprint_error(": can't map mem space\n"); 239 1.1 bad return; 240 1.1 bad } 241 1.1 bad 242 1.6 thorpej sc->membase = ia->ia_iomem[0].ir_addr; 243 1.6 thorpej sc->subregionmask = 244 1.6 thorpej (1 << (ia->ia_iomem[0].ir_size / TCIC_MEM_PAGESIZE)) - 1; 245 1.6 thorpej sc->memsize2 = tcic_log2((u_int)ia->ia_iomem[0].ir_size); 246 1.1 bad 247 1.1 bad sc->intr_est = ic; 248 1.1 bad sc->pct = (pcmcia_chipset_tag_t) & tcic_isa_functions; 249 1.1 bad 250 1.1 bad sc->iot = iot; 251 1.1 bad sc->ioh = ioh; 252 1.1 bad sc->memt = memt; 253 1.1 bad sc->memh = memh; 254 1.1 bad 255 1.1 bad /* 256 1.29 andvar * determine chip type and initialise some chip type dependent 257 1.1 bad * parameters in softc. 258 1.1 bad */ 259 1.1 bad sc->chipid = tcic_chipid(iot, ioh); 260 1.1 bad sc->validirqs = tcic_validirqs(sc->chipid); 261 1.1 bad 262 1.1 bad /* 263 1.2 bad * allocate an irq. interrupts are relatively 264 1.2 bad * scarce but for TCIC controllers very infrequent. 265 1.1 bad */ 266 1.1 bad 267 1.6 thorpej if (ia->ia_nirq < 1) 268 1.11 drochner sc->irq = ISA_UNKNOWN_IRQ; 269 1.6 thorpej else 270 1.6 thorpej sc->irq = ia->ia_irq[0].ir_irq; 271 1.11 drochner if (sc->irq == ISA_UNKNOWN_IRQ) { 272 1.1 bad if (isa_intr_alloc(ic, 273 1.1 bad sc->validirqs & (tcic_isa_intr_alloc_mask & 0xff00), 274 1.1 bad IST_EDGE, &sc->irq)) { 275 1.20 cegger aprint_normal("\n"); 276 1.26 chs aprint_error_dev(self, "can't allocate interrupt\n"); 277 1.1 bad return; 278 1.1 bad } 279 1.27 msaitoh aprint_normal(": using irq %d", sc->irq); 280 1.1 bad } 281 1.27 msaitoh aprint_normal("\n"); 282 1.1 bad 283 1.1 bad tcic_attach(sc); 284 1.1 bad 285 1.1 bad 286 1.1 bad /* 287 1.1 bad * XXX mycroft recommends I/O space range 0x400-0xfff. 288 1.1 bad */ 289 1.1 bad 290 1.1 bad /* 291 1.1 bad * XXX some hardware doesn't seem to grok addresses in 0x400 range-- 292 1.1 bad * apparently missing a bit or more of address lines. (e.g. 293 1.1 bad * CIRRUS_PD672X with Linksys EthernetCard ne2000 clone in TI 294 1.1 bad * TravelMate 5000--not clear which is at fault) 295 1.13 perry * 296 1.1 bad * Add a kludge to detect 10 bit wide buses and deal with them, 297 1.1 bad * and also a config file option to override the probe. 298 1.1 bad */ 299 1.1 bad 300 1.1 bad #if 0 301 1.1 bad /* 302 1.1 bad * This is what we'd like to use, but... 303 1.1 bad */ 304 1.1 bad sc->iobase = 0x400; 305 1.1 bad sc->iosize = 0xbff; 306 1.1 bad #else 307 1.1 bad /* 308 1.1 bad * ...the above bus width probe doesn't always work. 309 1.1 bad * So, experimentation has shown the following range 310 1.1 bad * to not lose on systems that 0x300-0x3ff loses on 311 1.1 bad * (e.g. the NEC Versa 6030X). 312 1.1 bad */ 313 1.1 bad sc->iobase = 0x330; 314 1.1 bad sc->iosize = 0x0cf; 315 1.1 bad #endif 316 1.1 bad 317 1.1 bad DPRINTF(("%s: bus_space_alloc range 0x%04lx-0x%04lx)\n", 318 1.26 chs device_xname(self), (long) sc->iobase, 319 1.1 bad (long) sc->iobase + sc->iosize)); 320 1.1 bad 321 1.1 bad if (tcic_isa_alloc_iobase && tcic_isa_alloc_iosize) { 322 1.1 bad sc->iobase = tcic_isa_alloc_iobase; 323 1.1 bad sc->iosize = tcic_isa_alloc_iosize; 324 1.1 bad 325 1.1 bad DPRINTF(("%s: bus_space_alloc range 0x%04lx-0x%04lx " 326 1.27 msaitoh "(config override)\n", device_xname(self), 327 1.27 msaitoh (long)sc->iobase, (long)sc->iobase + sc->iosize)); 328 1.1 bad } 329 1.1 bad sc->ih = isa_intr_establish(ic, sc->irq, IST_EDGE, IPL_TTY, 330 1.1 bad tcic_intr, sc); 331 1.1 bad if (sc->ih == NULL) { 332 1.27 msaitoh aprint_error_dev(self, "can't establish interrupt\n"); 333 1.1 bad return; 334 1.1 bad } 335 1.1 bad 336 1.1 bad tcic_attach_sockets(sc); 337 1.1 bad } 338 1.1 bad 339 1.1 bad void * 340 1.27 msaitoh tcic_isa_chip_intr_establish(pcmcia_chipset_handle_t pch, 341 1.27 msaitoh struct pcmcia_function *pf, int ipl, int (*fct)(void *), void *arg) 342 1.1 bad { 343 1.1 bad struct tcic_handle *h = (struct tcic_handle *) pch; 344 1.1 bad int irq, ist; 345 1.1 bad void *ih; 346 1.1 bad 347 1.27 msaitoh DPRINTF(("%s: tcic_isa_chip_intr_establish\n", 348 1.27 msaitoh device_xname(h->sc->sc_dev))); 349 1.1 bad 350 1.1 bad /* XXX should we convert level to pulse? -chb */ 351 1.1 bad if (pf->cfe->flags & PCMCIA_CFE_IRQLEVEL) 352 1.1 bad ist = IST_LEVEL; 353 1.1 bad else if (pf->cfe->flags & PCMCIA_CFE_IRQPULSE) 354 1.1 bad ist = IST_PULSE; 355 1.1 bad else 356 1.1 bad ist = IST_LEVEL; 357 1.1 bad 358 1.1 bad if (isa_intr_alloc(h->sc->intr_est, 359 1.1 bad h->sc->validirqs & tcic_isa_intr_alloc_mask, ist, &irq)) 360 1.1 bad return (NULL); 361 1.1 bad if ((ih = isa_intr_establish(h->sc->intr_est, irq, ist, ipl, 362 1.1 bad fct, arg)) == NULL) 363 1.1 bad return (NULL); 364 1.1 bad 365 1.26 chs DPRINTF(("%s: intr estrablished\n", device_xname(h->sc->sc_dev))); 366 1.1 bad 367 1.1 bad h->ih_irq = irq; 368 1.1 bad 369 1.20 cegger printf("%s: card irq %d\n", device_xname(h->pcmcia), irq); 370 1.1 bad 371 1.1 bad return (ih); 372 1.1 bad } 373 1.1 bad 374 1.13 perry void 375 1.22 dsl tcic_isa_chip_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih) 376 1.1 bad { 377 1.1 bad struct tcic_handle *h = (struct tcic_handle *) pch; 378 1.1 bad int val, reg; 379 1.1 bad 380 1.27 msaitoh DPRINTF(("%s: tcic_isa_chip_intr_disestablish\n", 381 1.27 msaitoh device_xname(h->sc->sc_dev))); 382 1.1 bad 383 1.1 bad h->ih_irq = 0; 384 1.1 bad 385 1.1 bad reg = TCIC_IR_SCF1_N(h->sock); 386 1.1 bad val = tcic_read_ind_2(h, reg); 387 1.1 bad val &= ~TCIC_SCF1_IRQ_MASK; 388 1.1 bad tcic_write_ind_2(h, reg, val); 389 1.1 bad 390 1.1 bad isa_intr_disestablish(h->sc->intr_est, ih); 391 1.1 bad } 392