Skip site navigation (1)Skip section navigation (2)
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>