Commit f829c042 authored by Ulf Hansson's avatar Ulf Hansson Committed by Russell King

ARM: 7833/1: mmc: mmci: Adapt to register write restrictions

After a write to the MMCICLOCK register data cannot be written to this
register for three feedback clock cycles. Writes to the MMCIPOWER
register must be separated by three MCLK cycles. Previously no issues
has been observered, but using higher ARM clock frequencies on STE-
platforms has triggered this problem.

The MMCICLOCK register is written to in .set_ios and for some data
transmissions for SDIO. We do not need a delay at the data transmission
path, because sending and receiving data will require more than three
clock cycles. Then we use a simple logic to only delay in .set_ios and
thus we don't affect throughput performance.
Signed-off-by: default avatarJohan Rudholm <jrudholm@gmail.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Acked-by: default avatarRickard Andersson <rickard.andersson@stericsson.com>
Reviewed-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent e36bd9c6
...@@ -189,6 +189,21 @@ static int mmci_validate_data(struct mmci_host *host, ...@@ -189,6 +189,21 @@ static int mmci_validate_data(struct mmci_host *host,
return 0; return 0;
} }
static void mmci_reg_delay(struct mmci_host *host)
{
/*
* According to the spec, at least three feedback clock cycles
* of max 52 MHz must pass between two writes to the MMCICLOCK reg.
* Three MCLK clock cycles must pass between two MMCIPOWER reg writes.
* Worst delay time during card init is at 100 kHz => 30 us.
* Worst delay time when up and running is at 25 MHz => 120 ns.
*/
if (host->cclk < 25000000)
udelay(30);
else
ndelay(120);
}
/* /*
* This must be called with host->lock held * This must be called with host->lock held
*/ */
...@@ -1264,6 +1279,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -1264,6 +1279,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
mmci_set_clkreg(host, ios->clock); mmci_set_clkreg(host, ios->clock);
mmci_write_pwrreg(host, pwr); mmci_write_pwrreg(host, pwr);
mmci_reg_delay(host);
spin_unlock_irqrestore(&host->lock, flags); spin_unlock_irqrestore(&host->lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment