diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-07-01 23:51:56 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2005-07-01 23:51:56 +0000 |
commit | 420968103d6f70617afff7176732e5a22c1e80f2 (patch) | |
tree | 88731b79b91f3c44cbaec77833a1068040792ec3 /sys/arch/arm | |
parent | fcfbf526bc30d43ed9ab3d24457e6abc683e9443 (diff) |
Move all zaurus specific code from pxa2x0_pcic.c into scoop_pcic.c
without affecting the way the driver works.
Diffstat (limited to 'sys/arch/arm')
-rw-r--r-- | sys/arch/arm/xscale/files.pxa2x0 | 3 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_pcic.c | 591 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxapcicvar.h | 82 |
3 files changed, 215 insertions, 461 deletions
diff --git a/sys/arch/arm/xscale/files.pxa2x0 b/sys/arch/arm/xscale/files.pxa2x0 index 76ddf18fc2b..b416567cead 100644 --- a/sys/arch/arm/xscale/files.pxa2x0 +++ b/sys/arch/arm/xscale/files.pxa2x0 @@ -1,4 +1,4 @@ -# $OpenBSD: files.pxa2x0,v 1.15 2005/06/16 21:30:11 uwe Exp $ +# $OpenBSD: files.pxa2x0,v 1.16 2005/07/01 23:51:55 uwe Exp $ # $NetBSD: files.pxa2x0,v 1.6 2004/05/01 19:09:14 thorpej Exp $ # # Configuration info for Intel PXA2[51]0 CPU support @@ -76,7 +76,6 @@ include "dev/pcmcia/files.pcmcia" # PCMCIA controller device pxapcic: pcmciabus -attach pxapcic at pxaip file arch/arm/xscale/pxa2x0_pcic.c pxapcic # XXX this is a hack to use dev/pcmcia without fdc.c diff --git a/sys/arch/arm/xscale/pxa2x0_pcic.c b/sys/arch/arm/xscale/pxa2x0_pcic.c index bd3b5bd073e..944b7599913 100644 --- a/sys/arch/arm/xscale/pxa2x0_pcic.c +++ b/sys/arch/arm/xscale/pxa2x0_pcic.c @@ -1,4 +1,5 @@ -/* $OpenBSD: pxa2x0_pcic.c,v 1.13 2005/04/11 03:38:03 uwe Exp $ */ +/* $OpenBSD: pxa2x0_pcic.c,v 1.14 2005/07/01 23:51:55 uwe Exp $ */ + /* * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org> * @@ -15,7 +16,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/types.h> #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> @@ -36,6 +36,16 @@ #include <arm/xscale/pxa2x0_gpio.h> #include <arm/xscale/pxapcicvar.h> +int pxapcic_print(void *, const char *); +int pxapcic_submatch(struct device *, void *, void *); + +void pxapcic_create_event_thread(void *); +void pxapcic_event_thread(void *); +void pxapcic_event_process(struct pxapcic_socket *); +void pxapcic_attach_card(struct pxapcic_socket *); +void pxapcic_detach_card(struct pxapcic_socket *, int); +int pxapcic_intr(void *); + int pxapcic_mem_alloc(pcmcia_chipset_handle_t, bus_size_t, struct pcmcia_mem_handle *); void pxapcic_mem_free(pcmcia_chipset_handle_t, @@ -43,6 +53,7 @@ void pxapcic_mem_free(pcmcia_chipset_handle_t, int pxapcic_mem_map(pcmcia_chipset_handle_t, int, bus_addr_t, bus_size_t, struct pcmcia_mem_handle *, bus_addr_t *, int *); void pxapcic_mem_unmap(pcmcia_chipset_handle_t, int); + int pxapcic_io_alloc(pcmcia_chipset_handle_t, bus_addr_t, bus_size_t, bus_size_t, struct pcmcia_io_handle *); void pxapcic_io_free(pcmcia_chipset_handle_t, @@ -50,43 +61,23 @@ void pxapcic_io_free(pcmcia_chipset_handle_t, int pxapcic_io_map(pcmcia_chipset_handle_t, int, bus_addr_t, bus_size_t, struct pcmcia_io_handle *, int *); void pxapcic_io_unmap(pcmcia_chipset_handle_t, int); + void *pxapcic_intr_establish(pcmcia_chipset_handle_t, struct pcmcia_function *, int, int (*)(void *), void *, char *); void pxapcic_intr_disestablish(pcmcia_chipset_handle_t, void *); const char *pxapcic_intr_string(pcmcia_chipset_handle_t, void *); -void pxapcic_wait_ready(struct pxapcic_socket *); + +void pxapcic_socket_setup(struct pxapcic_socket *); void pxapcic_socket_enable(pcmcia_chipset_handle_t); void pxapcic_socket_disable(pcmcia_chipset_handle_t); -void pxapcic_event_thread(void *); - -void pxapcic_delay(int, const char *); - -int pxapcic_match(struct device *, void *, void *); -void pxapcic_attach(struct device *, struct device *, void *); -void pxapcic_create_event_thread(void *arg); -int pxapcic_submatch(struct device *parent, void *, void *aux); -int pxapcic_print(void *aux, const char *name); -int pxapcic_intr(void *arg); - -void pxapcic_event_process(struct pxapcic_socket *); - -void pxapcic_attach_card(struct pxapcic_socket *h); -void pxapcic_detach_card(struct pxapcic_socket *h, int flags); - -int pxapcic_intr_detect(void *arg); - -/* DON'T CONFIGURE CF slot 1 for now */ -#define NUM_CF_CARDS 2 - -struct cfattach pxapcic_ca = { - sizeof(struct pxapcic_softc), pxapcic_match, pxapcic_attach -}; - struct cfdriver pxapcic_cd = { NULL, "pxapcic", DV_DULL }; +/* + * PCMCIA chipset methods + */ struct pcmcia_chip_functions pxapcic_pcmcia_functions = { pxapcic_mem_alloc, pxapcic_mem_free, @@ -106,13 +97,13 @@ struct pcmcia_chip_functions pxapcic_pcmcia_functions = { pxapcic_socket_disable, }; - +/* + * PCMCIA Helpers + */ int -pxapcic_mem_alloc(pch, size, pmh) - pcmcia_chipset_handle_t pch; - bus_size_t size; - struct pcmcia_mem_handle *pmh; +pxapcic_mem_alloc(pcmcia_chipset_handle_t pch, bus_size_t size, + struct pcmcia_mem_handle *pmh) { struct pxapcic_socket *so = pch; @@ -123,21 +114,14 @@ pxapcic_mem_alloc(pch, size, pmh) } void -pxapcic_mem_free(pch, pmh) - pcmcia_chipset_handle_t pch; - struct pcmcia_mem_handle *pmh; +pxapcic_mem_free(pcmcia_chipset_handle_t pch, struct pcmcia_mem_handle *pmh) { } int -pxapcic_mem_map(pch, kind, card_addr, size, pmh, offsetp, windowp) - pcmcia_chipset_handle_t pch; - int kind; - bus_addr_t card_addr; - bus_size_t size; - struct pcmcia_mem_handle *pmh; - bus_addr_t *offsetp; - int *windowp; +pxapcic_mem_map(pcmcia_chipset_handle_t pch, int kind, bus_addr_t card_addr, + bus_size_t size, struct pcmcia_mem_handle *pmh, bus_addr_t *offsetp, + int *windowp) { struct pxapcic_socket *so = pch; int error; @@ -173,9 +157,7 @@ pxapcic_mem_map(pch, kind, card_addr, size, pmh, offsetp, windowp) } void -pxapcic_mem_unmap(pch, window) - pcmcia_chipset_handle_t pch; - int window; +pxapcic_mem_unmap(pcmcia_chipset_handle_t pch, int window) { struct pxapcic_socket *so = pch; @@ -183,12 +165,8 @@ pxapcic_mem_unmap(pch, window) } int -pxapcic_io_alloc(pch, start, size, align, pih) - pcmcia_chipset_handle_t pch; - bus_addr_t start; - bus_size_t size; - bus_size_t align; - struct pcmcia_io_handle *pih; +pxapcic_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start, + bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pih) { struct pxapcic_socket *so = pch; int error; @@ -214,9 +192,7 @@ pxapcic_io_alloc(pch, start, size, align, pih) } void -pxapcic_io_free(pch, pih) - pcmcia_chipset_handle_t pch; - struct pcmcia_io_handle *pih; +pxapcic_io_free(pcmcia_chipset_handle_t pch, struct pcmcia_io_handle *pih) { struct pxapcic_socket *so = pch; @@ -224,216 +200,219 @@ pxapcic_io_free(pch, pih) } int -pxapcic_io_map(pch, width, offset, size, pih, windowp) - pcmcia_chipset_handle_t pch; - int width; - bus_addr_t offset; - bus_size_t size; - struct pcmcia_io_handle *pih; - int *windowp; +pxapcic_io_map(pcmcia_chipset_handle_t pch, int width, bus_addr_t offset, + bus_size_t size, struct pcmcia_io_handle *pih, int *windowp) { return (0); } -void pxapcic_io_unmap(pch, window) - pcmcia_chipset_handle_t pch; - int window; +void pxapcic_io_unmap(pcmcia_chipset_handle_t pch, int window) { } void * -pxapcic_intr_establish(pch, pf, ipl, fct, arg, name) - pcmcia_chipset_handle_t pch; - struct pcmcia_function *pf; - int ipl; - int (*fct)(void *); - void *arg; - char *name; +pxapcic_intr_establish(pcmcia_chipset_handle_t pch, + struct pcmcia_function *pf, int ipl, int (*fct)(void *), void *arg, + char *name) { struct pxapcic_socket *so = pch; /* XXX need to check if something should be done here */ - return pxa2x0_gpio_intr_establish(so->irqpin, IST_EDGE_FALLING, - ipl, fct, arg, name); + return (pxa2x0_gpio_intr_establish(so->irqpin, IST_EDGE_FALLING, + ipl, fct, arg, name)); } void -pxapcic_intr_disestablish(pch, ih) - pcmcia_chipset_handle_t pch; - void *ih; +pxapcic_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih) { pxa2x0_gpio_intr_disestablish(ih); } const char * -pxapcic_intr_string(pch, ih) - pcmcia_chipset_handle_t pch; - void *ih; -{ - return pxa2x0_gpio_intr_string(ih); -} - -void -pxapcic_wait_ready(so) - struct pxapcic_socket *so; +pxapcic_intr_string(pcmcia_chipset_handle_t pch, void *ih) { - bus_space_tag_t iot = so->sc->sc_iot; - int i; - - for (i = 0; i < 10000; i++) { - if (bus_space_read_2(iot, so->scooph, SCOOP_REG_CSR) & - SCP_CSR_READY) - return; - delay(500); -#ifdef PCICDEBUG - if ((i>5000) && (i%100 == 99)) - printf("."); -#endif - } - -#ifdef DIAGNOSTIC - printf("pxapcic_wait_ready: ready never happened, status = %02x\n", - bus_space_read_2(iot, so->scooph, SCOOP_REG_CSR)); -#endif + return (pxa2x0_gpio_intr_string(ih)); } void -pxapcic_socket_enable(pch) - pcmcia_chipset_handle_t pch; +pxapcic_socket_enable(pcmcia_chipset_handle_t pch) { struct pxapcic_socket *so = pch; - bus_space_tag_t iot = so->sc->sc_iot; - u_int16_t reg; - -#ifdef PCICDEBUG - printf("pxapcic_socket_enable: socket %d\n", so->socket); -#endif - - /* XXX fix scoop1 base address before trying that. */ - if (so->socket == 1) - return; - - /* XXX bit 2 was clear on boot with card preconfigured. */ - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_IRM); - bus_space_write_2(iot, so->scooph, SCOOP_REG_IRM, reg & ~0x0004); - - /* Enable CF socket 0 power. */ - if (so->socket == 0) { - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_GPWR); - bus_space_write_2(iot, so->scooph, SCOOP_REG_GPWR, - reg | (1<<6)); /* SCOOP0_CF_POWER_C3000 */ - } + int i; - /* XXX */ - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_CPR); - reg = reg & ~(SCP_CPR_PWR|SCP_CPR_5V|SCP_CPR_3V); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg); + /* Power down the card and socket before setting the voltage. */ + so->pcictag->write(so, PXAPCIC_CARD_POWER, PXAPCIC_POWER_OFF); + so->pcictag->set_power(so, PXAPCIC_POWER_OFF); /* - * wait 300ms until power fails (Tpf). Then, wait 100ms since + * Wait 300ms until power fails (Tpf). Then, wait 100ms since * we are changing Vcc (Toff). */ delay((300 + 100) * 1000); - /* Socket 1 supports only 5 V (which really is 3.3) for C3000? */ - reg = reg | (SCP_CPR_PWR|SCP_CPR_5V); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg); + /* Power up the socket and card at appropriate voltage. */ + if (so->power_capability & PXAPCIC_POWER_5V) { + so->pcictag->set_power(so, PXAPCIC_POWER_5V); + so->pcictag->write(so, PXAPCIC_CARD_POWER, + PXAPCIC_POWER_5V); + } else { + so->pcictag->set_power(so, PXAPCIC_POWER_3V); + so->pcictag->write(so, PXAPCIC_CARD_POWER, + PXAPCIC_POWER_3V); + } /* - * wait 100ms until power raise (Tpr) and 20ms to become + * Wait 100ms until power raise (Tpr) and 20ms to become * stable (Tsu(Vcc)). * - * some machines require some more time to be settled + * Some machines require some more time to be settled * (another 200ms is added here). */ delay((100 + 20 + 200) * 1000); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CCR, SCP_CCR_RESET); + /* Hold RESET at least 10us. */ + so->pcictag->write(so, PXAPCIC_CARD_RESET, 1); delay(10); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CCR, 0); - + so->pcictag->write(so, PXAPCIC_CARD_RESET, 0); - /* wait 20ms as per pc card standard (r2.01) section 4.3.6 */ - + /* Wait 20ms as per PC Card standard (r2.01) section 4.3.6. */ delay(20000); - pxapcic_wait_ready(so); - -#if 0 - printf("cardtype %d\n", h->pcmcia); + /* Wait for the card to become ready. */ + for (i = 0; i < 10000; i++) { + if (so->pcictag->read(so, PXAPCIC_CARD_READY)) + break; + delay(500); +#ifdef PCICDEBUG + if ((i>5000) && (i%100 == 99)) + printf("."); #endif + } } void -pxapcic_socket_disable(pch) - pcmcia_chipset_handle_t pch; +pxapcic_socket_disable(pcmcia_chipset_handle_t pch) { struct pxapcic_socket *so = pch; - bus_space_tag_t iot = so->sc->sc_iot; - u_int16_t reg; #ifdef PCICDEBUG printf("pxapcic_socket_disable: socket %d\n", so->socket); #endif - /* XXX fix scoop1 base address before trying that. */ - if (so->socket == 1) - return; + /* Power down the card and socket. */ + so->pcictag->write(so, PXAPCIC_CARD_POWER, PXAPCIC_POWER_OFF); + so->pcictag->set_power(so, PXAPCIC_POWER_OFF); +} - /* XXX */ - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_CPR); - reg = reg & ~(SCP_CPR_PWR|SCP_CPR_5V|SCP_CPR_3V); - bus_space_write_2(iot, so->scooph, SCOOP_REG_CPR, reg); +/* + * Attachment and initialization + */ - /* Disable CF socket 0 power. */ - if (so->socket == 0) { - reg = bus_space_read_2(iot, so->scooph, SCOOP_REG_GPWR); - bus_space_write_2(iot, so->scooph, SCOOP_REG_GPWR, - reg & ~(1<<6)); /* SCOOP0_CF_POWER_C3000 */ - } +int +pxapcic_print(void *aux, const char *name) +{ + return (UNCONF); } -#if 0 -void -pxapcic_socket_settype(pch, type) - pcmcia_chipset_handle_t pch; - int type; +int +pxapcic_submatch(struct device *parent, void *match, void *aux) { + struct cfdata *cf = match; - /* XXX */ + return ((*cf->cf_attach->ca_match)(parent, cf, aux)); } -#endif -#if 0 void -pxapcic_socket_setup(struct pxapcic_socket *sp) +pxapcic_attach(struct pxapcic_softc *sc, + void (*socket_setup_hook)(struct pxapcic_socket *)) { - /* - sp->power_capability = PXAPCIC_POWER_3V; - */ - sp->pcictag = &pxapcic_sacpcic_functions; -} -#endif + struct pcmciabus_attach_args paa; + struct pxapcic_socket *so; + int i; -#if 0 -void -pxapcic_set_power(struct pxapcic_socket *so, int arg) -{ - /* 3 volt only, not supported - XXX */ -} + printf(": %d slot%s\n", sc->sc_nslots, sc->sc_nslots==1 ? "" : "s"); + + /* zaurus: configure slot 1 first to make internal drive be wd0. */ + for (i = sc->sc_nslots-1; i >= 0; i--) { + so = &sc->sc_socket[i]; + so->sc = sc; + so->socket = i; + so->flags = 0; + + socket_setup_hook(so); + paa.paa_busname = "pcmcia"; + paa.pct = (pcmcia_chipset_tag_t)&pxapcic_pcmcia_functions; + paa.pch = (pcmcia_chipset_handle_t)so; + paa.iobase = 0; + paa.iosize = 0x4000000; + + so->pcmcia = config_found_sm(&sc->sc_dev, &paa, + pxapcic_print, pxapcic_submatch); + + pxa2x0_gpio_set_function(sc->sc_irqpin[i], GPIO_IN); + pxa2x0_gpio_set_function(sc->sc_irqcfpin[i], GPIO_IN); + + /* Card slot interrupt */ + so->irq = pxa2x0_gpio_intr_establish(sc->sc_irqcfpin[i], + IST_EDGE_BOTH, IPL_BIO /* XXX */, pxapcic_intr, so, + sc->sc_dev.dv_xname); + + /* GPIO pin for interrupt */ + so->irqpin = sc->sc_irqpin[i]; + +#ifdef DO_CONFIG_PENDING + config_pending_incr(); #endif + kthread_create_deferred(pxapcic_create_event_thread, so); + } +} + +/* + * Card slot interrupt handling + */ + int -pxapcic_match(struct device *parent, void *v, void *aux) +pxapcic_intr(void *arg) { + struct pxapcic_socket *so = arg; + + so->pcictag->clear_intr(so); + wakeup(so); return (1); -} +} + +/* + * Event management + */ + +void +pxapcic_create_event_thread(void *arg) +{ + struct pxapcic_socket *sock = arg; + struct pxapcic_softc *sc = sock->sc; + u_int cs; + + /* If there's a card there, attach it. */ + cs = sock->pcictag->read(sock, PXAPCIC_CARD_STATUS); + if (cs == PXAPCIC_CARD_VALID) + pxapcic_attach_card(sock); + + if (kthread_create(pxapcic_event_thread, sock, &sock->event_thread, + sc->sc_dev.dv_xname, sock->socket ? "1" : "0")) { + printf("%s: unable to create event thread for %s\n", + sc->sc_dev.dv_xname, sock->socket ? "1" : "0"); + } +#ifdef DO_CONFIG_PENDING + config_pending_decr(); +#endif +} void pxapcic_event_thread(void *arg) { struct pxapcic_socket *sock = arg; - u_int16_t csr; + u_int cs; int present; while (sock->sc->sc_shutdown == 0) { @@ -444,12 +423,11 @@ pxapcic_event_thread(void *arg) (void) tsleep((caddr_t)sock, PWAIT, "pxapcicss", hz/4); - csr = bus_space_read_2(sock->sc->sc_iot, sock->scooph, - SCOOP_REG_CSR); + cs = sock->pcictag->read(sock, PXAPCIC_CARD_STATUS); present = sock->flags & PXAPCIC_FLAG_CARDP; - if (((csr & SCP_CSR_MISSING) == 0) == (present == 1)) + if ((cs == PXAPCIC_CARD_VALID) == (present == 1)) continue; /* state unchanged */ /* XXX Do both? */ @@ -465,6 +443,22 @@ pxapcic_event_thread(void *arg) } void +pxapcic_event_process(struct pxapcic_socket *sock) +{ + u_int cs; + + cs = sock->pcictag->read(sock, PXAPCIC_CARD_STATUS); + + if (cs == PXAPCIC_CARD_VALID) { + if (!(sock->flags & PXAPCIC_FLAG_CARDP)) + pxapcic_attach_card(sock); + } else { + if ((sock->flags & PXAPCIC_FLAG_CARDP)) + pxapcic_detach_card(sock, DETACH_FORCE); + } +} + +void pxapcic_attach_card(struct pxapcic_socket *h) { if (h->flags & PXAPCIC_FLAG_CARDP) @@ -483,218 +477,5 @@ pxapcic_detach_card(struct pxapcic_socket *h, int flags) /* call the MI detach function */ pcmcia_card_detach(h->pcmcia, flags); - } else { - //DPRINTF(("pcic_detach_card: already detached")); - } -} - - -void pxapcic_event_process_st(void *h); -void -pxapcic_event_process_st(void *v) -{ - struct pxapcic_socket *h = v; - pxapcic_event_process(h); -} -void -pxapcic_event_process(sock) - struct pxapcic_socket *sock; -{ - struct pxapcic_softc *sc = sock->sc; - u_int16_t csr; - - csr = bus_space_read_2(sc->sc_iot, sock->scooph, SCOOP_REG_CSR); - - switch (csr & SCP_CSR_MISSING) { - case 0: /* PRESENT */ - //DPRINTF(("%s: insertion event\n", sock->sc->dv_xname)); - if (!(sock->flags & PXAPCIC_FLAG_CARDP)) - pxapcic_attach_card(sock); - break; - - case SCP_CSR_MISSING: - //DPRINTF(("%s: removal event\n", sock->sc->dv_xname)); - if ((sock->flags & PXAPCIC_FLAG_CARDP)) - pxapcic_detach_card(sock, DETACH_FORCE); - break; - } -} - -void -pxapcic_create_event_thread(void *arg) -{ - struct pxapcic_socket *sock = arg; - struct pxapcic_softc *sc = sock->sc; - u_int16_t csr; - - csr = bus_space_read_2(sc->sc_iot, sock->scooph, SCOOP_REG_CSR); - - /* if there's a card there, attach it */ - - switch (csr & SCP_CSR_MISSING) { - case 0: /* PRESENT */ - pxapcic_attach_card(sock); - break; - default: - ; - } - - if (kthread_create(pxapcic_event_thread, sock, &sock->event_thread, - sc->sc_dev.dv_xname, sock->socket ? "1" : "0")) { - printf("%s: unable to create event thread for %s\n", - sc->sc_dev.dv_xname, sock->socket ? "1" : "0"); - } -#ifdef DO_CONFIG_PENDING - config_pending_decr(); -#endif -} - -int -pxapcic_submatch(struct device *parent, void *match, void *aux) -{ - struct cfdata *cf = match; - - return ((*cf->cf_attach->ca_match)(parent, cf, aux)); - -} - -int -pxapcic_print(void *aux, const char *name) -{ - return (UNCONF); -} - - -void -pxapcic_attach(struct device *parent, struct device *self, void *aux) -{ - struct pcmciabus_attach_args paa; - struct pxapcic_softc *sc = (struct pxapcic_softc *)self; - struct pxaip_attach_args *pxa = aux; - struct pxapcic_socket *so; - bus_space_tag_t iot; - bus_space_handle_t scooph; - int i; - int error; - bus_addr_t pa; - bus_size_t size = 0x100; - - iot = sc->sc_iot = pxa->pxa_iot; - - sc->sc_shutdown = 0; - - printf("\n"); - - /* - * should be model based not processor based, and in zaurus/... - * not arm/xscale - */ - if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X) { -#define C3000_CF0_IRQ 105 -#define C3000_CF1_IRQ 106 -#define C3000_CF0_CD 94 -#define C3000_CF1_CD 93 - sc->sc_nslots = 2; - sc->sc_irqpin[0] = C3000_CF0_IRQ; - sc->sc_irqcfpin[0] = C3000_CF0_CD; - sc->sc_irqpin[1] = C3000_CF1_IRQ; - sc->sc_irqcfpin[1] = C3000_CF1_CD; - } else { -#define C860_CF0_IRQ 17 -#define C860_CF0_CD 14 - /* C860 */ - sc->sc_nslots = 1; - sc->sc_irqpin[0] = C860_CF0_IRQ; - sc->sc_irqcfpin[0] = C860_CF0_CD; } - - for(i = 0; i < NUM_CF_CARDS; i++) { - so = &sc->sc_socket[i]; - so->sc = sc; - so->socket = i; - so->flags = 0; - - /* scoop? */ - if (so->socket == 0) - pa = 0x10800000; - else if (so->socket == 1) - pa = 0x14800000; /* 0x08800040 */ - else { - printf ("%s: invalid CF slot %d\n", sc->sc_dev.dv_xname, - i); - continue; - } - error = bus_space_map(iot, pa, size, 0, &scooph); - if (error) { - printf ("%s%d: failed to map memory %x for scoop\n", - sc->sc_dev.dv_xname, i, pa); - continue; - } - so->scooph = scooph; - - bus_space_write_2(iot, scooph, SCOOP_REG_IMR, 0x00c0); - - /* setup */ - bus_space_write_2(iot, scooph, SCOOP_REG_MCR, 0x0100); - bus_space_write_2(iot, scooph, SCOOP_REG_CDR, 0x0000); - bus_space_write_2(iot, scooph, SCOOP_REG_CPR, 0x0000); - bus_space_write_2(iot, scooph, SCOOP_REG_IMR, 0x0000); - bus_space_write_2(iot, scooph, SCOOP_REG_IRM, 0x00ff); - bus_space_write_2(iot, scooph, SCOOP_REG_ISR, 0x0000); - bus_space_write_2(iot, scooph, SCOOP_REG_IRM, 0x0000); - - bus_space_write_2(iot, scooph, SCOOP_REG_CPR, - SCP_CPR_PWR|SCP_CPR_5V); /* 5 V for 3000? */ - - - paa.paa_busname = "pcmcia"; - paa.pct = (pcmcia_chipset_tag_t) &pxapcic_pcmcia_functions; - paa.pch = (pcmcia_chipset_handle_t)&sc->sc_socket[i]; - paa.iobase = 0; - paa.iosize = 0x4000000; - - so->pcmcia = config_found_sm(&sc->sc_dev, &paa, pxapcic_print, - pxapcic_submatch); - } - - /* configure slot 1 first to make internal drive be wd0 */ - for (i = sc->sc_nslots-1; i >= 0; i--) { - so = &sc->sc_socket[i]; - pxa2x0_gpio_set_function(sc->sc_irqpin[i], GPIO_IN); - pxa2x0_gpio_set_function(sc->sc_irqcfpin[i], GPIO_IN); - - sc->sc_socket[i].irq = pxa2x0_gpio_intr_establish( - sc->sc_irqcfpin[i], - IST_EDGE_BOTH, IPL_BIO /* XXX */, pxapcic_intr_detect, - so, sc->sc_dev.dv_xname); - - /* GPIO pin for interrupt */ - sc->sc_socket[i].irqpin = sc->sc_irqpin[i]; - - bus_space_write_2(iot, so->scooph, SCOOP_REG_IMR, 0x00ce); - bus_space_write_2(iot, so->scooph, SCOOP_REG_MCR, 0x0111); - -#ifdef DO_CONFIG_PENDING - config_pending_incr(); -#endif - kthread_create_deferred(pxapcic_create_event_thread, so); - } -} - -int -pxapcic_intr_detect(void *arg) -{ - struct pxapcic_socket *so = arg; - bus_space_tag_t iot; - - iot = so->sc->sc_iot; - - /* - (so->pcictag->clear_intr)(so->socket); - */ - bus_space_write_2(iot, so->scooph, SCOOP_REG_IRM, 0x00ff); - bus_space_write_2(iot, so->scooph, SCOOP_REG_ISR, 0x0000); - bus_space_write_2(iot, so->scooph, SCOOP_REG_IRM, 0x0000); - wakeup(so); - return 1; } diff --git a/sys/arch/arm/xscale/pxapcicvar.h b/sys/arch/arm/xscale/pxapcicvar.h index d1f8654b02e..fc7e9a78591 100644 --- a/sys/arch/arm/xscale/pxapcicvar.h +++ b/sys/arch/arm/xscale/pxapcicvar.h @@ -1,4 +1,5 @@ -/* $OpenBSD: pxapcicvar.h,v 1.5 2005/02/23 00:08:16 drahn Exp $ */ +/* $OpenBSD: pxapcicvar.h,v 1.6 2005/07/01 23:51:55 uwe Exp $ */ + /* * Copyright (c) 2005 Dale Rahn <drahn@openbsd.org> * @@ -17,39 +18,49 @@ struct pxapcic_socket { struct pxapcic_softc *sc; - int socket; /* socket number */ + int socket; /* socket number */ struct device *pcmcia; struct proc *event_thread; - bus_space_handle_t scooph; - int flags; + int power_capability; /* PXAPCIC_POWER_3V | PXAPCIC_POWER_5V */ - int power_capability; int irqpin; void *irq; - void *pcictag_cookie; /* opaque data for pcictag functions */ + void *pcictag_cookie; /* opaque data for pcictag functions */ + struct pxapcic_tag *pcictag; }; /* event */ -#define PXAPCIC_EVENT_INSERTION 0 -#define PXAPCIC_EVENT_REMOVAL 1 +#define PXAPCIC_EVENT_INSERTION 0 +#define PXAPCIC_EVENT_REMOVAL 1 -/* laststatus */ -#define PXAPCIC_FLAG_CARDD 0 -#define PXAPCIC_FLAG_CARDP 1 +/* flags */ +#define PXAPCIC_FLAG_CARDD 0 +#define PXAPCIC_FLAG_CARDP 1 struct pxapcic_tag { - int (*read)(struct pxapcic_socket *, int); - void (*write)(struct pxapcic_socket *, int, int); + u_int (*read)(struct pxapcic_socket *, int); + void (*write)(struct pxapcic_socket *, int, u_int); void (*set_power)(struct pxapcic_socket *, int); - void (*clear_intr)(int); + void (*clear_intr)(struct pxapcic_socket *); void *(*intr_establish)(struct pxapcic_socket *, int, int (*)(void *), void *); void (*intr_disestablish)(struct pxapcic_socket *, void *); + const char *(*intr_string)(struct pxapcic_socket *); }; +/* pcictag registers and their values */ +#define PXAPCIC_CARD_STATUS 0 +#define PXAPCIC_CARD_INVALID 0 +#define PXAPCIC_CARD_VALID 1 +#define PXAPCIC_CARD_READY 1 +#define PXAPCIC_CARD_POWER 2 +#define PXAPCIC_POWER_OFF 0 +#define PXAPCIC_POWER_3V 1 +#define PXAPCIC_POWER_5V 2 +#define PXAPCIC_CARD_RESET 3 struct pxapcic_softc { struct device sc_dev; @@ -64,43 +75,6 @@ struct pxapcic_softc { int sc_irqcfpin[2]; }; - -#define SCOOP_REG_MCR 0x00 -#define SCOOP_REG_CDR 0x04 -#define SCOOP_REG_CSR 0x08 -#define SCOOP_REG_CPR 0x0C -#define SCOOP_REG_CCR 0x10 -#define SCOOP_REG_IRR 0x14 -#define SCOOP_REG_IRM 0x14 -#define SCOOP_REG_IMR 0x18 -#define SCOOP_REG_ISR 0x1C -#define SCOOP_REG_GPCR 0x20 -#define SCOOP_REG_GPWR 0x24 -#define SCOOP_REG_GPRR 0x28 - -#define SCP_CDR_DETECT 0x0002 - -#define SCP_CSR_READY 0x0002 -#define SCP_CSR_MISSING 0x0004 -#define SCP_CSR_WPROT 0x0008 -#define SCP_CSR_BVD1 0x0010 -#define SCP_CSR_BVD2 0x0020 -#define SCP_CSR_3V 0x0040 -#define SCP_CSR_PWR 0x0080 - -#define SCP_CPR_OFF 0x0000 -#define SCP_CPR_3V 0x0001 -#define SCP_CPR_5V 0x0002 -#define SCP_CPR_PWR 0x0080 - - -#define SCP_MCR_IOCARD 0x0010 -#define SCP_CCR_RESET 0x0080 - -#define SCP_IMR_READY 0x0002 -#define SCP_IMR_DETECT 0x0004 -#define SCP_IMR_WRPROT 0x0008 -#define SCP_IMR_STSCHG 0x0010 -#define SCP_IMR_BATWARN 0x0020 -#define SCP_IMR_UNKN0 0x0040 -#define SCP_IMR_UNKN1 0x0080 +void pxapcic_attach(struct pxapcic_softc *, + void (*socket_setup_hook)(struct pxapcic_socket *)); +int pxapcic_intr(void *); |