omap: mmc: Raise timeout value to 20ms
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
@@ -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 20000static 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
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.txtmmc_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
Signed-off-by Tom Rini <[email protected]>---
?drivers/mmc/omap_hsmmc.c | ? 30 +++++++++++++++++------------- ?1 files changed, 17 insertions(+), 13 deletions(-)drivers/mmc/omap_hsmmc.c +0
-0@@ -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
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
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
PATCH 1/1 omap: mmc: Raise timeout value to 20ms
In reply to Peter BigotQuoted 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
@@ -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
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_MSEC20, sinceget_timerdoes 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@@ -198,7 +198,8 @@ static int mmc_send_cmd(struct mmc *mmc, structmmc_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