PERFORCE change 107283 for review
Warner Losh
imp at FreeBSD.org
Wed Oct 4 17:54:06 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=107283
Change 107283 by imp at imp_lighthouse on 2006/10/05 00:53:44
First cut at a rock-simple bounce buffer for the stupid
write path. Also, first cut at the write path. It seems to
work..
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/at91_mci.c#24 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/at91_mci.c#24 (text+ko) ====
@@ -61,6 +61,8 @@
#include "mmcbr_if.h"
+#define BBSZ 512
+
struct at91_mci_softc {
void *intrhand; /* Interrupt handle */
device_t dev;
@@ -78,6 +80,7 @@
int bus_busy;
struct mmc_request *req;
struct mmc_command *curcmd;
+ char bounce_buffer[BBSZ];
};
static inline uint32_t
@@ -313,9 +316,13 @@
at91_mci_start_cmd(struct at91_mci_softc *sc, struct mmc_command *cmd)
{
uint32_t cmdr, ier = 0, mr;
+ uint32_t *src, *dst;
+ int i;
struct mmc_data *data;
struct mmc_request *req;
size_t block_size = 1 << 9; // Fixed, per mmc/sd spec for 2GB cards
+ void *vaddr;
+ bus_addr_t paddr;
sc->curcmd = cmd;
data = cmd->data;
@@ -358,29 +365,41 @@
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) {
+ if (cmdr & MCI_CMDR_TRDIR)
+ vaddr = cmd->data->data;
+ else {
+ if (data->len != BBSZ)
+ panic("Write multiblock write support");
+ vaddr = sc->bounce_buffer;
+ src = (uint32_t *)cmd->data->data;
+ dst = (uint32_t *)vaddr;
+ for (i = 0; i < data->len / 4; i++)
+ dst[i] = bswap32(src[i]);
+ }
data->xfer_len = 0;
+ if (bus_dmamap_load(sc->dmatag, sc->map, vaddr, data->len,
+ at91_mci_getaddr, &paddr, 0) != 0) {
+ if (req->cmd->flags & STOP_STARTED)
+ req->stop->error = MMC_ERR_NO_MEMORY;
+ else
+ req->cmd->error = MMC_ERR_NO_MEMORY;
+ sc->req = NULL;
+ sc->curcmd = NULL;
+ req->done(req);
+ return;
+ }
+ sc->mapped++;
if (cmdr & MCI_CMDR_TRDIR) {
- void *vaddr = cmd->data->data;
- bus_addr_t paddr;
-
- if (bus_dmamap_load(sc->dmatag, sc->map, vaddr,
- data->len, at91_mci_getaddr, &paddr, 0) != 0) {
- if (req->cmd->flags & STOP_STARTED)
- req->stop->error = MMC_ERR_NO_MEMORY;
- else
- req->cmd->error = MMC_ERR_NO_MEMORY;
- sc->req = NULL;
- sc->curcmd = NULL;
- 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");
+ } else {
+ bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_PREWRITE);
+ WR4(sc, PDC_TPR, paddr);
+ WR4(sc, PDC_TCR, data->len / 4);
+ ier = MCI_SR_TXBUFE;
+ }
}
// printf("CMDR %x ARGR %x with data\n", cmdr, cmd->arg);
WR4(sc, MCI_ARGR, cmd->arg);
@@ -495,6 +514,18 @@
}
static void
+at91_mci_xmit_done(struct at91_mci_softc *sc)
+{
+ // Finish up the sequence...
+ WR4(sc, PDC_PTCR, PDC_PTCR_RXTDIS | PDC_PTCR_TXTDIS);
+ WR4(sc, MCI_IDR, MCI_SR_TXBUFE);
+ WR4(sc, MCI_IER, MCI_SR_NOTBUSY);
+ bus_dmamap_sync(sc->dmatag, sc->map, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->dmatag, sc->map);
+ sc->mapped--;
+}
+
+static void
at91_mci_intr(void *arg)
{
struct at91_mci_softc *sc = (struct at91_mci_softc*)arg;
@@ -527,7 +558,7 @@
} else {
if (sr & MCI_SR_TXBUFE) {
// printf("TXBUFE\n");
-//XXX at91_mci_xmit_done(sc);
+ at91_mci_xmit_done(sc);
}
if (sr & MCI_SR_RXBUFF) {
// printf("RXBUFF\n");
@@ -543,6 +574,7 @@
}
if (sr & MCI_SR_NOTBUSY) {
// printf("NOTBUSY\n");
+ WR4(sc, MCI_IDR, MCI_SR_NOTBUSY);
WR4(sc, MCI_IER, MCI_SR_CMDRDY);
}
if (sr & MCI_SR_DTIP) {
More information about the p4-projects
mailing list