mmc: fix OCR Polling
PATCH 1/1 mmc: fix OCR Polling
Hi Peng,
Quoted 27 lines
From: Peng.Fan at freescale.com (Peng Fan)
Date: Thu, 19 Mar 2015 16:22:46 +0800
Subject: [U-Boot] [PATCH] mmc: fix OCR PollingIf in
mmc_send_op_cond,OCR_BUSYis set in CMD1's response, then state is transfered to Ready state, and there is no need to send CMD1 again. Otherwise following CMD1 will recieve no response, or timeour error from driver such asfsl_esdhc.c.If not into Ready state in previous CMD1, then continue CMD1 command.
In
mmc_complete_op_cond, we use the valuemmc->op_cond_responsefrommmc_send_op_cond, since there should be no CMD1 command betweenmmc_send_op_condandmmc_complete_op_condBefore fixing this, uboot log shows:
"
CMD_SEND:0ARG 0x00000000 MMC_RSP_NONE CMD_SEND:8 ARG 0x000001AA MMC_RSP_R1,5,6,7 0x18EC1504 CMD_SEND:55 ARG 0x00000000 MMC_RSP_R1,5,6,7 0x18EC1504CMD_SEND:0
Quoted 8 lines
ARG 0x00000000
MMC_RSP_NONE
CMD_SEND:1
ARG 0x00000000
MMC_RSP_R3,4 0x00FF8080
CMD_SEND:1
ARG 0x40300000
MMC_RSP_R3,4 0xC0FF8080 --> Already OCR_BUSYset
Quoted 19 lines
CMD_SEND:1
ARG 0x40300000 MMC_RSP_R3,4 0x0096850A --> Failed CMD1MMC init failed
"Using this patch, this issue is fixed, emmc can be detected correctly.
Signed-off-by Peng Fan <[email protected]>--- drivers/mmc/mmc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)drivers/mmc/mmc.c +0
-0
drivers/mmc/mmc.c static int mmc_complete_op_cond(struct mmc *mmc) · line 412
Quoted 8 lines
drivers/mmc/mmc.c +4
-1@@ -406,14 +406,23 @@ static int mmc_complete_op_cond(struct mmc *mmc) mmc->op_cond_pending =0 ; start =get_timer (0 ); - do { +/* +* If in mmc_send_op_cond, OCR_BUSY is set in CMD1's response, then +* state is transfered to Ready state, and there is no need to +* send CMD1 again. Otherwise following CMD1 will recieve no
response,
Quoted 19 lines
drivers/mmc/mmc.c +7
-1+* or timeour error from driver such as fsl_esdhc.c. +* +* If not into Ready state in previous CMD1, then continue CMD1 +* command. +*/ +while (!(mmc->op_cond_response &OCR_BUSY )) { err =mmc_send_op_cond_iter (mmc, &cmd,1 );if (err)return err;if (get_timer (start) > timeout)return UNUSABLE_ERR ;udelay (100 ); - }while (!(mmc->op_cond_response &OCR_BUSY )); + }if (mmc_host_is_spi (mmc)) {/* read OCR for spi */ cmd.cmdidx =MMC_CMD_SPI_READ_OCR ;Signature · 1 line
1.8.4
After this patch, if the busy flag is indeed already set (so that the loop body
is not executed), and it is not an SPI case (mmc_host_is_spi(mmc) is false), the "cmd" structure (which is local to mmc_complete_op_cond() function) is left uninitialized, and using cmd.response[0] later in the function becomes
incorrect. And the OCR register value and the high capacity flag may be set incorrectly.
So, this patch is not enough by itself, it needs to be modified (appended) in order to get the correct code.
Coincidentally, the same day I submitted a patch series ("[U-Boot] [PATCH 0/6] mmc: Fix OCR polling and splitted initialization"), that, among other changes, fixes the OCR polling problem too ("[U-Boot] [PATCH 4/6] mmc: Continue polling MMC card for OCR only if it is still not ready"),
but in a slightly different way, that hopefully doesn't have the mentioned issue.
Thanks.
Best regards,
Andrew
PATCH 1/1 mmc: fix OCR Polling
Hi, Andrew
Quoted 85 lines · Andrew Gabbasov
Hi Peng,
Quoted 27 lines
From: Peng.Fan at freescale.com (Peng Fan)
Date: Thu, 19 Mar 2015 16:22:46 +0800
Subject: [U-Boot] [PATCH] mmc: fix OCR PollingIf in
mmc_send_op_cond,OCR_BUSYis set in CMD1's response, then state is transfered to Ready state, and there is no need to send CMD1 again. Otherwise following CMD1 will recieve no response, or timeour error from driver such asfsl_esdhc.c.If not into Ready state in previous CMD1, then continue CMD1 command.
In
mmc_complete_op_cond, we use the valuemmc->op_cond_responsefrommmc_send_op_cond, since there should be no CMD1 command betweenmmc_send_op_condandmmc_complete_op_condBefore fixing this, uboot log shows:
"
CMD_SEND:0ARG 0x00000000 MMC_RSP_NONE CMD_SEND:8 ARG 0x000001AA MMC_RSP_R1,5,6,7 0x18EC1504 CMD_SEND:55 ARG 0x00000000 MMC_RSP_R1,5,6,7 0x18EC1504CMD_SEND:0
Quoted 8 lines
ARG 0x00000000 MMC_RSP_NONE CMD_SEND:1 ARG 0x00000000 MMC_RSP_R3,4 0x00FF8080 CMD_SEND:1 ARG 0x40300000 MMC_RSP_R3,4 0xC0FF8080 --> Already OCR_BUSYset
Quoted 19 lines
CMD_SEND:1
ARG 0x40300000 MMC_RSP_R3,4 0x0096850A --> Failed CMD1MMC init failed
"Using this patch, this issue is fixed, emmc can be detected correctly.
Signed-off-by Peng Fan <[email protected]>--- drivers/mmc/mmc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)drivers/mmc/mmc.c +0
-0drivers/mmc/mmc.c static int mmc_complete_op_cond(struct mmc *mmc) · line 412
Quoted 8 lines
drivers/mmc/mmc.c +4
-1@@ -406,14 +406,23 @@ static int mmc_complete_op_cond(struct mmc *mmc) mmc->op_cond_pending =0 ; start =get_timer (0 ); - do { +/* +* If in mmc_send_op_cond, OCR_BUSY is set in CMD1's response, then +* state is transfered to Ready state, and there is no need to +* send CMD1 again. Otherwise following CMD1 will recieve no response,
Quoted 19 lines
drivers/mmc/mmc.c +7
-1+* or timeour error from driver such as fsl_esdhc.c. +* +* If not into Ready state in previous CMD1, then continue CMD1 +* command. +*/ +while (!(mmc->op_cond_response &OCR_BUSY )) { err =mmc_send_op_cond_iter (mmc, &cmd,1 );if (err)return err;if (get_timer (start) > timeout)return UNUSABLE_ERR ;udelay (100 ); - }while (!(mmc->op_cond_response &OCR_BUSY )); + }if (mmc_host_is_spi (mmc)) {/* read OCR for spi */ cmd.cmdidx =MMC_CMD_SPI_READ_OCR ;Signature · 1 line
1.8.4
Quoted 8 lines
After this patch, if the busy flag is indeed already set (so that the loop body
is not executed), and it is not an SPI case (mmc_host_is_spi(mmc)is false), the "cmd" structure (which is local tommc_complete_op_cond()function) is left uninitialized, and using cmd.response[0] later in the function becomes
incorrect. And the OCR register value and the high capacity flag may be set incorrectly.
Yeah. you are right.
Maybe the following piece of code should be added to replace mmc->ocr = cmd.response[0]:
"
if (mmc_host_is_spi(mmc))
mmc->ocr = cmd.response[0];
else
mmc->ocr = mmc->op_cond_response;"
Thanks for correcting me.
Quoted 11 lines
So, this patch is not enough by itself, it needs to be modified (appended) in order to get the correct code.
Coincidentally, the same day I submitted a patch series ("[U-Boot] [PATCH 0/6] mmc: Fix OCR polling and splitted initialization"), that, among other changes, fixes the OCR polling problem too ("[U-Boot] [PATCH 4/6] mmc: Continue polling MMC card for OCR only if it is still not ready"),
but in a slightly different way, that hopefully doesn't have the mentioned issue.
Your's does not have such issue:)
Quoted 8 lines
Thanks.
Best regards,
Andrew.
Thanks
Peng.
PATCH 1/1 mmc: fix OCR Polling
Hi Peng,
Quoted 18 lines
From: Peng Fan [mailto:Peng.Fan at freescale.com]
Sent: Saturday, March 21, 2015 1:34 PM
To: Gabbasov, Andrew; u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH] mmc: fix OCR Polling[skipped]
Quoted 6 lines
After this patch, if the busy flag is indeed already set (so that the loop body is not executed), and it is not an SPI case (
mmc_host_is_spi(mmc)is false), the "cmd" structure (which is local tommc_complete_op_cond()function) is left uninitialized, and using cmd.response[0] later in the function becomes incorrect. And the OCR register value and the high capacity flag may be set incorrectly.Yeah. you are right.
Maybe the following piece of code should be added to replacemmc->ocr= cmd.response[0]:
"
if (mmc_host_is_spi(mmc))
Quoted 5 lines
mmc->ocr = cmd.response[0]; else mmc->ocr = mmc->op_cond_response;"
Thanks for correcting me.
Well, there can be several ways to correct that. The easiest would be something
similar to what you propose, but, just to avoid extra "if", we could add
mmc->op_cond_response = cmd.response[0];
to the end of existing "if(mmc_host_is_spi(mmc))" and change
mmc->ocr = cmd.response[0];
to
mmc->ocr = mmc->op_cond_response;at the end of function. Since op_cond_response should be already set from the function beginning, this can be used immediately.
And, going further, since op_cond_response is actually the same contents as mmc->ocr, we could combine them and use mmc->ocr at once, from the beginning of polling loops. This is a little more complex, but makes the code cleaner. This is what is done in one of other patches in my series ;-)
Thanks.
Best regards,
Andrew
PATCH 1/1 mmc: fix OCR Polling
Hi Andrew, Peng,
Quoted 39 lines · Andrew Gabbasov
Hi Peng,
Quoted 18 lines
From: Peng Fan [mailto:Peng.Fan at freescale.com]
Sent: Saturday, March 21, 2015 1:34 PM
To: Gabbasov, Andrew; u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH] mmc: fix OCR Polling[skipped]
Quoted 6 lines
After this patch, if the busy flag is indeed already set (so that the loop body is not executed), and it is not an SPI case (
mmc_host_is_spi(mmc)is false), the "cmd" structure (which is local tommc_complete_op_cond()function) is left uninitialized, and using cmd.response[0] later in the function becomes incorrect. And the OCR register value and the high capacity flag may be set incorrectly.Yeah. you are right.
Maybe the following piece of code should be added to replacemmc->ocr= cmd.response[0]:
"
if (mmc_host_is_spi(mmc))Quoted 5 lines
mmc->ocr = cmd.response[0]; else mmc->ocr = mmc->op_cond_response;"
Thanks for correcting me.Well, there can be several ways to correct that. The easiest would be something
similar to what you propose, but, just to avoid extra "if", we could add
mmc->op_cond_response= cmd.response[0];
to the end of existing "if(mmc_host_is_spi(mmc))" and change
mmc->ocr= cmd.response[0];
to
mmc->ocr=mmc->op_cond_response;
at the end of function. Sinceop_cond_responseshould be already set from the function beginning, this can be used immediately.
Quoted 6 lines
And, going further, since
op_cond_responseis actually the same contents asmmc->ocr, we could combine them and usemmc->ocrat once, from the beginning of polling loops. This is a little more complex, but makes the code cleaner. This is what is done in one of other patches in my series ;-)
This does seem like a case where a simple accessor structure would help until we figure out how to process.
Something like mmc_get_ocr() as a private API perhaps?
Quoted 5 lines
Thanks.
Best regards,
Andrew
Regards
? Pantelis
Quoted 5 lines
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
PATCH 1/1 mmc: fix OCR Polling
Hi Pantelis,
Quoted 55 lines
From: Pantelis Antoniou [mailto:pantelis.antoniou at gmail.com]
Sent: Friday, March 27, 2015 9:32 PM
To: Gabbasov, Andrew
Cc: Peng Fan; u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH] mmc: fix OCR PollingHi Andrew, Peng,
Quoted 1 line
On Mar 23, 2015, at 01:23 , Andrew Gabbasov
Quoted 38 lines · <[email protected]> wrote:
Hi Peng,
Quoted 18 lines
From: Peng Fan [mailto:Peng.Fan at freescale.com]
Sent: Saturday, March 21, 2015 1:34 PM
To: Gabbasov, Andrew; u-boot at lists.denx.de
Subject: Re: [U-Boot] [PATCH] mmc: fix OCR Polling[skipped]
Quoted 6 lines
After this patch, if the busy flag is indeed already set (so that the loop body is not executed), and it is not an SPI case (
mmc_host_is_spi(mmc)is false), the "cmd" structure (which is local tommc_complete_op_cond()function) is left uninitialized, and using cmd.response[0] later in the function becomes incorrect. And the OCR register value and the high capacity flag may be set incorrectly.Yeah. you are right.
Maybe the following piece of code should be added to replacemmc->ocr= cmd.response[0]:
"
if (mmc_host_is_spi(mmc))Quoted 5 lines
mmc->ocr = cmd.response[0]; else mmc->ocr = mmc->op_cond_response;"
Thanks for correcting me.Well, there can be several ways to correct that. The easiest would be something
similar to what you propose, but, just to avoid extra "if", we could add
mmc->op_cond_response= cmd.response[0];
to the end of existing "if(mmc_host_is_spi(mmc))" and change
mmc->ocr= cmd.response[0];
to
mmc->ocr=mmc->op_cond_response;
at the end of function. Sinceop_cond_responseshould be already set from the function beginning, this can be used immediately.Quoted 6 lines
And, going further, since
op_cond_responseis actually the same contents asmmc->ocr, we could combine them and usemmc->ocrat once, from the beginning of polling loops. This is a little more complex, but makes the code cleaner. This is what is done in one of other patches in my series ;-)
Quoted 4 lines
This does seem like a case where a simple accessor structure would help until we figure out how to process.
Something like
mmc_get_ocr()as a private API perhaps?
Actually I don't see any need to introduce a new accessor or any other API here. Currently the 2 fields are used to store exactly the same data (OCR, which is a response to send_op_cond command). But the 'op_cond_response' is used while OCR polling and 'ocr' is filled in after its completion.
The correct solution from my point of view is to just use a single field (ocr) from the very beginning. I have already submitted this solution in one of my patches ("[PATCH 2/6] mmc: Avoid extra duplicate entry in mmc device structure" in "[PATCH 0/6] mmc: Fix OCR polling and splitted initialization" series).
Thanks.
Best regards,
Andrew