[PATCH 3/3] This commit solve mmc_write_blocks with async cmd12 hidden bug

richie_wang macro_system at 163.com
Wed Sep 25 02:20:25 CEST 2013


When the processor use mmc_write_blocks to write multi-block data to SD
Memory card
it will send CMD12 to finish the transfer. But if the code using PIO method
and processor
speed is high than the SD host sending the data in SD host buffer.There will
be a condition
CMD12 will on cmd line and some data still on data line, which will conflict
will multi-write
Time requirement in SPEC. This commit makes CPU send CMD12 after register
0x24 bit8 change to
zero.

Signed-off-by: richie_wang <macro_system at 163.com>
---
:100644 100644 aa2fdef... f2f982c... M	drivers/mmc/mmc_write.c
:100644 100644 dfb2eee... d66cc9a... M	drivers/mmc/sdhci.c
:100644 100644 74d06ae... a0c9e32... M	include/sdhci.h
 drivers/mmc/mmc_write.c |    8 ++++++++
 drivers/mmc/sdhci.c     |   11 +++++++++++
 include/sdhci.h         |    4 ++++
 3 files changed, 23 insertions(+)

diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
index aa2fdef..f2f982c 100644
--- a/drivers/mmc/mmc_write.c
+++ b/drivers/mmc/mmc_write.c
@@ -10,6 +10,7 @@
 #include <config.h>
 #include <common.h>
 #include <part.h>
+#include <sdhci.h>
 #include "mmc_private.h"
 
 static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt)
@@ -103,6 +104,7 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t
start,
 {
 	struct mmc_cmd cmd;
 	struct mmc_data data;
+	struct sdhci_host* host;
 	int timeout = 1000;
 
 	if ((start + blkcnt) > mmc->block_dev.lba) {
@@ -142,6 +144,12 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t
start,
 		cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
 		cmd.cmdarg = 0;
 		cmd.resp_type = MMC_RSP_R1b;
+		
+		/* cmd12 async timing problem */
+		host = (struct sdhci_host*)mmc->priv;
+		if(host->magic_num == SDHCI_MAGIC_NUM)
+			sdhci_cmd12_wait(host);
+		
 		if (mmc_send_cmd(mmc, &cmd, NULL)) {
 			printf("mmc fail to send stop cmd\n");
 			return 0;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index dfb2eee..d66cc9a 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -410,6 +410,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32
min_clk)
 	struct mmc *mmc;
 	unsigned int caps;
 
+	host->magic_num = SDHCI_MAGIC_NUM;
 	mmc = malloc(sizeof(struct mmc));
 	if (!mmc) {
 		printf("mmc malloc fail!\n");
@@ -482,3 +483,13 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32
min_clk)
 
 	return 0;
 }
+
+
+void sdhci_cmd12_wait(struct sdhci_host *host)
+{
+	u32 mask = SDHCI_DOING_WRITE;
+	
+	while(sdhci_readl(host, SDHCI_PRESENT_STATE) & mask);
+
+	return ;
+}
diff --git a/include/sdhci.h b/include/sdhci.h
index 74d06ae..a0c9e32 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -233,7 +233,10 @@ struct sdhci_ops {
 #endif
 };
 
+#define SDHCI_MAGIC_NUM		0x20131001
+
 struct sdhci_host {
+	unsigned int magic_num;
 	char *name;
 	void *ioaddr;
 	unsigned int quirks;
@@ -332,4 +335,5 @@ static inline u8 sdhci_readb(struct sdhci_host *host,
int reg)
 #endif
 
 int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk);
+void sdhci_cmd12_wait(struct sdhci_host *host);
 #endif /* __SDHCI_HW_H */
-- 
1.7.9.5




--
View this message in context: http://u-boot.10912.n7.nabble.com/Patch-about-mmc-and-sdhci-Please-look-it-i-can-not-pull-the-patch-I-copy-it-here-tp164059.html
Sent from the U-Boot mailing list archive at Nabble.com.


More information about the U-Boot mailing list