1 /* $NetBSD: tcic2var.h,v 1.2 2001/12/15 13:23:22 soren 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 #ifndef _TCIC2VAR_H 34 #define _TCIC2VAR_H 35 36 #include <sys/device.h> 37 38 #include <dev/pcmcia/pcmciareg.h> 39 #include <dev/pcmcia/pcmciachip.h> 40 41 #include <dev/ic/tcic2reg.h> 42 43 struct proc; 44 45 struct tcic_event { 46 SIMPLEQ_ENTRY(tcic_event) pe_q; 47 int pe_type; 48 }; 49 50 /* pe_type */ 51 #define TCIC_EVENT_INSERTION 0 52 #define TCIC_EVENT_REMOVAL 1 53 54 55 struct tcic_handle { 56 struct tcic_softc *sc; 57 int sock; /* socket number */ 58 int flags; 59 int sstat; /* last value of R_SSTAT */ 60 int memalloc; 61 int memwins; 62 struct { 63 bus_addr_t addr; 64 bus_size_t size; 65 int size2; /* size as 2^n scaled by 4K */ 66 long offset; 67 int speed; /* in ns */ 68 int kind; 69 } mem[TCIC_MAX_MEM_WINS]; 70 int ioalloc; 71 struct { 72 bus_addr_t addr; 73 bus_size_t size; 74 int width; 75 int speed; /* in ns */ 76 } io[TCIC_IO_WINS]; 77 int ih_irq; 78 struct device *pcmcia; 79 80 int shutdown; 81 struct proc *event_thread; 82 SIMPLEQ_HEAD(, tcic_event) events; 83 }; 84 85 #define TCIC_FLAG_SOCKETP 0x0001 86 #define TCIC_FLAG_CARDP 0x0002 87 88 /* 89 * This is sort of arbitrary. It merely needs to be "enough". It can be 90 * overridden in the conf file, anyway. 91 */ 92 93 #define TCIC_MEM_PAGES 4 94 #define TCIC_MEMSIZE TCIC_MEM_PAGES*TCIC_MEM_PAGESIZE 95 96 #define TCIC_NSLOTS 2 97 98 struct tcic_softc { 99 struct device dev; 100 101 bus_space_tag_t memt; 102 bus_space_handle_t memh; 103 bus_space_tag_t iot; 104 bus_space_handle_t ioh; 105 106 int chipid; 107 int validirqs; 108 int pwrena; /* holds TCIC_PWR_ENA on'084 and successors */ 109 110 /* XXX isa_chipset_tag_t, pci_chipset_tag_t, etc. */ 111 void *intr_est; 112 113 pcmcia_chipset_tag_t pct; 114 115 /* this needs to be large enough to hold TCIC_MEM_PAGES bits */ 116 int subregionmask; 117 118 /* used by memory window mapping functions */ 119 bus_addr_t membase; 120 int memsize2; /* int(log2(memsize)) */ 121 122 /* 123 * used by io window mapping functions. These can actually overlap 124 * with another tcic, since the underlying extent mapper will deal 125 * with individual allocations. This is here to deal with the fact 126 * that different busses have different real widths (different pc 127 * hardware seems to use 10 or 12 bits for the I/O bus). 128 */ 129 bus_addr_t iobase; 130 bus_size_t iosize; 131 132 int irq; 133 void *ih; 134 135 struct tcic_handle handle[TCIC_NSLOTS]; 136 }; 137 138 int tcic_log2 __P((u_int)); 139 int tcic_ns2wscnt __P((int)); 140 141 int tcic_check_reserved_bits __P((bus_space_tag_t, bus_space_handle_t)); 142 int tcic_chipid __P((bus_space_tag_t, bus_space_handle_t)); 143 int tcic_chipid_known __P((int)); 144 char *tcic_chipid_to_string __P((int)); 145 int tcic_validirqs __P((int)); 146 147 void tcic_attach __P((struct tcic_softc *)); 148 void tcic_attach_sockets __P((struct tcic_softc *)); 149 int tcic_intr __P((void *arg)); 150 151 static __inline__ int tcic_read_1 __P((struct tcic_handle *, int)); 152 static __inline__ int tcic_read_2 __P((struct tcic_handle *, int)); 153 static __inline__ int tcic_read_4 __P((struct tcic_handle *, int)); 154 static __inline__ void tcic_write_1 __P((struct tcic_handle *, int, int)); 155 static __inline__ void tcic_write_2 __P((struct tcic_handle *, int, int)); 156 static __inline__ void tcic_write_4 __P((struct tcic_handle *, int, int)); 157 static __inline__ int tcic_read_ind_2 __P((struct tcic_handle *, int)); 158 static __inline__ void tcic_write_ind_2 __P((struct tcic_handle *, int, int)); 159 static __inline__ void tcic_sel_sock __P((struct tcic_handle *)); 160 static __inline__ void tcic_wait_ready __P((struct tcic_handle *)); 161 static __inline__ int tcic_read_aux_1 __P((bus_space_tag_t, bus_space_handle_t, int, int)); 162 static __inline__ int tcic_read_aux_2 __P((bus_space_tag_t, bus_space_handle_t, int)); 163 static __inline__ void tcic_write_aux_1 __P((bus_space_tag_t, bus_space_handle_t, int, int, int)); 164 static __inline__ void tcic_write_aux_2 __P((bus_space_tag_t, bus_space_handle_t, int, int)); 165 166 int tcic_chip_mem_alloc __P((pcmcia_chipset_handle_t, bus_size_t, 167 struct pcmcia_mem_handle *)); 168 void tcic_chip_mem_free __P((pcmcia_chipset_handle_t, 169 struct pcmcia_mem_handle *)); 170 int tcic_chip_mem_map __P((pcmcia_chipset_handle_t, int, bus_addr_t, 171 bus_size_t, struct pcmcia_mem_handle *, bus_size_t *, int *)); 172 void tcic_chip_mem_unmap __P((pcmcia_chipset_handle_t, int)); 173 174 int tcic_chip_io_alloc __P((pcmcia_chipset_handle_t, bus_addr_t, 175 bus_size_t, bus_size_t, struct pcmcia_io_handle *)); 176 void tcic_chip_io_free __P((pcmcia_chipset_handle_t, 177 struct pcmcia_io_handle *)); 178 int tcic_chip_io_map __P((pcmcia_chipset_handle_t, int, bus_addr_t, 179 bus_size_t, struct pcmcia_io_handle *, int *)); 180 void tcic_chip_io_unmap __P((pcmcia_chipset_handle_t, int)); 181 182 void tcic_chip_socket_enable __P((pcmcia_chipset_handle_t)); 183 void tcic_chip_socket_disable __P((pcmcia_chipset_handle_t)); 184 185 static __inline__ int tcic_read_1 __P((struct tcic_handle *, int)); 186 static __inline__ int 187 tcic_read_1(h, reg) 188 struct tcic_handle *h; 189 int reg; 190 { 191 return (bus_space_read_1(h->sc->iot, h->sc->ioh, reg)); 192 } 193 194 static __inline__ int tcic_read_2 __P((struct tcic_handle *, int)); 195 static __inline__ int 196 tcic_read_2(h, reg) 197 struct tcic_handle *h; 198 int reg; 199 { 200 return (bus_space_read_2(h->sc->iot, h->sc->ioh, reg)); 201 } 202 203 static __inline__ int tcic_read_4 __P((struct tcic_handle *, int)); 204 static __inline__ int 205 tcic_read_4(h, reg) 206 struct tcic_handle *h; 207 int reg; 208 { 209 int val; 210 val = bus_space_read_2(h->sc->iot, h->sc->ioh, reg); 211 val |= bus_space_read_2(h->sc->iot, h->sc->ioh, reg+2) << 16; 212 return val; 213 } 214 215 static __inline__ void tcic_write_1 __P((struct tcic_handle *, int, int)); 216 static __inline__ void 217 tcic_write_1(h, reg, data) 218 struct tcic_handle *h; 219 int reg; 220 int data; 221 { 222 bus_space_write_1(h->sc->iot, h->sc->ioh, reg, (data)); 223 } 224 225 static __inline__ void tcic_write_2 __P((struct tcic_handle *, int, int)); 226 static __inline__ void 227 tcic_write_2(h, reg, data) 228 struct tcic_handle *h; 229 int reg; 230 int data; 231 { 232 bus_space_write_2(h->sc->iot, h->sc->ioh, reg, (data)); 233 } 234 235 static __inline__ void tcic_write_4 __P((struct tcic_handle *, int, int)); 236 static __inline__ void 237 tcic_write_4(h, reg, data) 238 struct tcic_handle *h; 239 int reg; 240 int data; 241 { 242 bus_space_write_2(h->sc->iot, h->sc->ioh, reg, (data)); 243 bus_space_write_2(h->sc->iot, h->sc->ioh, reg+2, (data)>>16); 244 } 245 246 static __inline__ int tcic_read_ind_2 __P((struct tcic_handle *, int)); 247 static __inline__ int 248 tcic_read_ind_2(h, reg) 249 struct tcic_handle *h; 250 int reg; 251 { 252 int r_addr, val; 253 r_addr = tcic_read_4(h, TCIC_R_ADDR); 254 tcic_write_4(h, TCIC_R_ADDR, reg|TCIC_ADDR_INDREG); 255 val = bus_space_read_2(h->sc->iot, h->sc->ioh, TCIC_R_DATA); 256 tcic_write_4(h, TCIC_R_ADDR, r_addr); 257 return val; 258 } 259 260 static __inline__ void tcic_write_ind_2 __P((struct tcic_handle *, int, int)); 261 static __inline__ void 262 tcic_write_ind_2(h, reg, data) 263 struct tcic_handle *h; 264 int reg; 265 int data; 266 { 267 int r_addr; 268 r_addr = tcic_read_4(h, TCIC_R_ADDR); 269 tcic_write_4(h, TCIC_R_ADDR, reg|TCIC_ADDR_INDREG); 270 bus_space_write_2(h->sc->iot, h->sc->ioh, TCIC_R_DATA, (data)); 271 tcic_write_4(h, TCIC_R_ADDR, r_addr); 272 } 273 274 static __inline__ void tcic_sel_sock __P((struct tcic_handle *)); 275 static __inline__ void 276 tcic_sel_sock(h) 277 struct tcic_handle *h; 278 { 279 int r_addr; 280 r_addr = tcic_read_2(h, TCIC_R_ADDR2); 281 tcic_write_2(h, TCIC_R_ADDR2, 282 (h->sock<<TCIC_ADDR2_SS_SHFT)|(r_addr & ~TCIC_ADDR2_SS_MASK)); 283 } 284 285 static __inline__ void tcic_wait_ready __P((struct tcic_handle *)); 286 static __inline__ void 287 tcic_wait_ready(h) 288 struct tcic_handle *h; 289 { 290 int i; 291 292 /* XXX appropriate socket must have been selected already. */ 293 for (i = 0; i < 10000; i++) { 294 if (tcic_read_1(h, TCIC_R_SSTAT) & TCIC_SSTAT_RDY) 295 return; 296 delay(500); 297 } 298 299 #ifdef DIAGNOSTIC 300 printf("tcic_wait_ready ready never happened\n"); 301 #endif 302 } 303 304 static __inline__ int tcic_read_aux_1 __P((bus_space_tag_t, bus_space_handle_t, int, int)); 305 static __inline__ int 306 tcic_read_aux_1(iot, ioh, auxreg, reg) 307 bus_space_tag_t iot; 308 bus_space_handle_t ioh; 309 int auxreg; 310 { 311 int mode, val; 312 mode = bus_space_read_1(iot, ioh, TCIC_R_MODE); 313 bus_space_write_1(iot, ioh, TCIC_R_MODE, (mode & ~TCIC_AR_MASK)|auxreg); 314 val = bus_space_read_1(iot, ioh, reg); 315 return val; 316 } 317 318 static __inline__ int tcic_read_aux_2 __P((bus_space_tag_t, bus_space_handle_t, int)); 319 static __inline__ int 320 tcic_read_aux_2(iot, ioh, auxreg) 321 bus_space_tag_t iot; 322 bus_space_handle_t ioh; 323 int auxreg; 324 { 325 int mode, val; 326 mode = bus_space_read_1(iot, ioh, TCIC_R_MODE); 327 bus_space_write_1(iot, ioh, TCIC_R_MODE, (mode & ~TCIC_AR_MASK)|auxreg); 328 val = bus_space_read_2(iot, ioh, TCIC_R_AUX); 329 return val; 330 } 331 332 static __inline__ void tcic_write_aux_1 __P((bus_space_tag_t, bus_space_handle_t, int, int, int)); 333 static __inline__ void 334 tcic_write_aux_1(iot, ioh, auxreg, reg, val) 335 bus_space_tag_t iot; 336 bus_space_handle_t ioh; 337 int auxreg, reg, val; 338 { 339 int mode; 340 mode = bus_space_read_1(iot, ioh, TCIC_R_MODE); 341 bus_space_write_1(iot, ioh, TCIC_R_MODE, (mode & ~TCIC_AR_MASK)|auxreg); 342 bus_space_write_1(iot, ioh, reg, val); 343 } 344 345 static __inline__ void tcic_write_aux_2 __P((bus_space_tag_t, bus_space_handle_t, int, int)); 346 static __inline__ void 347 tcic_write_aux_2(iot, ioh, auxreg, val) 348 bus_space_tag_t iot; 349 bus_space_handle_t ioh; 350 int auxreg, val; 351 { 352 int mode; 353 mode = bus_space_read_1(iot, ioh, TCIC_R_MODE); 354 bus_space_write_1(iot, ioh, TCIC_R_MODE, (mode & ~TCIC_AR_MASK)|auxreg); 355 bus_space_write_2(iot, ioh, TCIC_R_AUX, val); 356 } 357 358 #endif /* _TCIC2VAR_H */ 359