All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zhang Haijun <b42677@freescale.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 7/7 V5] powerpc/esdhc: Update esdhc command execution process
Date: Fri, 10 Jan 2014 11:54:21 +0800	[thread overview]
Message-ID: <52CF6EED.2060805@freescale.com> (raw)
In-Reply-To: <D0D9A28D-66FE-4549-BE2C-B7870B532DBC@antoniou-consulting.com>

Hi, Pantelis

This patch is based on patch http://patchwork.ozlabs.org/patch/283002/

I'm afraid it was delegated to York by mistake.

Best regards,
Haijun

? 2014/1/9 19:08, Pantelis Antoniou ??:
> Hi Haijun,
>
> Patch does not apply.
>
> On Dec 30, 2013, at 10:20 AM, Haijun Zhang wrote:
>
>> The max timeout value esdhc host can accept is about 2.69 sec.
>> At 50 Mhz SD_CLK period, the max busy timeout
>> value = 2^27 * SD_CLK period ~= 2.69 sec.
>>
>> In case erase command CMD38 timeout is caculated  by
>> mult * 300ms * num(unit by erase group), so the time one erase
>> group need should be more than 300ms, 5000ms should be enough.
>>
>> 1. Add data reset procedure for data error and command with busy error.
>> 2. Add timeout value detecting during waiting for transfer complete.
>> 3. Ignore Command inhibit (DAT) state when excuting CMD12.
>> 4. Add command CRC error detecting.
>> 5. Enlarged the timeout value used for busy state release.
>>
>> Signed-off-by: Haijun Zhang <Haijun.Zhang@freescale.com>
>> ---
>> changes for V5:
>> 	- no changes
>>
>> drivers/mmc/fsl_esdhc.c | 164 +++++++++++++++++++++++++++++++-----------------
>> 1 file changed, 106 insertions(+), 58 deletions(-)
>>
>> diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
>> index 9f4d3a2..134a02d 100644
>> --- a/drivers/mmc/fsl_esdhc.c
>> +++ b/drivers/mmc/fsl_esdhc.c
>> @@ -266,26 +266,36 @@ static int
>> esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
>> {
>> 	uint	xfertyp;
>> -	uint	irqstat;
>> +	uint	irqstat = 0, mask;
>> 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
>> 	volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
>> +	int ret = 0, timeout;
>> +
>> +	esdhc_write32(&regs->irqstat, 0xffffffffU);
>> +
>> +	sync();
>> +
>> +	mask = PRSSTAT_CICHB | PRSSTAT_CIDHB;
>>
>> #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
>> 	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
>> 		return 0;
>> +#else
>> +	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
>> +		mask &= ~PRSSTAT_CIDHB;
>> #endif
>>
>> -	esdhc_write32(&regs->irqstat, -1);
>> -
>> -	sync();
>> -
>> 	/* Wait for the bus to be idle */
>> -	while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
>> -			(esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
>> -		;
>> -
>> -	while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
>> -		;
>> +	timeout = 1000;
>> +	while (esdhc_read32(&regs->prsstat) & mask) {
>> +		if (timeout == 0) {
>> +			printf("\nController never released inhibit bit(s).\n");
>> +			ret = COMM_ERR;
>> +			goto reset;
>> +		}
>> +		timeout--;
>> +		mdelay(1);
>> +	}
>>
>> 	/* Wait at least 8 SD clock cycles before the next command */
>> 	/*
>> @@ -296,11 +306,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
>>
>> 	/* Set up for a data transfer if we have one */
>> 	if (data) {
>> -		int err;
>> -
>> -		err = esdhc_setup_data(mmc, data);
>> -		if(err)
>> -			return err;
>> +		ret = esdhc_setup_data(mmc, data);
>> +		if (ret)
>> +			goto reset;
>> 	}
>>
>> 	/* Figure out the transfer arguments */
>> @@ -325,43 +333,14 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
>>
>> 	irqstat = esdhc_read32(&regs->irqstat);
>>
>> -	/* Reset CMD and DATA portions on error */
>> -	if (irqstat & CMD_ERR) {
>> -		esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
>> -			      SYSCTL_RSTC);
>> -		while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
>> -			;
>> -
>> -		if (data) {
>> -			esdhc_write32(&regs->sysctl,
>> -				      esdhc_read32(&regs->sysctl) |
>> -				      SYSCTL_RSTD);
>> -			while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
>> -				;
>> -		}
>> +	if (irqstat & IRQSTAT_CTOE) {
>> +		ret = TIMEOUT;
>> +		goto reset;
>> 	}
>>
>> -	if (irqstat & IRQSTAT_CTOE)
>> -		return TIMEOUT;
>> -
>> -	if (irqstat & CMD_ERR)
>> -		return COMM_ERR;
>> -
>> -	/* Workaround for ESDHC errata ENGcm03648 */
>> -	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
>> -		int timeout = 2500;
>> -
>> -		/* Poll on DATA0 line for cmd with busy signal for 250 ms */
>> -		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
>> -					PRSSTAT_DAT0)) {
>> -			udelay(100);
>> -			timeout--;
>> -		}
>> -
>> -		if (timeout <= 0) {
>> -			printf("Timeout waiting for DAT0 to go high!\n");
>> -			return TIMEOUT;
>> -		}
>> +	if (irqstat & CMD_ERR) {
>> +		ret = COMM_ERR;
>> +		goto reset;
>> 	}
>>
>> 	/* Copy the response to the response buffer */
>> @@ -379,7 +358,20 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
>> 	} else
>> 		cmd->response[0] = esdhc_read32(&regs->cmdrsp0);
>>
>> -	/* Wait until all of the blocks are transferred */
>> +	/*
>> +	 * At 50 Mhz SD_CLK period, the max busy timeout
>> +	 * value or data transfer time need was about
>> +	 * = 2^27 * SD_CLK period ~= 2.69 sec.
>> +	 * So wait max 10 sec for data transfer complete or busy
>> +	 * state release.
>> +	 */
>> +	timeout = 10000;
>> +
>> +	/*
>> +	 * eSDHC host V2.3 has response busy interrupt, so
>> +	 * we should wait for busy state to be released and data
>> +	 * was out of programing state before next command send.
>> +	 */
>> 	if (data) {
>> #ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
>> 		esdhc_pio_read_write(mmc, data);
>> @@ -387,20 +379,76 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
>> 		do {
>> 			irqstat = esdhc_read32(&regs->irqstat);
>>
>> -			if (irqstat & IRQSTAT_DTOE)
>> -				return TIMEOUT;
>> +			if (irqstat & IRQSTAT_DTOE) {
>> +				ret = TIMEOUT;
>> +				break;
>> +			}
>>
>> -			if (irqstat & DATA_ERR)
>> -				return COMM_ERR;
>> -		} while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
>> +			if (irqstat & DATA_ERR) {
>> +				ret = COMM_ERR;
>> +				break;
>> +			}
>> +
>> +			if (timeout <= 0) {
>> +				ret = TIMEOUT;
>> +				break;
>> +			}
>> +			mdelay(1);
>> +			timeout--;
>> +		} while (((irqstat & DATA_COMPLETE) != DATA_COMPLETE) &&
>> +				(esdhc_read32(&regs->prsstat) & PRSSTAT_DLA));
>> #endif
>> 		if (data->flags & MMC_DATA_READ)
>> 			check_and_invalidate_dcache_range(cmd, data);
>> 	}
>>
>> -	esdhc_write32(&regs->irqstat, -1);
>> +	 /* Workaround for ESDHC errata ENGcm03648 */
>> +	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
>> +		int timeout = 5000;
>> +
>> +		/* Poll on DATA0 line for cmd with busy signal for 5 sec */
>> +		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
>> +					PRSSTAT_DAT0)) {
>> +			mdelay(1);
>> +			timeout--;
>> +		}
>> +
>> +		if (timeout <= 0) {
>> +			printf("\nTimeout waiting for DAT0 to go high!\n");
>> +			ret = TIMEOUT;
>> +			goto reset;
>> +		}
>> +	}
>> +
>> +	if (esdhc_read32(&regs->irqstat) & (DATA_ERR | CMD_ERR))
>> +		ret = COMM_ERR;
>> +
>> +	if (ret)
>> +		goto reset;
>> +
>> +	esdhc_write32(&regs->irqstat, 0xffffffffU);
>>
>> 	return 0;
>> +
>> +reset:
>> +
>> +	/* Reset CMD and DATA portions on error */
>> +	esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
>> +			SYSCTL_RSTC);
>> +	while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
>> +		;
>> +
>> +	if (data || (cmd->resp_type & MMC_RSP_BUSY)) {
>> +		esdhc_write32(&regs->sysctl,
>> +			      esdhc_read32(&regs->sysctl) |
>> +			      SYSCTL_RSTD);
>> +		while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
>> +			;
>> +	}
>> +
>> +	esdhc_write32(&regs->irqstat, 0xffffffffU);
>> +
>> +	return ret;
>> }
>>
>> static void set_sysctl(struct mmc *mmc, uint clock)
>> -- 
>> 1.8.4.1
>>
>>
> Regards
>
> -- Pantelis
>
>
>

  reply	other threads:[~2014-01-10  3:54 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-30  8:20 [U-Boot] [PATCH 1/7 V5] mmc: Add some usefull macro definition Haijun Zhang
2013-12-30  8:20 ` [U-Boot] [PATCH 2/7 V5] mmc: Get secure erase information from card Haijun Zhang
2014-01-09 11:09   ` Pantelis Antoniou
2014-01-10  3:49     ` Zhang Haijun
2013-12-30  8:20 ` [U-Boot] [PATCH 3/7 V5] mmc: Enhance erase handling procedure Haijun Zhang
2013-12-30  8:20 ` [U-Boot] [PATCH 4/7 V5] mmc: Update the handling of returned erase block Haijun Zhang
2013-12-30  8:20 ` [U-Boot] [PATCH 5/7 V5] mmc: Enhance mmcinfo command Haijun Zhang
2013-12-30  8:20 ` [U-Boot] [PATCH 6/7 V5] Powerpc/esdhc: Add esdhc host version define Haijun Zhang
2013-12-30  8:20 ` [U-Boot] [PATCH 7/7 V5] powerpc/esdhc: Update esdhc command execution process Haijun Zhang
2014-01-09 11:08   ` Pantelis Antoniou
2014-01-10  3:54     ` Zhang Haijun [this message]
2014-01-06  3:09 ` [U-Boot] [PATCH 1/7 V5] mmc: Add some usefull macro definition Zhang Haijun
2014-02-24  1:18 ` Zhang Haijun

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52CF6EED.2060805@freescale.com \
    --to=b42677@freescale.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.