1 /* $NetBSD: pxa2x0_pcic.c,v 1.12 2013/10/13 06:55:34 riz Exp $ */ 2 /* $OpenBSD: pxa2x0_pcic.c,v 1.17 2005/12/14 15:08:51 uwe Exp $ */ 3 4 /* 5 * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/cdefs.h> 21 __KERNEL_RCSID(0, "$NetBSD: pxa2x0_pcic.c,v 1.12 2013/10/13 06:55:34 riz Exp $"); 22 23 #include <sys/param.h> 24 #include <sys/systm.h> 25 #include <sys/device.h> 26 #include <sys/kernel.h> 27 #include <sys/kthread.h> 28 #include <sys/malloc.h> 29 30 #include <uvm/uvm.h> 31 32 #include <sys/bus.h> 33 #include <machine/intr.h> 34 35 #include <dev/pcmcia/pcmciareg.h> 36 #include <dev/pcmcia/pcmciavar.h> 37 #include <dev/pcmcia/pcmciachip.h> 38 39 #include <arm/xscale/pxa2x0cpu.h> 40 #include <arm/xscale/pxa2x0reg.h> 41 #include <arm/xscale/pxa2x0var.h> 42 #include <arm/xscale/pxa2x0_gpio.h> 43 #include <arm/xscale/pxa2x0_pcic.h> 44 45 static int pxapcic_print(void *, const char *); 46 47 static void pxapcic_doattach(device_t); 48 49 static void pxapcic_event_thread(void *); 50 static void pxapcic_event_process(struct pxapcic_socket *); 51 static void pxapcic_attach_card(struct pxapcic_socket *); 52 static void pxapcic_detach_card(struct pxapcic_socket *, int); 53 54 static int pxapcic_mem_alloc(pcmcia_chipset_handle_t, bus_size_t, 55 struct pcmcia_mem_handle *); 56 static void pxapcic_mem_free(pcmcia_chipset_handle_t, 57 struct pcmcia_mem_handle *); 58 static int pxapcic_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t, 59 bus_size_t, struct pcmcia_mem_handle *, bus_size_t *, int *); 60 static void pxapcic_mem_unmap(pcmcia_chipset_handle_t, int); 61 62 static int pxapcic_io_alloc(pcmcia_chipset_handle_t, bus_addr_t, 63 bus_size_t, bus_size_t, struct pcmcia_io_handle *); 64 static void pxapcic_io_free(pcmcia_chipset_handle_t, 65 struct pcmcia_io_handle *); 66 static int pxapcic_io_map(pcmcia_chipset_handle_t, int, 67 bus_addr_t, bus_size_t, struct pcmcia_io_handle *, int *); 68 static void pxapcic_io_unmap(pcmcia_chipset_handle_t, int); 69 70 static void *pxapcic_intr_establish(pcmcia_chipset_handle_t, 71 struct pcmcia_function *, int, int (*)(void *), void *); 72 static void pxapcic_intr_disestablish(pcmcia_chipset_handle_t, void *); 73 74 static void pxapcic_socket_enable(pcmcia_chipset_handle_t); 75 static void pxapcic_socket_disable(pcmcia_chipset_handle_t); 76 static void pxapcic_socket_settype(pcmcia_chipset_handle_t, int); 77 78 /* 79 * PCMCIA chipset methods 80 */ 81 static struct pcmcia_chip_functions pxapcic_pcmcia_functions = { 82 pxapcic_mem_alloc, 83 pxapcic_mem_free, 84 pxapcic_mem_map, 85 pxapcic_mem_unmap, 86 87 pxapcic_io_alloc, 88 pxapcic_io_free, 89 pxapcic_io_map, 90 pxapcic_io_unmap, 91 92 pxapcic_intr_establish, 93 pxapcic_intr_disestablish, 94 95 pxapcic_socket_enable, 96 pxapcic_socket_disable, 97 pxapcic_socket_settype, 98 }; 99 100 #define PXAPCIC_ATTR_OFFSET 0x08000000 101 #define PXAPCIC_COMMON_OFFSET 0x0C000000 102 103 /* 104 * PCMCIA Helpers 105 */ 106 static int 107 pxapcic_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, 108 struct pcmcia_mem_handle *pmh) 109 { 110 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 111 112 /* All we need is the bus space tag */ 113 memset(pmh, 0, sizeof(*pmh)); 114 pmh->memt = so->sc->sc_iot; 115 116 return 0; 117 } 118 119 static void 120 pxapcic_mem_free(pcmcia_chipset_handle_t pch, struct pcmcia_mem_handle *pmh) 121 { 122 123 /* Nothing to do */ 124 } 125 126 static int 127 pxapcic_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr, 128 bus_size_t size, struct pcmcia_mem_handle *pmh, bus_size_t *offsetp, 129 int *windowp) 130 { 131 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 132 int error; 133 bus_addr_t pa; 134 135 pa = trunc_page(card_addr); 136 *offsetp = card_addr - pa; 137 size = round_page(card_addr + size) - pa; 138 pmh->realsize = size; 139 140 pa += PXA2X0_PCIC_SOCKET_BASE; 141 pa += PXA2X0_PCIC_SOCKET_OFFSET * so->socket; 142 143 switch (kind & ~PCMCIA_WIDTH_MEM_MASK) { 144 case PCMCIA_MEM_ATTR: 145 pa += PXAPCIC_ATTR_OFFSET; 146 break; 147 case PCMCIA_MEM_COMMON: 148 pa += PXAPCIC_COMMON_OFFSET; 149 break; 150 default: 151 panic("pxapcic_mem_map: bogus kind"); 152 } 153 154 error = bus_space_map(so->sc->sc_iot, pa, size, 0, &pmh->memh); 155 if (error) 156 return error; 157 158 *windowp = (int)pmh->memh; 159 return 0; 160 } 161 162 static void 163 pxapcic_mem_unmap(pcmcia_chipset_handle_t pch, int window) 164 { 165 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 166 167 bus_space_unmap(so->sc->sc_iot, (bus_addr_t)window, 4096); /* XXX */ 168 } 169 170 static int 171 pxapcic_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start, 172 bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pih) 173 { 174 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 175 bus_addr_t pa; 176 int error; 177 178 memset(pih, 0, sizeof(*pih)); 179 pih->iot = so->sc->sc_iot; 180 pih->addr = start; 181 pih->size = size; 182 183 pa = pih->addr; 184 pa += PXA2X0_PCIC_SOCKET_BASE; 185 pa += PXA2X0_PCIC_SOCKET_OFFSET * so->socket; 186 187 /* XXX Are we ignoring alignment constraints? */ 188 error = bus_space_map(so->sc->sc_iot, pa, size, 0, &pih->ioh); 189 190 return error; 191 } 192 193 static void 194 pxapcic_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pih) 195 { 196 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 197 198 bus_space_unmap(so->sc->sc_iot, pih->ioh, pih->size); 199 } 200 201 static int 202 pxapcic_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, 203 bus_size_t size, struct pcmcia_io_handle *pih, int *windowp) 204 { 205 206 return 0; 207 } 208 209 static void 210 pxapcic_io_unmap(pcmcia_chipset_handle_t pch, int window) 211 { 212 213 /* Nothing to do */ 214 } 215 216 static void * 217 pxapcic_intr_establish(pcmcia_chipset_handle_t pch, 218 struct pcmcia_function *pf, int ipl, int (*fct)(void *), void *arg) 219 { 220 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 221 /* XXX need to check if something should be done here */ 222 223 return (*so->pcictag->intr_establish)(so, ipl, fct, arg); 224 } 225 226 static void 227 pxapcic_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih) 228 { 229 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 230 231 (*so->pcictag->intr_disestablish)(so, ih); 232 } 233 234 static void 235 pxapcic_socket_enable(pcmcia_chipset_handle_t pch) 236 { 237 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 238 int i; 239 240 /* Power down the card and socket before setting the voltage. */ 241 (*so->pcictag->write)(so, PXAPCIC_CARD_POWER, PXAPCIC_POWER_OFF); 242 (*so->pcictag->set_power)(so, PXAPCIC_POWER_OFF); 243 244 /* 245 * Wait 300ms until power fails (Tpf). Then, wait 100ms since 246 * we are changing Vcc (Toff). 247 */ 248 delay((300 + 100) * 1000); 249 250 /* Power up the socket and card at appropriate voltage. */ 251 if (so->power_capability & PXAPCIC_POWER_5V) { 252 (*so->pcictag->set_power)(so, PXAPCIC_POWER_5V); 253 (*so->pcictag->write)(so, PXAPCIC_CARD_POWER, 254 PXAPCIC_POWER_5V); 255 } else { 256 (*so->pcictag->set_power)(so, PXAPCIC_POWER_3V); 257 (*so->pcictag->write)(so, PXAPCIC_CARD_POWER, 258 PXAPCIC_POWER_3V); 259 } 260 261 /* 262 * Wait 100ms until power raise (Tpr) and 20ms to become 263 * stable (Tsu(Vcc)). 264 * 265 * Some machines require some more time to be settled 266 * (another 200ms is added here). 267 */ 268 delay((100 + 20 + 200) * 1000); 269 270 /* Hold RESET at least 10us. */ 271 (*so->pcictag->write)(so, PXAPCIC_CARD_RESET, 1); 272 delay(10); 273 /* XXX wrong, but lets TE-CF100 cards work for some reason. */ 274 delay(3000); 275 (*so->pcictag->write)(so, PXAPCIC_CARD_RESET, 0); 276 277 /* Wait 20ms as per PC Card standard (r2.01) section 4.3.6. */ 278 delay(20 * 1000); 279 280 /* Wait for the card to become ready. */ 281 for (i = 0; i < 10000; i++) { 282 if ((*so->pcictag->read)(so, PXAPCIC_CARD_READY)) 283 break; 284 delay(500); 285 } 286 } 287 288 static void 289 pxapcic_socket_disable(pcmcia_chipset_handle_t pch) 290 { 291 struct pxapcic_socket *so = (struct pxapcic_socket *)pch; 292 293 #ifdef PCICDEBUG 294 printf("pxapcic_socket_disable: socket %d\n", so->socket); 295 #endif 296 297 /* Power down the card and socket. */ 298 (*so->pcictag->write)(so, PXAPCIC_CARD_POWER, PXAPCIC_POWER_OFF); 299 (*so->pcictag->set_power)(so, PXAPCIC_POWER_OFF); 300 } 301 302 static void 303 pxapcic_socket_settype(pcmcia_chipset_handle_t pch, int type) 304 { 305 306 #ifdef PCICDEBUG 307 printf("pxapcic_socket_settype: type=%d",type); 308 309 switch (type) { 310 case PCMCIA_IFTYPE_MEMORY: 311 printf("(Memory)\n"); 312 break; 313 case PCMCIA_IFTYPE_IO: 314 printf("(I/O)\n"); 315 break; 316 default: 317 printf("(unknown)\n"); 318 break; 319 } 320 #endif 321 } 322 323 /* 324 * Attachment and initialization 325 */ 326 static int 327 pxapcic_print(void *aux, const char *name) 328 { 329 330 return UNCONF; 331 } 332 333 void 334 pxapcic_attach_common(struct pxapcic_softc *sc, 335 void (*socket_setup_hook)(struct pxapcic_socket *)) 336 { 337 struct pcmciabus_attach_args paa; 338 struct pxapcic_socket *so; 339 int s[PXAPCIC_NSLOT]; 340 int i; 341 342 printf(": %d slot%s\n", sc->sc_nslots, sc->sc_nslots < 2 ? "" : "s"); 343 344 if (sc->sc_nslots == 0) { 345 aprint_error_dev(sc->sc_dev, "can't attach\n"); 346 return; 347 } 348 349 if (bus_space_map(sc->sc_iot, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 350 0, &sc->sc_memctl_ioh)) { 351 aprint_error_dev(sc->sc_dev, "failed to map MEMCTL\n"); 352 return; 353 } 354 355 /* Clear CIT (card present) and set NOS correctly. */ 356 bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR, 357 (sc->sc_nslots == 2) ? MECR_NOS : 0); 358 359 if (sc->sc_flags & PPF_REVERSE_ORDER) { 360 for (i = 0; i < sc->sc_nslots; i++) { 361 s[i] = sc->sc_nslots - 1 - i; 362 } 363 } else { 364 for (i = 0; i < sc->sc_nslots; i++) { 365 s[i] = i; 366 } 367 } 368 369 for (i = 0; i < sc->sc_nslots; i++) { 370 so = &sc->sc_socket[s[i]]; 371 so->sc = sc; 372 so->socket = s[i]; 373 so->flags = 0; 374 375 (*socket_setup_hook)(so); 376 377 paa.paa_busname = "pcmcia"; 378 paa.pct = (pcmcia_chipset_tag_t)&pxapcic_pcmcia_functions; 379 paa.pch = (pcmcia_chipset_handle_t)so; 380 381 so->pcmcia = config_found_ia(sc->sc_dev, "pcmciabus", &paa, 382 pxapcic_print); 383 384 pxa2x0_gpio_set_function(sc->sc_irqpin[s[i]], GPIO_IN); 385 pxa2x0_gpio_set_function(sc->sc_irqcfpin[s[i]], GPIO_IN); 386 387 /* Card slot interrupt */ 388 so->irq = pxa2x0_gpio_intr_establish(sc->sc_irqcfpin[s[i]], 389 IST_EDGE_BOTH, IPL_BIO /* XXX */, pxapcic_intr, so); 390 391 /* GPIO pin for interrupt */ 392 so->irqpin = sc->sc_irqpin[s[i]]; 393 } 394 395 config_interrupts(sc->sc_dev, pxapcic_doattach); 396 } 397 398 void 399 pxapcic_doattach(device_t self) 400 { 401 struct pxapcic_softc *sc = device_private(self); 402 struct pxapcic_socket *sock; 403 int s[PXAPCIC_NSLOT]; 404 int i; 405 u_int cs; 406 407 if (sc->sc_flags & PPF_REVERSE_ORDER) { 408 for (i = 0; i < sc->sc_nslots; i++) { 409 s[i] = sc->sc_nslots - 1 - i; 410 } 411 } else { 412 for (i = 0; i < sc->sc_nslots; i++) { 413 s[i] = i; 414 } 415 } 416 417 for (i = 0; i < sc->sc_nslots; i++) { 418 sock = &sc->sc_socket[s[i]]; 419 420 config_pending_incr(self); 421 422 /* If there's a card there, attach it. */ 423 cs = (*sock->pcictag->read)(sock, PXAPCIC_CARD_STATUS); 424 if (cs == PXAPCIC_CARD_VALID) 425 pxapcic_attach_card(sock); 426 427 if (kthread_create(PRI_NONE, 0, NULL, pxapcic_event_thread, 428 sock, &sock->event_thread, "%s,%d", 429 device_xname(sc->sc_dev), sock->socket)) { 430 aprint_error_dev(sc->sc_dev, 431 "unable to create event thread for %d\n", 432 sock->socket); 433 } 434 } 435 } 436 437 /* 438 * Card slot interrupt handling 439 */ 440 int 441 pxapcic_intr(void *arg) 442 { 443 struct pxapcic_socket *so = (struct pxapcic_socket *)arg; 444 445 (*so->pcictag->clear_intr)(so); 446 wakeup(so); 447 448 return 1; 449 } 450 451 static void 452 pxapcic_event_thread(void *arg) 453 { 454 struct pxapcic_socket *sock = (struct pxapcic_socket *)arg; 455 u_int cs; 456 int present; 457 458 config_pending_decr(sock->sc->sc_dev); 459 460 while (sock->sc->sc_shutdown == 0) { 461 (void) tsleep(sock, PWAIT, "pxapcicev", 0); 462 463 /* sleep .25s to avoid chattering interrupts */ 464 (void) tsleep((void *)sock, PWAIT, "pxapcicss", hz/4); 465 466 cs = (*sock->pcictag->read)(sock, PXAPCIC_CARD_STATUS); 467 present = sock->flags & PXAPCIC_FLAG_CARDP; 468 if ((cs == PXAPCIC_CARD_VALID) == (present == 1)) { 469 continue; /* state unchanged */ 470 } 471 472 /* XXX Do both? */ 473 pxapcic_event_process(sock); 474 } 475 sock->event_thread = NULL; 476 477 /* In case parent is waiting for us to exit. */ 478 wakeup(sock->sc); 479 kthread_exit(0); 480 } 481 482 static void 483 pxapcic_event_process(struct pxapcic_socket *sock) 484 { 485 u_int cs; 486 487 cs = (*sock->pcictag->read)(sock, PXAPCIC_CARD_STATUS); 488 if (cs == PXAPCIC_CARD_VALID) { 489 if (!(sock->flags & PXAPCIC_FLAG_CARDP)) { 490 pxapcic_attach_card(sock); 491 } 492 } else { 493 if ((sock->flags & PXAPCIC_FLAG_CARDP)) { 494 pxapcic_detach_card(sock, DETACH_FORCE); 495 } 496 } 497 } 498 499 static void 500 pxapcic_attach_card(struct pxapcic_socket *h) 501 { 502 struct pxapcic_softc *sc = h->sc; 503 uint32_t reg; 504 505 if (h->flags & PXAPCIC_FLAG_CARDP) 506 panic("pcic_attach_card: already attached"); 507 h->flags |= PXAPCIC_FLAG_CARDP; 508 509 /* Set CIT if any card is present. */ 510 reg = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR); 511 bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR, 512 reg | MECR_CIT); 513 514 /* call the MI attach function */ 515 pcmcia_card_attach(h->pcmcia); 516 } 517 518 static void 519 pxapcic_detach_card(struct pxapcic_socket *h, int flags) 520 { 521 struct pxapcic_softc *sc = h->sc; 522 uint32_t reg; 523 int i; 524 525 if (h->flags & PXAPCIC_FLAG_CARDP) { 526 h->flags &= ~PXAPCIC_FLAG_CARDP; 527 528 /* call the MI detach function */ 529 pcmcia_card_detach(h->pcmcia, flags); 530 } 531 532 /* Clear CIT if no other card is present. */ 533 for (i = 0; i < sc->sc_nslots; i++) { 534 if (sc->sc_socket[i].flags & PXAPCIC_FLAG_CARDP) { 535 return; 536 } 537 } 538 539 reg = bus_space_read_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR); 540 bus_space_write_4(sc->sc_iot, sc->sc_memctl_ioh, MEMCTL_MECR, 541 reg & ~MECR_CIT); 542 } 543