[BACK]Return to scoop_pcic.c CVS log [TXT][DIR] Up to [local] / sys / arch / zaurus / dev

Annotation of sys/arch/zaurus/dev/scoop_pcic.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: scoop_pcic.c,v 1.1 2005/07/01 23:51:55 uwe Exp $      */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
        !             5:  *
        !             6:  * Permission to use, copy, modify, and distribute this software for any
        !             7:  * purpose with or without fee is hereby granted, provided that the above
        !             8:  * copyright notice and this permission notice appear in all copies.
        !             9:  *
        !            10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !            11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            17:  */
        !            18:
        !            19: #include <sys/param.h>
        !            20: #include <sys/systm.h>
        !            21: #include <uvm/uvm.h>
        !            22:
        !            23: #include <arch/arm/xscale/pxa2x0var.h>
        !            24: #include <arch/arm/xscale/pxapcicvar.h>
        !            25:
        !            26: #include <machine/zaurus_reg.h>
        !            27: #include <machine/zaurus_var.h>
        !            28:
        !            29: #include <zaurus/dev/zaurus_scoopreg.h>
        !            30:
        !            31: int    scoop_pcic_match(struct device *, void *, void *);
        !            32: void   scoop_pcic_attach(struct device *, struct device *, void *);
        !            33: void   scoop_pcic_socket_setup(struct pxapcic_socket *);
        !            34:
        !            35: struct cfattach pxapcic_scoop_ca = {
        !            36:        sizeof(struct pxapcic_softc), scoop_pcic_match,
        !            37:        scoop_pcic_attach
        !            38: };
        !            39:
        !            40: u_int  scoop_pcic_read(struct pxapcic_socket *, int);
        !            41: void   scoop_pcic_write(struct pxapcic_socket *, int, u_int);
        !            42: void   scoop_pcic_set_power(struct pxapcic_socket *, int);
        !            43: void   scoop_pcic_clear_intr(struct pxapcic_socket *);
        !            44:
        !            45: struct pxapcic_tag scoop_pcic_functions = {
        !            46:        scoop_pcic_read,
        !            47:        scoop_pcic_write,
        !            48:        scoop_pcic_set_power,
        !            49:        scoop_pcic_clear_intr,
        !            50:        0,                      /* intr_establish */
        !            51:        0,                      /* intr_disestablish */
        !            52:        0                       /* intr_string */
        !            53: };
        !            54:
        !            55: int
        !            56: scoop_pcic_match(struct device *parent, void *cf, void *aux)
        !            57: {
        !            58:        return (ZAURUS_ISC860 || ZAURUS_ISC3000);
        !            59: }
        !            60:
        !            61: void
        !            62: scoop_pcic_attach(struct device *parent, struct device *self, void *aux)
        !            63: {
        !            64:        struct pxapcic_softc *sc = (struct pxapcic_softc *)self;
        !            65:        struct pxaip_attach_args *pxa = aux;
        !            66:
        !            67:        sc->sc_iot = pxa->pxa_iot;
        !            68:
        !            69:        if (ZAURUS_ISC860) {
        !            70:                sc->sc_nslots = 1;
        !            71:                sc->sc_irqpin[0] = C860_CF0_IRQ;
        !            72:                sc->sc_irqcfpin[0] = C860_CF0_IRQ_PIN;
        !            73:        } else if (ZAURUS_ISC3000) {
        !            74:                sc->sc_nslots = 2;
        !            75:                sc->sc_irqpin[0] = C3000_CF0_IRQ;
        !            76:                sc->sc_irqcfpin[0] = C3000_CF0_IRQ_PIN;
        !            77:                sc->sc_irqpin[1] = C3000_CF1_IRQ;
        !            78:                sc->sc_irqcfpin[1] = C3000_CF1_IRQ_PIN;
        !            79:        }
        !            80:
        !            81:        pxapcic_attach(sc, &scoop_pcic_socket_setup);
        !            82: }
        !            83:
        !            84: void
        !            85: scoop_pcic_socket_setup(struct pxapcic_socket *so)
        !            86: {
        !            87:        struct pxapcic_softc *sc;
        !            88:        bus_addr_t pa;
        !            89:        bus_size_t size = SCOOP_SIZE;
        !            90:        bus_space_tag_t iot;
        !            91:        bus_space_handle_t scooph;
        !            92:        int error;
        !            93:
        !            94:        sc = so->sc;
        !            95:        iot = sc->sc_iot;
        !            96:
        !            97:        if (so->socket == 0)
        !            98:                pa = C3000_SCOOP0_BASE;
        !            99:        else if (so->socket == 1)
        !           100:                pa = C3000_SCOOP1_BASE;
        !           101:        else
        !           102:                panic("%s: invalid CF slot %d", sc->sc_dev.dv_xname,
        !           103:                    so->socket);
        !           104:        error = bus_space_map(iot, trunc_page(pa), round_page(size),
        !           105:            0, &scooph);
        !           106:        if (error)
        !           107:                panic("%s: failed to map memory %x for scoop",
        !           108:                    sc->sc_dev.dv_xname, pa);
        !           109:        scooph += pa - trunc_page(pa);
        !           110:
        !           111:        bus_space_write_2(iot, scooph, SCOOP_IMR,
        !           112:            SCP_IMR_UNKN0 | SCP_IMR_UNKN1);
        !           113:
        !           114:        /* setup */
        !           115:        bus_space_write_2(iot, scooph, SCOOP_MCR, 0x0100);
        !           116:        bus_space_write_2(iot, scooph, SCOOP_CDR, 0x0000);
        !           117:        bus_space_write_2(iot, scooph, SCOOP_CPR, 0x0000);
        !           118:        bus_space_write_2(iot, scooph, SCOOP_IMR, 0x0000);
        !           119:        bus_space_write_2(iot, scooph, SCOOP_IRM, 0x00ff);
        !           120:        bus_space_write_2(iot, scooph, SCOOP_ISR, 0x0000);
        !           121:        bus_space_write_2(iot, scooph, SCOOP_IRM, 0x0000);
        !           122:
        !           123:        /* C3000 */
        !           124:        if (so->socket == 1) {
        !           125:                bus_space_write_2(iot, scooph, SCOOP_CPR, 0x80c1);
        !           126:                bus_space_write_2(iot, scooph, SCOOP_IMR, 0x00c4);
        !           127:                bus_space_write_2(iot, scooph, SCOOP_MCR, 0x0111);
        !           128:        } else {
        !           129:                bus_space_write_2(iot, scooph, SCOOP_CPR,
        !           130:                    SCP_CPR_PWR|SCP_CPR_5V);
        !           131:        }
        !           132:
        !           133:        bus_space_write_2(iot, scooph, SCOOP_IMR, 0x00ce);
        !           134:        bus_space_write_2(iot, scooph, SCOOP_MCR, 0x0111);
        !           135:
        !           136:        /* C3000 */
        !           137:        so->power_capability = PXAPCIC_POWER_3V;
        !           138:        if (so->socket == 0)
        !           139:                so->power_capability |= PXAPCIC_POWER_5V;
        !           140:
        !           141:        so->pcictag_cookie = (void *)scooph;
        !           142:        so->pcictag = &scoop_pcic_functions;
        !           143: }
        !           144:
        !           145: u_int
        !           146: scoop_pcic_read(struct pxapcic_socket *so, int reg)
        !           147: {
        !           148:        bus_space_tag_t iot = so->sc->sc_iot;
        !           149:        bus_space_handle_t ioh = (bus_space_handle_t)so->pcictag_cookie;
        !           150:        u_int16_t csr;
        !           151:
        !           152:        csr = bus_space_read_2(iot, ioh, SCOOP_CSR);
        !           153:
        !           154:        switch (reg) {
        !           155:        case PXAPCIC_CARD_STATUS:
        !           156:                if (csr & SCP_CSR_MISSING)
        !           157:                        return (PXAPCIC_CARD_INVALID);
        !           158:                else
        !           159:                        return (PXAPCIC_CARD_VALID);
        !           160:
        !           161:        case PXAPCIC_CARD_READY:
        !           162:                return ((bus_space_read_2(iot, ioh, SCOOP_CSR) &
        !           163:                    SCP_CSR_READY) != 0);
        !           164:
        !           165:        default:
        !           166:                panic("scoop_pcic_read: bogus register");
        !           167:        }
        !           168: }
        !           169:
        !           170: void
        !           171: scoop_pcic_write(struct pxapcic_socket *so, int reg, u_int val)
        !           172: {
        !           173:        bus_space_tag_t iot = so->sc->sc_iot;
        !           174:        bus_space_handle_t ioh = (bus_space_handle_t)so->pcictag_cookie;
        !           175:        u_int16_t newval;
        !           176:        int s;
        !           177:
        !           178:        s = splhigh();
        !           179:
        !           180:        switch (reg) {
        !           181:        case PXAPCIC_CARD_POWER:
        !           182:                newval = bus_space_read_2(iot, ioh, SCOOP_CPR);
        !           183:                newval &= ~(SCP_CPR_PWR | SCP_CPR_3V | SCP_CPR_5V);
        !           184:
        !           185:                if (val == PXAPCIC_POWER_3V)
        !           186:                        newval |= (SCP_CPR_PWR | SCP_CPR_3V);
        !           187:                else if (val == PXAPCIC_POWER_5V)
        !           188:                        newval |= (SCP_CPR_PWR | SCP_CPR_5V);
        !           189:
        !           190:                bus_space_write_2(iot, ioh, SCOOP_CPR, newval);
        !           191:                break;
        !           192:
        !           193:        case PXAPCIC_CARD_RESET:
        !           194:                bus_space_write_2(iot, ioh, SCOOP_CCR,
        !           195:                    val ? SCP_CCR_RESET : 0);
        !           196:                break;
        !           197:
        !           198:        default:
        !           199:                panic("scoop_pcic_write: bogus register");
        !           200:        }
        !           201:
        !           202:        splx(s);
        !           203: }
        !           204:
        !           205: void
        !           206: scoop_pcic_set_power(struct pxapcic_socket *so, int pwr)
        !           207: {
        !           208:        bus_space_tag_t iot = so->sc->sc_iot;
        !           209:        bus_space_handle_t ioh = (bus_space_handle_t)so->pcictag_cookie;
        !           210:        u_int16_t reg;
        !           211:        int s;
        !           212:
        !           213:        s = splhigh();
        !           214:
        !           215:        switch (pwr) {
        !           216:        case PXAPCIC_POWER_OFF:
        !           217: #if 0
        !           218:                /* XXX does this disable power to both sockets? */
        !           219:                reg = bus_space_read_2(iot, ioh, SCOOP_GPWR);
        !           220:                bus_space_write_2(iot, ioh, SCOOP_GPWR,
        !           221:                    reg & ~(1 << SCOOP0_CF_POWER_C3000));
        !           222: #endif
        !           223:                break;
        !           224:
        !           225:        case PXAPCIC_POWER_3V:
        !           226:        case PXAPCIC_POWER_5V:
        !           227:                /* XXX */
        !           228:                if (so->socket == 0) {
        !           229:                        reg = bus_space_read_2(iot, ioh, SCOOP_GPWR);
        !           230:                        bus_space_write_2(iot, ioh, SCOOP_GPWR,
        !           231:                            reg | (1 << SCOOP0_CF_POWER_C3000));
        !           232:                }
        !           233:                break;
        !           234:
        !           235:        default:
        !           236:                splx(s);
        !           237:                panic("scoop_pcic_set_power: bogus power state");
        !           238:        }
        !           239:
        !           240:        splx(s);
        !           241: }
        !           242:
        !           243: void
        !           244: scoop_pcic_clear_intr(struct pxapcic_socket *so)
        !           245: {
        !           246:        bus_space_tag_t iot = so->sc->sc_iot;
        !           247:        bus_space_handle_t ioh = (bus_space_handle_t)so->pcictag_cookie;
        !           248:
        !           249:        bus_space_write_2(iot, ioh, SCOOP_IRM, 0x00ff);
        !           250:        bus_space_write_2(iot, ioh, SCOOP_ISR, 0x0000);
        !           251:        bus_space_write_2(iot, ioh, SCOOP_IRM, 0x0000);
        !           252: }

CVSweb