[U-Boot] [PATCH v2 1/3] mmc: sdhci: fix the wrong operation when response type is R1b
Lei Wen
adrian.wenl at gmail.com
Fri Mar 30 05:33:06 CEST 2012
Hi Jaehoon,
On Fri, Mar 30, 2012 at 10:39 AM, Jaehoon Chung <jh80.chung at samsung.com> wrote:
> When response type is R1b, mask value is added the SDHCI_INT_DAT_END.
> but in while(), didn't check that flag.
> So sdhci controller didn't work fine.
> CMD6 didn't always complete.
Could you elaborate it more in details?
do {
stat = sdhci_readl(host, SDHCI_INT_STATUS);
if (stat & SDHCI_INT_ERROR)
break;
} while ((stat & mask) != mask);
Here in the while condition, if the status read out don't contain all mask,
then the looping would continue.
Do you mean you just need a retry max time set here?
>
> Signed-off-by: Jaehoon Chung <jh80.chung at samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
> ---
> drivers/mmc/sdhci.c | 33 +++++++++++++++++++++++----------
> 1 files changed, 23 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index fc904b5..0dd08b9 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -124,10 +124,11 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
> {
> struct sdhci_host *host = (struct sdhci_host *)mmc->priv;
> unsigned int stat = 0;
> - int ret = 0;
> + int i, ret = 0;
> int trans_bytes = 0, is_aligned = 1;
> u32 mask, flags, mode;
> unsigned int timeout, start_addr = 0;
> + unsigned int retry = 10000;
>
> /* Wait max 10 ms */
> timeout = 10;
> @@ -206,19 +207,31 @@ int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
> flush_cache(start_addr, trans_bytes);
> #endif
> sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND);
> - do {
> +
> + for (i = 0; i < retry; i++) {
> stat = sdhci_readl(host, SDHCI_INT_STATUS);
> - if (stat & SDHCI_INT_ERROR)
> + if (stat & (SDHCI_INT_RESPONSE | SDHCI_INT_DATA_END)) {
> + sdhci_cmd_done(host, cmd);
> + sdhci_writel(host, mask, SDHCI_INT_STATUS);
> + if (!data) {
> + sdhci_writel(host, stat, SDHCI_INT_STATUS);
Why do two write?
> + }
> break;
> - } while ((stat & mask) != mask);
> + }
> + }
>
> - if ((stat & (SDHCI_INT_ERROR | mask)) == mask) {
> - sdhci_cmd_done(host, cmd);
> - sdhci_writel(host, mask, SDHCI_INT_STATUS);
> - } else
> - ret = -1;
> + if (i == retry) {
> + printf("%s: waiting for status update\n",__func__);
> + return TIMEOUT;
> + }
> +
> + if (stat & SDHCI_INT_TIMEOUT) {
> + return TIMEOUT;
> + } else if (stat & SDHCI_INT_ERROR) {
> + return -1;
> + }
>
> - if (!ret && data)
> + if (data)
> ret = sdhci_transfer_data(host, data, start_addr);
>
> stat = sdhci_readl(host, SDHCI_INT_STATUS);
Thanks,
Lei
More information about the U-Boot
mailing list