PERFORCE change 107143 for review
Warner Losh
imp at FreeBSD.org
Mon Oct 2 22:57:26 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=107143
Change 107143 by imp at 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 */
More information about the p4-projects
mailing list