Skip to contentSkip to conversation

omap: mmc: Raise timeout value to 20ms

PATCH New Tom Rini 3 participants 6 messages Jan 3, 2012 – Jan 4, 2012 MMC, SD and SDIO

lore
Share & tools
lore

Tom Rini

author
#0 lore raw

PATCH 1/1 omap: mmc: Raise timeout value to 20ms

With certain SD cards the code detects a timeout when the hardware has not timed out. We change the timeout used to match the kernel which gives software 20ms to detect a timeout. We also define to match the kernel and expand the previously incorrect comment. Finally, we let get_timer() perform subtraction for us as it offers.

---
 drivers/mmc/omap_hsmmc.c |   30 +++++++++++++++++-------------
 1 files changed, 17 insertions(+), 13 deletions(-)
drivers/mmc/omap_hsmmc.c +17 -13
index c38b9e6..378fbda 100644
@@ -33,8 +33,12 @@
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/sys_proto.h>
 
-/* If we fail after 1 second wait, something is really bad */
-#define MAX_RETRY_MS	1000
+/*
+ * Set our timeout value to 20ms.  This has always been the timeout value
+ * used by the kernel.  We define this in terms of usec since we check
+ * against get_timer calls which returns a usec value.
+ */
+#define MMC_TIMEOUT_USEC	20000
 
 static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
 static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
@@ -107,7 +111,7 @@ void mmc_init_stream(struct hsmmc *mmc_base)
 	writel(MMC_CMD0, &mmc_base->cmd);
 	start = get_timer(0);
 	while (!(readl(&mmc_base->stat) & CC_MASK)) {
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s: timedout waiting for cc!\n", __func__);
 			return;
 		}
@@ -118,7 +122,7 @@ void mmc_init_stream(struct hsmmc *mmc_base)
 		;
 	start = get_timer(0);
 	while (!(readl(&mmc_base->stat) & CC_MASK)) {
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s: timedout waiting for cc2!\n", __func__);
 			return;
 		}
@@ -140,7 +144,7 @@ static int mmc_init_setup(struct mmc *mmc)
 		&mmc_base->sysconfig);
 	start = get_timer(0);
 	while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s: timedout waiting for cc2!\n", __func__);
 			return TIMEOUT;
 		}
@@ -148,7 +152,7 @@ static int mmc_init_setup(struct mmc *mmc)
 	writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
 	start = get_timer(0);
 	while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) {
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s: timedout waiting for softresetall!\n",
 				__func__);
 			return TIMEOUT;
@@ -171,7 +175,7 @@ static int mmc_init_setup(struct mmc *mmc)
 		(dsor << CLKD_OFFSET) | ICE_OSCILLATE);
 	start = get_timer(0);
 	while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s: timedout waiting for ics!\n", __func__);
 			return TIMEOUT;
 		}
@@ -199,7 +203,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 
 	start = get_timer(0);
 	while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) {
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s: timedout waiting for cmddis!\n", __func__);
 			return TIMEOUT;
 		}
@@ -207,7 +211,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	writel(0xFFFFFFFF, &mmc_base->stat);
 	start = get_timer(0);
 	while (readl(&mmc_base->stat)) {
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s: timedout waiting for stat!\n", __func__);
 			return TIMEOUT;
 		}
@@ -270,7 +274,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 	start = get_timer(0);
 	do {
 		mmc_stat = readl(&mmc_base->stat);
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s : timeout: No status update\n", __func__);
 			return TIMEOUT;
 		}
@@ -322,7 +326,7 @@ static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size)
 		ulong start = get_timer(0);
 		do {
 			mmc_stat = readl(&mmc_base->stat);
-			if (get_timer(0) - start > MAX_RETRY_MS) {
+			if (get_timer(start) > MMC_TIMEOUT_USEC) {
 				printf("%s: timedout waiting for status!\n",
 						__func__);
 				return TIMEOUT;
@@ -374,7 +378,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
 		ulong start = get_timer(0);
 		do {
 			mmc_stat = readl(&mmc_base->stat);
-			if (get_timer(0) - start > MAX_RETRY_MS) {
+			if (get_timer(start) > MMC_TIMEOUT_USEC) {
 				printf("%s: timedout waiting for status!\n",
 						__func__);
 				return TIMEOUT;
@@ -454,7 +458,7 @@ static void mmc_set_ios(struct mmc *mmc)
 
 	start = get_timer(0);
 	while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-		if (get_timer(0) - start > MAX_RETRY_MS) {
+		if (get_timer(start) > MMC_TIMEOUT_USEC) {
 			printf("%s: timedout waiting for ics!\n", __func__);
 			return;
 		}
Signature · 1 line
1.7.0.4
#1 lore raw

PATCH 1/1 omap: mmc: Raise timeout value to 20ms

Quoted 5 lines · Tom Rini

With certain SD cards the code detects a timeout when the hardware has not timed out. ?We change the timeout used to match the kernel which gives software 20ms to detect a timeout. ?We also define to match the kernel and expand the previously incorrect comment. Finally, we let get_timer() perform subtraction for us as it offers.

This doesn't work for me with the SanDisk 4GB card on the BeagleBoard-xM. I updated the recipe to remove Andreas' original patch, substituted the new one, and I get the following, which is the behavior before I used Andreas' patch except that now it takes about 20 seconds for each timeout message to print.

Peter

SD/MMC found on device 0
reading uEnv.txt
mmc_send_cmd: timedout waiting for stat!

294 bytes read
Loaded environment from uEnv.txt
Importing environment from mmc ...
Running uenvcmd ...
Setting bus to 1
Loading file "/boot/uImage" from mmc device 0:2 (xxa2)
mmc_send_cmd: timedout waiting for stat!
mmc_send_cmd: timedout waiting for stat!

Quoted 127 lines

---
?drivers/mmc/omap_hsmmc.c | ? 30 +++++++++++++++++------------- ?1 files changed, 17 insertions(+), 13 deletions(-)

drivers/mmc/omap_hsmmc.c +0 -0
index c38b9e6..378fbda 100644
@@ -33,8 +33,12 @@

?#include <asm/arch/mmc_host_def.h>
?#include <asm/arch/sys_proto.h>

drivers/mmc/omap_hsmmc.c +6 -2
-/* If we fail after 1 second wait, something is really bad */
-#define MAX_RETRY_MS ? 1000
+/*
+ * Set our timeout value to 20ms. ?This has always been the timeout value
+ * used by the kernel. ?We define this in terms of usec since we check
+ * against get_timer calls which returns a usec value.
+ */
+#define MMC_TIMEOUT_USEC ? ? ? 20000

?static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size); ?static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,

drivers/mmc/omap_hsmmc.c +11 -12
@@ -107,7 +111,7 @@ void mmc_init_stream(struct hsmmc *mmc_base)
 ? ? ? ?writel(MMC_CMD0, &mmc_base->cmd);
 ? ? ? ?start = get_timer(0);
 ? ? ? ?while (!(readl(&mmc_base->stat) & CC_MASK)) {
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for cc!\n", __func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return;
 ? ? ? ? ? ? ? ?}
@@ -118,7 +122,7 @@ void mmc_init_stream(struct hsmmc *mmc_base)
 ? ? ? ? ? ? ? ?;
 ? ? ? ?start = get_timer(0);
 ? ? ? ?while (!(readl(&mmc_base->stat) & CC_MASK)) {
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for cc2!\n", __func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return;
 ? ? ? ? ? ? ? ?}
@@ -140,7 +144,7 @@ static int mmc_init_setup(struct mmc *mmc)
 ? ? ? ? ? ? ? ?&mmc_base->sysconfig);
 ? ? ? ?start = get_timer(0);
 ? ? ? ?while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for cc2!\n", __func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return TIMEOUT;
 ? ? ? ? ? ? ? ?}
@@ -148,7 +152,7 @@ static int mmc_init_setup(struct mmc *mmc)
 ? ? ? ?writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
 ? ? ? ?start = get_timer(0);
 ? ? ? ?while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) {
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for softresetall!\n",
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return TIMEOUT;
@@ -171,7 +175,7 @@ static int mmc_init_setup(struct mmc *mmc)
 ? ? ? ? ? ? ? ?(dsor << CLKD_OFFSET) | ICE_OSCILLATE);
 ? ? ? ?start = get_timer(0);
 ? ? ? ?while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for ics!\n", __func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return TIMEOUT;
 ? ? ? ? ? ? ? ?}
@@ -199,7 +203,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 
 ? ? ? ?start = get_timer(0);
 ? ? ? ?while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) {
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for cmddis!\n", __func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return TIMEOUT;
 ? ? ? ? ? ? ? ?}
@@ -207,7 +211,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 ? ? ? ?writel(0xFFFFFFFF, &mmc_base->stat);
 ? ? ? ?start = get_timer(0);
 ? ? ? ?while (readl(&mmc_base->stat)) {
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for stat!\n", __func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return TIMEOUT;
 ? ? ? ? ? ? ? ?}
@@ -270,7 +274,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
 ? ? ? ?start = get_timer(0);
 ? ? ? ?do {
 ? ? ? ? ? ? ? ?mmc_stat = readl(&mmc_base->stat);
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s : timeout: No status update\n", __func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return TIMEOUT;
 ? ? ? ? ? ? ? ?}
@@ -322,7 +326,7 @@ static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size)
 ? ? ? ? ? ? ? ?ulong start = get_timer(0);
 ? ? ? ? ? ? ? ?do {
 ? ? ? ? ? ? ? ? ? ? ? ?mmc_stat = readl(&mmc_base->stat);
- ? ? ? ? ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for status!\n",
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__func__);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return TIMEOUT;
@@ -374,7 +378,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
 ? ? ? ? ? ? ? ?ulong start = get_timer(0);
 ? ? ? ? ? ? ? ?do {
 ? ? ? ? ? ? ? ? ? ? ? ?mmc_stat = readl(&mmc_base->stat);
- ? ? ? ? ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for status!\n",
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__func__);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return TIMEOUT;
@@ -454,7 +458,7 @@ static void mmc_set_ios(struct mmc *mmc)
 
 ? ? ? ?start = get_timer(0);
 ? ? ? ?while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
- ? ? ? ? ? ? ? if (get_timer(0) - start > MAX_RETRY_MS) {
+ ? ? ? ? ? ? ? if (get_timer(start) > MMC_TIMEOUT_USEC) {
 ? ? ? ? ? ? ? ? ? ? ? ?printf("%s: timedout waiting for ics!\n", __func__);
 ? ? ? ? ? ? ? ? ? ? ? ?return;
 ? ? ? ? ? ? ? ?}
--

1.7.0.4

author
#2 lore raw

PATCH 1/1 omap: mmc: Raise timeout value to 20ms

Quoted 7 lines · Peter Bigot
Quoted 5 lines · Tom Rini

With certain SD cards the code detects a timeout when the hardware has not timed out. We change the timeout used to match the kernel which gives software 20ms to detect a timeout. We also define to match the kernel and expand the previously incorrect comment. Finally, we let get_timer() perform subtraction for us as it offers.

Quoted 5 lines

This doesn't work for me with the SanDisk 4GB card on the BeagleBoard-xM. I updated the recipe to remove Andreas' original patch, substituted the new one, and I get the following, which is the behavior before I used Andreas' patch except that now it takes about 20 seconds for each timeout message to print.

Dang. Is your card a class 6 card by chance? I'm going to go and see if I can pick one up locally real quick.

Signature · 1 line
Tom
#3 lore raw

PATCH 1/1 omap: mmc: Raise timeout value to 20ms

Quoted 8 lines · Tom Rini
Quoted 7 lines · Peter Bigot
Quoted 5 lines · Tom Rini

With certain SD cards the code detects a timeout when the hardware has not timed out. ?We change the timeout used to match the kernel which gives software 20ms to detect a timeout. ?We also define to match the kernel and expand the previously incorrect comment. Finally, we let get_timer() perform subtraction for us as it offers.

Quoted 8 lines
Quoted 5 lines

This doesn't work for me with the SanDisk 4GB card on the BeagleBoard-xM. ?I updated the recipe to remove Andreas' original patch, substituted the new one, and I get the following, which is the behavior before I used Andreas' patch except that now it takes about 20 seconds for each timeout message to print.

Dang. ?Is your card a class 6 card by chance? ?I'm going to go and see if I can pick one up locally real quick.

It claims to be a class 4 card.

Peter

#4 lore raw

PATCH 1/1 omap: mmc: Raise timeout value to 20ms

In reply to Peter Bigot
Quoted 7 lines · Peter Bigot
Quoted 5 lines · Tom Rini

With certain SD cards the code detects a timeout when the hardware has not timed out. ?We change the timeout used to match the kernel which gives software 20ms to detect a timeout. ?We also define to match the kernel and expand the previously incorrect comment. Finally, we let get_timer() perform subtraction for us as it offers.

Quoted 5 lines

This doesn't work for me with the SanDisk 4GB card on the BeagleBoard-xM. ?I updated the recipe to remove Andreas' original patch, substituted the new one, and I get the following, which is the behavior before I used Andreas' patch except that now it takes about 20 seconds for each timeout message to print.

I got this to work with two changes:

* s/MMC_TIMEOUT_USEC/MMC_TIMEOUT_MSEC/g and define MMC_TIMEOUT_MSEC 20, since get_timer does operate on msec in the current meta-ti BeagleBoard-xM

* The patch below, which is what I think fixes the real problem (that PSTATE.CMDI is still lit up when the function is entered).

drivers/mmc/omap_hsmmc.c +0 -0
index c38b9e6..62b659a 100644
@@ -198,7 +198,8 @@ static int mmc_send_cmd(struct mmc *mmc, struct

mmc_cmd *cmd,

        ulong start;

        start = get_timer(0);
-       while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) {
+#define CMDI_MASK                      (0x1 << 0)
+       while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK))) {
                if (get_timer(0) - start > MAX_RETRY_MS) {
                        printf("%s: timedout waiting for cmddis!\n", __func__);
                        return TIMEOUT;

Peter

#5 lore raw

PATCH 1/1 omap: mmc: Raise timeout value to 20ms

Quoted 8 lines · you
Quoted 7 lines · Peter Bigot
Quoted 5 lines · Tom Rini

With certain SD cards the code detects a timeout when the hardware has not timed out. We change the timeout used to match the kernel which gives software 20ms to detect a timeout. We also define to match the kernel and expand the previously incorrect comment. Finally, we let get_timer() perform subtraction for us as it offers.

Quoted 5 lines
Quoted 5 lines

This doesn't work for me with the SanDisk 4GB card on the BeagleBoard-xM. I updated the recipe to remove Andreas' original patch, substituted the new one, and I get the following, which is the behavior before I used Andreas' patch except that now it takes about 20 seconds for each timeout message to print.

(*)

Quoted 26 lines

I got this to work with two changes:

* s/MMC_TIMEOUT_USEC/MMC_TIMEOUT_MSEC/g and define MMC_TIMEOUT_MSEC 20, since get_timer does operate on msec in the current meta-ti BeagleBoard-xM

* The patch below, which is what I think fixes the real problem (that PSTATE.CMDI is still lit up when the function is entered).

drivers/mmc/omap_hsmmc.c +2 -1
index c38b9e6..62b659a 100644
@@ -198,7 +198,8 @@ static int mmc_send_cmd(struct mmc *mmc, struct
 mmc_cmd *cmd,
        ulong start;
 
        start = get_timer(0);
-       while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS) {
+#define CMDI_MASK                      (0x1 << 0)
+       while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK))) {
                if (get_timer(0) - start > MAX_RETRY_MS) {
                        printf("%s: timedout waiting for cmddis!\n",

__func__); return TIMEOUT;

Quoted 1 line

Peter

Without having tested (have the hardware causing errors on monday next week):
This version seems correct direction: We need to wait longer _before_ write action otherwise it is never finished - see (*). I am not an expert here but since this patch affects all mmc_cmds: Does this reduce performance?

Andreas