Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Oct 2006 00:54:05 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 107283 for review
Message-ID:  <200610050054.k950s5e0082716@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=107283

Change 107283 by imp@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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200610050054.k950s5e0082716>