1 /* $NetBSD: sa11xx_pcic.c,v 1.11 2007/12/06 17:00:31 ad Exp $ */ 2 3 /* 4 * Copyright (c) 2001 IWAMOTO Toshihiro. 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 /* 34 * Common code for SA-11x0 based PCMCIA modules. 35 */ 36 37 #include <sys/cdefs.h> 38 __KERNEL_RCSID(0, "$NetBSD: sa11xx_pcic.c,v 1.11 2007/12/06 17:00:31 ad Exp $"); 39 40 #include <sys/types.h> 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/device.h> 44 #include <sys/callout.h> 45 #include <sys/kernel.h> 46 #include <sys/kthread.h> 47 #include <sys/malloc.h> 48 #include <sys/bus.h> 49 #include <sys/intr.h> 50 51 #include <uvm/uvm.h> 52 53 #include <dev/pcmcia/pcmciareg.h> 54 #include <dev/pcmcia/pcmciavar.h> 55 #include <dev/pcmcia/pcmciachip.h> 56 57 #include <arm/sa11x0/sa11x0_reg.h> 58 #include <arm/sa11x0/sa11x0_var.h> 59 #include <arm/sa11x0/sa11xx_pcicreg.h> 60 #include <arm/sa11x0/sa11xx_pcicvar.h> 61 62 static int sapcic_mem_alloc(pcmcia_chipset_handle_t, bus_size_t, 63 struct pcmcia_mem_handle *); 64 static void sapcic_mem_free(pcmcia_chipset_handle_t, 65 struct pcmcia_mem_handle *); 66 static int sapcic_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t, 67 bus_size_t, struct pcmcia_mem_handle *, 68 bus_addr_t *, int *); 69 static void sapcic_mem_unmap(pcmcia_chipset_handle_t, int); 70 static int sapcic_io_alloc(pcmcia_chipset_handle_t, bus_addr_t, 71 bus_size_t, bus_size_t, 72 struct pcmcia_io_handle *); 73 static void sapcic_io_free(pcmcia_chipset_handle_t, 74 struct pcmcia_io_handle *); 75 static int sapcic_io_map(pcmcia_chipset_handle_t, int, 76 bus_addr_t, bus_size_t, 77 struct pcmcia_io_handle *, int *); 78 static void sapcic_io_unmap(pcmcia_chipset_handle_t, int); 79 static void *sapcic_intr_establish(pcmcia_chipset_handle_t, 80 struct pcmcia_function *, int, 81 int (*)(void *), void *); 82 static void sapcic_intr_disestablish(pcmcia_chipset_handle_t, 83 void *); 84 static void sapcic_socket_enable(pcmcia_chipset_handle_t); 85 static void sapcic_socket_disable(pcmcia_chipset_handle_t); 86 static void sapcic_socket_settype(pcmcia_chipset_handle_t, int); 87 88 static void sapcic_event_thread(void *); 89 90 static void sapcic_delay(int, const char *); 91 92 #ifdef DEBUG 93 #define DPRINTF(arg) printf arg 94 #else 95 #define DPRINTF(arg) 96 #endif 97 98 struct pcmcia_chip_functions sa11x0_pcmcia_functions = { 99 sapcic_mem_alloc, 100 sapcic_mem_free, 101 sapcic_mem_map, 102 sapcic_mem_unmap, 103 104 sapcic_io_alloc, 105 sapcic_io_free, 106 sapcic_io_map, 107 sapcic_io_unmap, 108 109 sapcic_intr_establish, 110 sapcic_intr_disestablish, 111 112 sapcic_socket_enable, 113 sapcic_socket_disable, 114 sapcic_socket_settype, 115 }; 116 117 118 void 119 sapcic_kthread_create(void *arg) 120 { 121 struct sapcic_socket *so = arg; 122 123 /* XXX attach card if already present */ 124 125 mutex_init(&so->sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 126 127 so->laststatus = (so->pcictag->read)(so, SAPCIC_STATUS_CARD); 128 if (so->laststatus == SAPCIC_CARD_VALID) { 129 printf("%s: card present\n", 130 so->sc->sc_dev.dv_xname); 131 132 pcmcia_card_attach(so->pcmcia); 133 } 134 135 if (kthread_create(PRI_NONE, 0, NULL, sapcic_event_thread, so, 136 &so->event_thread, "%s,%d", so->sc->sc_dev.dv_xname, so->socket)) { 137 printf("%s: unable to create event thread for socket %d\n", 138 so->sc->sc_dev.dv_xname, so->socket); 139 panic("sapcic_kthread_create"); 140 } 141 } 142 143 static void 144 sapcic_event_thread(void *arg) 145 { 146 struct sapcic_socket *so = arg; 147 int newstatus, s; 148 149 while (so->shutdown == 0) { 150 /* 151 * Serialize event processing on the PCIC. We may 152 * sleep while we hold this lock. 153 */ 154 mutex_enter(&so->sc->sc_lock); 155 156 /* sleep .25s to be enqueued chatterling interrupts */ 157 (void) tsleep(sapcic_event_thread, PWAIT, "pcicss", hz / 4); 158 159 s = splhigh(); 160 so->event = 0; 161 162 /* we don't rely on interrupt type */ 163 newstatus = (so->pcictag->read)(so, SAPCIC_STATUS_CARD); 164 splx(s); 165 166 if (so->laststatus == newstatus) { 167 /* 168 * No events to process; release the PCIC lock. 169 */ 170 mutex_exit(&so->sc->sc_lock); 171 (void) tsleep(&so->event, PWAIT, "pcicev", hz); 172 continue; 173 } 174 175 so->laststatus = newstatus; 176 switch (newstatus) { 177 case SAPCIC_CARD_VALID: 178 printf("%s: insertion event\n", 179 so->sc->sc_dev.dv_xname); 180 181 pcmcia_card_attach(so->pcmcia); 182 break; 183 184 case SAPCIC_CARD_INVALID: 185 printf("%s: removal event\n", 186 so->sc->sc_dev.dv_xname); 187 188 pcmcia_card_detach(so->pcmcia, DETACH_FORCE); 189 break; 190 191 default: 192 panic("sapcic_event_thread: unknown status %d", 193 newstatus); 194 } 195 196 mutex_exit(&so->sc->sc_lock); 197 } 198 199 so->event_thread = NULL; 200 201 /* In case parent is waiting for us to exit. */ 202 wakeup(so->sc); 203 204 kthread_exit(0); 205 } 206 207 static void 208 sapcic_delay(int timo, const char *wmesg) 209 { 210 #ifdef DIAGNOSTIC 211 if (curlwp == NULL) 212 panic("sapcic_delay: called in interrupt context"); 213 #endif 214 215 tsleep(sapcic_delay, PWAIT, wmesg, roundup(timo * hz, 1000) / 1000); 216 } 217 218 int 219 sapcic_intr(void *arg) 220 { 221 struct sapcic_socket *so = arg; 222 223 so->event++; 224 (so->pcictag->clear_intr)(so->socket); 225 wakeup(&so->event); 226 return 1; 227 } 228 229 static int 230 sapcic_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, 231 struct pcmcia_mem_handle *pmh) 232 { 233 struct sapcic_socket *so = pch; 234 235 /* All we need is bus space tag */ 236 memset(pmh, 0, sizeof(*pmh)); 237 pmh->memt = so->sc->sc_iot; 238 return 0; 239 } 240 241 242 static void 243 sapcic_mem_free(pcmcia_chipset_handle_t pch, struct pcmcia_mem_handle *pmh) 244 { 245 } 246 247 static int 248 sapcic_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr, 249 bus_size_t size, struct pcmcia_mem_handle *pmh, bus_addr_t *offsetp, 250 int *windowp) 251 { 252 struct sapcic_socket *so = pch; 253 int error; 254 bus_addr_t pa; 255 256 pa = trunc_page(card_addr); 257 *offsetp = card_addr - pa; 258 size = round_page(card_addr + size) - pa; 259 pmh->realsize = size; 260 261 pa += SAPCIC_BASE_OFFSET; 262 pa += SAPCIC_SOCKET_OFFSET * so->socket; 263 264 switch (kind & ~PCMCIA_WIDTH_MEM_MASK) { 265 case PCMCIA_MEM_ATTR: 266 pa += SAPCIC_ATTR_OFFSET; 267 break; 268 case PCMCIA_MEM_COMMON: 269 pa += SAPCIC_COMMON_OFFSET; 270 break; 271 default: 272 panic("sapcic_mem_map: bogus kind"); 273 } 274 275 error = bus_space_map(so->sc->sc_iot, pa, size, 0, &pmh->memh); 276 if (!error) 277 *windowp = (int)pmh->memh; 278 return error; 279 } 280 281 static void 282 sapcic_mem_unmap(pcmcia_chipset_handle_t pch, int window) 283 { 284 struct sapcic_socket *so = pch; 285 286 bus_space_unmap(so->sc->sc_iot, (bus_addr_t)window, 4096); /* XXX */ 287 } 288 289 static int 290 sapcic_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start, 291 bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pih) 292 { 293 struct sapcic_socket *so = pch; 294 int error; 295 bus_addr_t pa; 296 297 memset(pih, 0, sizeof(*pih)); 298 pih->iot = so->sc->sc_iot; 299 pih->addr = start; 300 pih->size = size; 301 302 pa = pih->addr; 303 pa += SAPCIC_BASE_OFFSET; 304 pa += SAPCIC_SOCKET_OFFSET * so->socket; 305 306 DPRINTF(("sapcic_io_alloc: %x %x\n", (unsigned int)pa, 307 (unsigned int)size)); 308 /* XXX Are we ignoring alignment constraints? */ 309 error = bus_space_map(so->sc->sc_iot, pa, size, 0, &pih->ioh); 310 311 return error; 312 } 313 314 static void 315 sapcic_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pih) 316 { 317 struct sapcic_socket *so = pch; 318 319 bus_space_unmap(so->sc->sc_iot, pih->ioh, pih->size); 320 } 321 322 static int 323 sapcic_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, 324 bus_size_t size, struct pcmcia_io_handle *pih, int *windowp) 325 { 326 327 return 0; 328 } 329 330 static void sapcic_io_unmap(pcmcia_chipset_handle_t pch, int window) 331 { 332 } 333 334 static void * 335 sapcic_intr_establish(pcmcia_chipset_handle_t pch, struct pcmcia_function *pf, 336 int ipl, int (*fct)(void *), void *arg) 337 { 338 struct sapcic_socket *so = pch; 339 340 /* XXX need to check if something should be done here */ 341 342 return (so->pcictag->intr_establish)(so, ipl, fct, arg); 343 } 344 345 static void 346 sapcic_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih) 347 { 348 struct sapcic_socket *so = pch; 349 350 (so->pcictag->intr_disestablish)(so, ih); 351 } 352 353 static void 354 sapcic_socket_enable(pcmcia_chipset_handle_t pch) 355 { 356 struct sapcic_socket *so = pch; 357 int i; 358 359 #if defined(DIAGNOSTIC) && defined(notyet) 360 if (so->flags & PCIC_FLAG_ENABLED) 361 printf("sapcic_socket_enable: enabling twice\n"); 362 #endif 363 364 /* disable interrupts */ 365 366 /* power down the socket to reset it, clear the card reset pin */ 367 (so->pcictag->set_power)(so, SAPCIC_POWER_OFF); 368 369 /* 370 * wait 300ms until power fails (Tpf). Then, wait 100ms since 371 * we are changing Vcc (Toff). 372 */ 373 sapcic_delay(300 + 100, "pccen0"); 374 375 /* power up the socket */ 376 /* XXX voltage selection should be done in PCMCIA code */ 377 if (so->power_capability & SAPCIC_POWER_5V) { 378 (so->pcictag->set_power)(so, SAPCIC_POWER_5V); 379 (so->pcictag->write)(so, SAPCIC_CONTROL_POWERSELECT, 380 SAPCIC_POWER_5V); 381 } else { 382 (so->pcictag->set_power)(so, SAPCIC_POWER_3V); 383 (so->pcictag->write)(so, SAPCIC_CONTROL_POWERSELECT, 384 SAPCIC_POWER_3V); 385 } 386 387 /* enable PCMCIA control lines */ 388 (so->pcictag->write)(so, SAPCIC_CONTROL_LINEENABLE, 1); 389 390 /* 391 * wait 100ms until power raise (Tpr) and 20ms to become 392 * stable (Tsu(Vcc)). 393 * 394 * some machines require some more time to be settled 395 * (300ms is added here). 396 */ 397 sapcic_delay(100 + 20 + 300, "pccen1"); 398 399 /* honor nWAIT signal */ 400 (so->pcictag->write)(so, SAPCIC_CONTROL_WAITENABLE, 1); 401 /* now make sure we have reset# active */ 402 (so->pcictag->write)(so, SAPCIC_CONTROL_RESET, 1); 403 404 /* 405 * hold RESET at least 10us, this is a min allow for slop in 406 * delay routine. 407 */ 408 delay(20); 409 410 /* clear the reset flag */ 411 (so->pcictag->write)(so, SAPCIC_CONTROL_RESET, 0); 412 413 /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */ 414 sapcic_delay(20, "pccen2"); 415 416 /* wait for the chip to finish initializing */ 417 sapcic_delay(10, "pccen3"); 418 for (i = 100; i; i--) { 419 if ((so->pcictag->read)(so, SAPCIC_STATUS_READY)) 420 break; 421 sapcic_delay(100, "pccen4"); 422 } 423 DPRINTF(("sapcic_socket_enable: wait ready %d\n", 100 - i)); 424 425 /* finally enable the interrupt */ 426 427 } 428 429 static void 430 sapcic_socket_disable(pcmcia_chipset_handle_t pch) 431 { 432 struct sapcic_socket *so = pch; 433 434 /* XXX mask card interrupts */ 435 436 /* power down the card */ 437 (so->pcictag->set_power)(so, SAPCIC_POWER_OFF); 438 439 /* float controller lines */ 440 (so->pcictag->write)(so, SAPCIC_CONTROL_LINEENABLE, 0); 441 } 442 443 static void 444 sapcic_socket_settype(pcmcia_chipset_handle_t pch, int type) 445 { 446 447 /* XXX nothing to do */ 448 } 449