Date: Tue, 3 Oct 2006 05:57:25 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 107143 for review Message-ID: <200610030557.k935vP68006911@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=107143 Change 107143 by imp@imp_lighthouse on 2006/10/03 05:57:12 teak bit dfn. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91_mci.c#16 edit .. //depot/projects/arm/src/sys/arm/at91/at91_mcireg.h#6 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91_mci.c#16 (text+ko) ==== @@ -31,6 +31,7 @@ #include <sys/bio.h> #include <sys/bus.h> #include <sys/conf.h> +#include <sys/endian.h> #include <sys/kernel.h> #include <sys/kthread.h> #include <sys/lock.h> @@ -71,6 +72,7 @@ struct mtx sc_mtx; bus_dma_tag_t dmatag; bus_dmamap_t map; + int mapped; struct mmc_host host; int wire4; int bus_busy; @@ -257,7 +259,6 @@ return; } -#if 0 static void at91_mci_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) { @@ -265,7 +266,6 @@ return; *(bus_addr_t *)arg = segs[0].ds_addr; } -#endif static int at91_mci_update_ios(device_t brdev, device_t reqdev) @@ -309,10 +309,15 @@ static void at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd) { - uint32_t cmdr; + uint32_t cmdr, ier = 0, mr; + struct mmc_data *data; + struct mmc_request *req; + size_t block_size = 1 << 9; // Fixed, per mmc/sd spec for 2GB cards sc->curcmd = cmd; + data = cmd->data; cmdr = cmd->opcode; + req = cmd->mrq; if (MMC_RSP(cmd->flags) == MMC_RSP_NONE) cmdr |= MCI_CMDR_RSPTYP_NO; else { @@ -323,24 +328,21 @@ else cmdr |= MCI_CMDR_RSPTYP_48; } -#if 0 - if (cmd->data) { - if (cmd->data->flags & MMC_DATA_READ) + if (data) { + if (data->flags & MMC_DATA_READ) cmdr |= MCI_CMDR_TRDIR; - if (cmd->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) + if (data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)) cmdr |= MCI_CMDR_TRCMD_START; - if (cmd->data->flags & MMC_DATA_STREAM) + if (data->flags & MMC_DATA_STREAM) cmdr |= MCI_CMDR_TRTYP_STREAM; - if (cmd->data->flags & MMC_DATA_MULTI) + if (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 (sc->host.ios.bus_mode == opendrain) cmdr |= MCI_CMDR_OPDCMD; - if (!cmd->data) { + if (!data) { at91_mci_pdc_disable(sc); printf("CMDR %x ARGR %x\n", cmdr, cmd->arg); WR4(sc, MCI_ARGR, cmd->arg); @@ -348,7 +350,43 @@ WR4(sc, MCI_IER, MCI_SR_ERROR | MCI_SR_CMDRDY); return; } - panic("WRITE THE DATA HANDLER"); + // Set block size and turn on PDC mode for dma xfer and disable + // PDC until we're ready. + mr = RD4(sc, MCI_MR) & ~MCI_MR_BLKLEN; + WR4(sc, MCI_MR, mr | (block_size << 16) | MCI_MR_PDCMODE); + WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS); + if (cmdr & MCI_CMDR_TRCMD_START) { + data->xfer_len = 0; + if (cmdr & MCI_CMDR_TRDIR) { + void *vaddr = cmd->data->data; + bus_addr_t paddr; + + if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, + block_size, at91_mci_getaddr, &paddr, 0) != 0) { + if (req->cmd->flags & STOP_STARTED) + req->stop->error = EAGAIN; + else + req->cmd->error = EAGAIN; + req->done(req); + return; + } + sc->mapped++; + bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREREAD); + WR4(sc, PDC_RPR, paddr); + WR4(sc, PDC_RCR, data->len / 4); + ier = MCI_SR_ENDRX; + } else + panic("Write write support"); + } + WR4(sc, MCI_ARGR, cmd->arg); + WR4(sc, MCI_CMDR, cmdr); + if (cmdr & MCI_CMDR_TRCMD_START) { + if (cmdr & MCI_CMDR_TRDIR) + WR4(sc, PDC_PTCR, PDC_PTCR_RXTEN); + else + WR4(sc, PDC_PTCR, PDC_PTCR_TXTEN); + } + WR4(sc, MCI_IER, MCI_SR_ERROR | ier); } static void @@ -426,6 +464,21 @@ return (0); } +static void +at91_mci_read_done(struct at91_mci_softc *sc) +{ + uint32_t *walker; + struct mmc_command *cmd; + int i, len; + + cmd = sc->curcmd; + bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->dmatag, sc->map); + walker = (uint32_t *)cmd->data->data; + len = cmd->data->len / 4; + for (i = 0; i < len; i++) + *walker = bswap32(*walker); +} static void at91_mci_intr(void *arg) @@ -467,7 +520,7 @@ } if (sr & MCI_SR_ENDRX) { printf("ENDRX\n"); -//XXX at91_mci_read_done(sc); + at91_mci_read_done(sc); } if (sr & MCI_SR_NOTBUSY) { printf("NOTBUSY\n"); ==== //depot/projects/arm/src/sys/arm/at91/at91_mcireg.h#6 (text+ko) ==== @@ -55,7 +55,7 @@ #define MCI_MR_PWSDIV (0x3fu << 8) /* (MCI) Power Saving Divider */ #define MCI_MR_PDCPADV (0x1u << 14) /* (MCI) PDC Padding Value */ #define MCI_MR_PDCMODE (0x1u << 15) /* (MCI) PDC Oriented Mode */ -#define MCI_MR_BLKLEN (0x1u << 18) /* (MCI) Data Block Length */ +#define MCI_MR_BLKLEN 0x3fff0000ul /* (MCI) Data Block Length */ /* -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register -------- */ #define MCI_DTOR_DTOCYC (0xfu << 0) /* (MCI) Data Timeout Cycle Number */ #define MCI_DTOR_DTOMUL (0x7u << 4) /* (MCI) Data Timeout Multiplier */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610030557.k935vP68006911>