[U-Boot] [PATCH] mmc: sdhci: Fix the SD clock stop sequence

According to the SDHC specification, stopping the SD Clock is by setting the SD Clock Enable bit in the Clock Control register at 0, instead of setting all bits at 0.
Before stopping the SD clock, we need to make sure all SD transactions to complete, so add checking the CMD and DAT bits in the Presen State register, before stopping the SD clock.
Signed-off-by: Wenyou Yang wenyou.yang@atmel.com ---
drivers/mmc/sdhci.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index d89e302..f02db4e 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -286,9 +286,15 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) { struct sdhci_host *host = mmc->priv; - unsigned int div, clk, timeout; + unsigned int div, clk, timeout, reg;
- sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); + while (sdhci_readl(host, SDHCI_PRESENT_STATE) & + (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)) + ; + + reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + reg &= ~SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL);
if (clock == 0) return 0;

Hi Wenyou,
On Sep 16, 2015, at 11:22 , Wenyou Yang wenyou.yang@atmel.com wrote:
According to the SDHC specification, stopping the SD Clock is by setting the SD Clock Enable bit in the Clock Control register at 0, instead of setting all bits at 0.
Before stopping the SD clock, we need to make sure all SD transactions to complete, so add checking the CMD and DAT bits in the Presen State register, before stopping the SD clock.
Signed-off-by: Wenyou Yang wenyou.yang@atmel.com
drivers/mmc/sdhci.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index d89e302..f02db4e 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -286,9 +286,15 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) { struct sdhci_host *host = mmc->priv;
- unsigned int div, clk, timeout;
- unsigned int div, clk, timeout, reg;
- sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
- while (sdhci_readl(host, SDHCI_PRESENT_STATE) &
(SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT))
;
Put a timeout here in case something is broken.
reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
reg &= ~SDHCI_CLOCK_CARD_EN;
sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL);
if (clock == 0) return 0;
-- 1.7.9.5
Regards
— Pantelis

Hi Pantelis,
-----Original Message----- From: Pantelis Antoniou [mailto:panto@antoniou-consulting.com] Sent: 2015年9月21日 23:36 To: Yang, Wenyou Cc: U-Boot Mailing List Subject: Re: [PATCH] mmc: sdhci: Fix the SD clock stop sequence
Hi Wenyou,
On Sep 16, 2015, at 11:22 , Wenyou Yang wenyou.yang@atmel.com wrote:
According to the SDHC specification, stopping the SD Clock is by setting the SD Clock Enable bit in the Clock Control register at 0, instead of setting all bits at 0.
Before stopping the SD clock, we need to make sure all SD transactions to complete, so add checking the CMD and DAT bits in the Presen State register, before stopping the SD clock.
Signed-off-by: Wenyou Yang wenyou.yang@atmel.com
drivers/mmc/sdhci.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index d89e302..f02db4e 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -286,9 +286,15 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) { struct sdhci_host *host = mmc->priv;
- unsigned int div, clk, timeout;
- unsigned int div, clk, timeout, reg;
- sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
- while (sdhci_readl(host, SDHCI_PRESENT_STATE) &
(SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT))
;
Put a timeout here in case something is broken.
The timeout is added in the version 2.
reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
reg &= ~SDHCI_CLOCK_CARD_EN;
sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL);
if (clock == 0) return 0;
-- 1.7.9.5
Regards
— Pantelis
Best Regards, Wenyou Yang
participants (3)
-
Pantelis Antoniou
-
Wenyou Yang
-
Yang, Wenyou