[U-Boot] [PATCH v1] ppc/85xx: PIO Support for FSL eSDHC Controller Driver

Dipen Dudhat dipen.dudhat at freescale.com
Wed Sep 9 11:29:07 CEST 2009


PIO Mode Support for eSDHC Controller Driver on Freescale SoCs.

Signed-off-by: Dipen Dudhat <dipen.dudhat at freescale.com>
---
- applies on git.denx.de/u-boot-mpc85xx.git branch->next
 drivers/mmc/fsl_esdhc.c |   80 +++++++++++++++++++++++++++++++++++++++++++++-
 include/fsl_esdhc.h     |    2 +
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index c6e9e6e..f02fc8a 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -73,8 +73,10 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
 	uint xfertyp = 0;
 
 	if (data) {
-		xfertyp |= XFERTYP_DPSEL | XFERTYP_DMAEN;
-
+		xfertyp |= XFERTYP_DPSEL;
+#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
+		xfertyp |= XFERTYP_DMAEN;
+#endif
 		if (data->blocks > 1) {
 			xfertyp |= XFERTYP_MSBSEL;
 			xfertyp |= XFERTYP_BCEN;
@@ -98,12 +100,80 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
 	return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
 }
 
+#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
+/*
+ * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
+ */
+static int
+esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
+{
+	struct fsl_esdhc *regs = mmc->priv;
+	uint blocks;
+	char *buffer;
+	uint databuf;
+	uint size;
+	uint irqstat;
+	uint timeout;
+
+	if (data->flags & MMC_DATA_READ) {
+		blocks = data->blocks;
+		buffer = data->dest;
+		while (blocks) {
+			size = data->blocksize;
+			while (size && (!(irqstat & IRQSTAT_TC))) {
+				udelay(1000);
+				irqstat = in_be32(&regs->irqstat);
+				databuf = in_le32(&regs->datport);
+				*((uint *)buffer) = databuf;
+				buffer += 4;
+				size -= 4;
+			}
+			blocks--;
+		}
+	} else {
+		blocks = data->blocks;
+		buffer = data->src;
+		while (blocks) {
+			timeout = MAX_TIMEOUT;
+			size = data->blocksize;
+			irqstat = in_be32(&regs->irqstat);
+			while (!(in_be32(&regs->prsstat) & PRSSTAT_BWEN) && --timeout);
+			if (timeout <= 0) {
+				printf("\nData Write Failed in PIO Mode.");
+				return TIMEOUT;
+			} else {
+				while (size && (!(irqstat & IRQSTAT_TC))) {
+					databuf = *((uint *)buffer);
+					buffer += 4;
+					size -= 4;
+					udelay(1000);
+					irqstat = in_be32(&regs->irqstat);
+					out_le32(&regs->datport, databuf);
+				}
+			}
+			blocks--;
+		}
+	}
+}
+#endif
+
 static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 {
 	uint wml_value;
 	int timeout;
 	struct fsl_esdhc *regs = mmc->priv;
 
+#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
+	if (!(data->flags & MMC_DATA_READ)) {
+		if ((in_be32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
+			printf("\nThe SD card is locked. "
+				"Can not write to a locked card.\n\n");
+			return TIMEOUT;
+			}
+			out_be32(&regs->dsaddr, (u32)data->src);
+		} else
+			out_be32(&regs->dsaddr, (u32)data->dest);
+#else
 	wml_value = data->blocksize/4;
 
 	if (data->flags & MMC_DATA_READ) {
@@ -125,6 +195,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 	}
 
 	out_be32(&regs->wml, wml_value);
+#endif
 
 	out_be32(&regs->blkattr, data->blocks << 16 | data->blocksize);
 
@@ -201,6 +272,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 		return TIMEOUT;
 
 	/* Copy the response to the response buffer */
+	udelay(1000);
 	if (cmd->resp_type & MMC_RSP_136) {
 		u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
 
@@ -217,6 +289,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 
 	/* Wait until all of the blocks are transferred */
 	if (data) {
+#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
+		esdhc_pio_read_write(mmc, data);
+#else
 		do {
 			irqstat = in_be32(&regs->irqstat);
 
@@ -227,6 +302,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 				return TIMEOUT;
 		} while (!(irqstat & IRQSTAT_TC) &&
 				(in_be32(&regs->prsstat) & PRSSTAT_DLA));
+#endif
 	}
 
 	out_be32(&regs->irqstat, -1);
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index 89b8304..9b30de4 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -86,6 +86,7 @@
 #define PRSSTAT_CDPL		(0x00040000)
 #define PRSSTAT_CINS		(0x00010000)
 #define PRSSTAT_BREN		(0x00000800)
+#define PRSSTAT_BWEN		(0x00000400)
 #define PRSSTAT_DLA		(0x00000004)
 #define PRSSTAT_CICHB		(0x00000002)
 #define PRSSTAT_CIDHB		(0x00000001)
@@ -117,6 +118,7 @@
 #define XFERTYP_DMAEN		0x00000001
 
 #define CINS_TIMEOUT		1000
+#define MAX_TIMEOUT		1000
 
 #define DSADDR		0x2e004
 
-- 
1.5.6.3



More information about the U-Boot mailing list