Date: Thu, 28 Sep 2006 19:56:44 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 106847 for review Message-ID: <200609281956.k8SJuiZX042086@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=106847 Change 106847 by imp@imp_lighthouse on 2006/09/28 19:56:17 Make non-data command transfers actually work in interrupt mode. Oops. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91_mci.c#9 edit .. //depot/projects/arm/src/sys/arm/at91/at91_mcireg.h#5 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91_mci.c#9 (text+ko) ==== @@ -74,6 +74,7 @@ int wire4; int bus_busy; struct mmc_request *req; + struct mmc_command *curcmd; }; static inline uint32_t @@ -108,6 +109,20 @@ #define AT91_MCI_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); static void +at91_mci_pdc_disable(struct at91_mci_softc *sc) +{ + WR4(sc, PDC_PTCR, PDC_PTCR_TXTDIS | PDC_PTCR_RXTDIS); + WR4(sc, PDC_RPR, 0); + WR4(sc, PDC_RCR, 0); + WR4(sc, PDC_RNPR, 0); + WR4(sc, PDC_RNCR, 0); + WR4(sc, PDC_TPR, 0); + WR4(sc, PDC_TCR, 0); + WR4(sc, PDC_TNPR, 0); + WR4(sc, PDC_TNCR, 0); +} + +static void at91_mci_init(device_t dev) { struct at91_mci_softc *sc = device_get_softc(dev); @@ -125,6 +140,7 @@ struct at91_mci_softc *sc = device_get_softc(dev); WR4(sc, MCI_IDR, 0xffffffff); /* Turn off interrupts */ + at91_mci_pdc_disable(sc); WR4(sc, MCI_CR, MCI_CR_MCIDIS | MCI_CR_SWRST); /* Put the device into reset */ } @@ -292,7 +308,47 @@ static void at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd) { - // XXX + uint32_t cmdr; + + sc->curcmd = cmd; + cmdr = cmd->opcode; + if (MMC_RSP(cmd->flags) == MMC_RSP_NONE) + cmdr |= MCI_CMDR_RSPTYP_NO; + else { + /* Allow big timeout for responses */ + cmdr |= MCI_CMDR_MAXLAT; + if (cmd->flags & MMC_RSP_136) + cmdr |= MCI_CMDR_RSPTYP_136; + else + cmdr |= MCI_CMDR_RSPTYP_48; + } +#if 0 + if (cmd->data) { + if (cmd->data->flags & MMC_DATA_READ) + cmdr |= MCI_CMDR_TRDIR; + if (cmd->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) + cmdr |= MCI_CMDR_TRCMD_START; + if (cmd->data->flags & MMC_DATA_STREAM) + cmdr |= MCI_CMDR_TRTYP_STREAM; + if (cmd->data->flags & MMC_DATA_MULTI) + cmdr |= MCI_CMDR_TRTYP_MULTIPLE; + // XXX bad + } +#endif + if (cmd->opcode == MMC_STOP_TRANSMISSION) + cmdr |= MCI_CMDR_TRCMD_STOP; +#if 0 + if (??? == opendrain) + cmdr |= MCI_CMDR_OPDCMD; +#endif + if (!cmd->data) { + at91_mci_pdc_disable(sc); + WR4(sc, MCI_ARGR, cmd->arg); + WR4(sc, MCI_CMDR, cmdr); + WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_CMDRDY); + return; + } +// panic(); } static void @@ -300,20 +356,26 @@ { struct mmc_request *req; + req = sc->req; // assert locked if (!(sc->flags & CMD_STARTED)) { + printf("Starting command %d of request %p\n", req->cmd->opcode, + req); sc->flags |= CMD_STARTED; at91_mci_start_cmd(sc, req->cmd); return; } if (!(sc->flags & STOP_STARTED) && req->stop) { + printf("Starting command %d of request %p\n", req->stop->opcode, + req); sc->flags |= STOP_STARTED; at91_mci_start_cmd(sc, req->stop); return; } /* We must be done -- bad idea to do this while locked? */ - req = sc->req; + printf("Finished request %p\n", req); sc->req = NULL; + sc->curcmd = NULL; req->done(req->done_data); } @@ -322,6 +384,7 @@ { struct at91_mci_softc *sc = device_get_softc(brdev); + printf("queuing request %p\n", req); AT91_MCI_LOCK(sc); // XXX do we want to be able to queue up multiple commands? // XXX sounds like a good idea, but all protocols are sync, so @@ -399,10 +462,33 @@ at91_mci_intr(void *arg) { struct at91_mci_softc *sc = (struct at91_mci_softc*)arg; + uint32_t sr; + int i; + struct mmc_command *cmd; AT91_MCI_LOCK(sc); - printf("i 0x%x\n", RD4(sc, MCI_SR)); - wakeup(sc); + sr = RD4(sc, MCI_SR); + printf("i 0x%x\n", sr); WR4(sc, MCI_IDR, 0xffffffff); + cmd = sc->curcmd; + if (sr & MCI_SR_CMDRDY && cmd != NULL) + for (i = 0; i < 4; i++) + cmd->resp[i] = RD4(sc, MCI_RSPR + (i << 2)); + if (sr & MCI_SR_ERROR) { + if ((sr & MCI_SR_RCRCE) && (cmd->opcode == MMC_SEND_OP_COND || + cmd->opcode == ACMD_SD_SEND_OP_COND)) + cmd->error = MMC_ERR_NONE; + else if (sr & (MCI_SR_RTOE | MCI_SR_DTOE)) + cmd->error = MMC_ERR_TIMEOUT; + else if (sr & (MCI_SR_RCRCE | MCI_SR_DCRCE)) + cmd->error = MMC_ERR_BADCRC; + else if (sr & (MCI_SR_OVRE | MCI_SR_UNRE)) + cmd->error = MMC_ERR_FIFO; + else + cmd->error = MMC_ERR_FAILED; + } else + cmd->error = MMC_ERR_NONE; + + at91_mci_start(sc); AT91_MCI_UNLOCK(sc); } ==== //depot/projects/arm/src/sys/arm/at91/at91_mcireg.h#5 (text+ko) ==== @@ -94,40 +94,33 @@ #define MCI_CMDR_TRTYP_MULTIPLE (0x1u << 19) /* (MCI) Multiple Block transfer type */ #define MCI_CMDR_TRTYP_STREAM (0x2u << 19) /* (MCI) Stream transfer type */ /* -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register -------- */ -#define MCI_SR_CMDRDY (0x1u << 0) /* (MCI) Command Ready flag */ -#define MCI_SR_RXRDY (0x1u << 1) /* (MCI) RX Ready flag */ -#define MCI_SR_TXRDY (0x1u << 2) /* (MCI) TX Ready flag */ -#define MCI_SR_BLKE (0x1u << 3) /* (MCI) Data Block Transfer Ended flag */ -#define MCI_SR_DTIP (0x1u << 4) /* (MCI) Data Transfer in Progress flag */ -#define MCI_SR_NOTBUSY (0x1u << 5) /* (MCI) Data Line Not Busy flag */ -#define MCI_SR_ENDRX (0x1u << 6) /* (MCI) End of RX Buffer flag */ -#define MCI_SR_ENDTX (0x1u << 7) /* (MCI) End of TX Buffer flag */ -#define MCI_SR_RXBUFF (0x1u << 14) /* (MCI) RX Buffer Full flag */ -#define MCI_SR_TXBUFE (0x1u << 15) /* (MCI) TX Buffer Empty flag */ -#define MCI_SR_RINDE (0x1u << 16) /* (MCI) Response Index Error flag */ -#define MCI_SR_RDIRE (0x1u << 17) /* (MCI) Response Direction Error flag */ -#define MCI_SR_RCRCE (0x1u << 18) /* (MCI) Response CRC Error flag */ -#define MCI_SR_RENDE (0x1u << 19) /* (MCI) Response End Bit Error flag */ -#define MCI_SR_RTOE (0x1u << 20) /* (MCI) Response Time-out Error flag */ -#define MCI_SR_DCRCE (0x1u << 21) /* (MCI) data CRC Error flag */ -#define MCI_SR_DTOE (0x1u << 22) /* (MCI) Data timeout Error flag */ -#define MCI_SR_OVRE (0x1u << 30) /* (MCI) Overrun flag */ -#define MCI_SR_UNRE (0x1u << 31) /* (MCI) Underrun flag */ +#define MCI_SR_CMDRDY (0x1u << 0) /* (MCI) Command Ready flag */ +#define MCI_SR_RXRDY (0x1u << 1) /* (MCI) RX Ready flag */ +#define MCI_SR_TXRDY (0x1u << 2) /* (MCI) TX Ready flag */ +#define MCI_SR_BLKE (0x1u << 3) /* (MCI) Data Block Transfer Ended flag */ +#define MCI_SR_DTIP (0x1u << 4) /* (MCI) Data Transfer in Progress flag */ +#define MCI_SR_NOTBUSY (0x1u << 5) /* (MCI) Data Line Not Busy flag */ +#define MCI_SR_ENDRX (0x1u << 6) /* (MCI) End of RX Buffer flag */ +#define MCI_SR_ENDTX (0x1u << 7) /* (MCI) End of TX Buffer flag */ +#define MCI_SR_RXBUFF (0x1u << 14) /* (MCI) RX Buffer Full flag */ +#define MCI_SR_TXBUFE (0x1u << 15) /* (MCI) TX Buffer Empty flag */ +#define MCI_SR_RINDE (0x1u << 16) /* (MCI) Response Index Error flag */ +#define MCI_SR_RDIRE (0x1u << 17) /* (MCI) Response Direction Error flag */ +#define MCI_SR_RCRCE (0x1u << 18) /* (MCI) Response CRC Error flag */ +#define MCI_SR_RENDE (0x1u << 19) /* (MCI) Response End Bit Error flag */ +#define MCI_SR_RTOE (0x1u << 20) /* (MCI) Response Time-out Error flag */ +#define MCI_SR_DCRCE (0x1u << 21) /* (MCI) data CRC Error flag */ +#define MCI_SR_DTOE (0x1u << 22) /* (MCI) Data timeout Error flag */ +#define MCI_SR_OVRE (0x1u << 30) /* (MCI) Overrun flag */ +#define MCI_SR_UNRE (0x1u << 31) /* (MCI) Underrun flag */ + /* -------- MCI_IER : (MCI Offset: 0x44) MCI Interrupt Enable Register -------- */ /* -------- MCI_IDR : (MCI Offset: 0x48) MCI Interrupt Disable Register -------- */ /* -------- MCI_IMR : (MCI Offset: 0x4c) MCI Interrupt Mask Register -------- */ -#define MCI_SR_ERROR (MCI_SR_UNRE |\ - MCI_SR_OVRE |\ - MCI_SR_DTOE |\ - MCI_SR_DCRCE |\ - MCI_SR_RTOE |\ - MCI_SR_RENDE |\ - MCI_SR_RCRCE |\ - MCI_SR_RDIRE |\ - MCI_SR_RINDE) - -#define AT91C_NO_ARGUMENT 0x0 +#define MCI_SR_ERROR (MCI_SR_UNRE | MCI_SR_OVRE | MCI_SR_DTOE | \ + MCI_SR_DCRCE | MCI_SR_RTOE | MCI_SR_RENDE | \ + MCI_SR_RCRCE | MCI_SR_RDIRE | MCI_SR_RINDE) #define AT91C_BUS_WIDTH_1BIT 0x00 #define AT91C_BUS_WIDTH_4BITS 0x02
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609281956.k8SJuiZX042086>