summaryrefslogtreecommitdiff
path: root/drivers/mmc/host/sdhci.c
diff options
context:
space:
mode:
authorDong Aisheng <aisheng.dong@nxp.com>2016-02-05 19:55:28 +0800
committerDong Aisheng <aisheng.dong@nxp.com>2016-02-16 15:49:16 +0800
commit89c224b34d3a63797d956969c2fdf4ccb7ff25bf (patch)
treeb3fb9596740ab47d13aee1ab3af1cc7a8d47ecb0 /drivers/mmc/host/sdhci.c
parentcfcd9c369186ddc8c9e25e7c7573f91a4516449d (diff)
MLK-12391-2 mmc: sdhci: add standard hw auto retuning support
If HW supports SDHCI_TUNING_MODE_3 which is auto retuning, we won't retune during runtime suspend and resume, instead we use Re-tuning Request signaled via SDHCI_INT_RETUNE interrupt to do retuning and hw auto retuning during data transfer to guarantee the signal sample window correction. This can avoid a mass of repeatly retuning during small file system data access and improve the performance. Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
Diffstat (limited to 'drivers/mmc/host/sdhci.c')
-rw-r--r--drivers/mmc/host/sdhci.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 35cb4535a150..b0c63b92366e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -240,6 +240,9 @@ static void sdhci_init(struct sdhci_host *host, int soft)
SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
SDHCI_INT_RESPONSE;
+ if (host->tuning_mode == SDHCI_TUNING_MODE_3)
+ host->ier |= SDHCI_INT_RETUNE;
+
sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
@@ -2599,6 +2602,9 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
pr_err("%s: Card is consuming too much power!\n",
mmc_hostname(host->mmc));
+ if (intmask & SDHCI_INT_RETUNE)
+ mmc_retune_needed(host->mmc);
+
if (intmask & SDHCI_INT_CARD_INT) {
if (host->mmc->caps2 & MMC_CAP2_SDIO_IRQ_NOTHREAD) {
sdhci_enable_sdio_irq_nolock(host, false);
@@ -2707,8 +2713,10 @@ int sdhci_suspend_host(struct sdhci_host *host)
{
sdhci_disable_card_detection(host);
- mmc_retune_timer_stop(host->mmc);
- mmc_retune_needed(host->mmc);
+ if (host->tuning_mode == SDHCI_TUNING_MODE_1) {
+ mmc_retune_timer_stop(host->mmc);
+ mmc_retune_needed(host->mmc);
+ }
if (!device_may_wakeup(mmc_dev(host->mmc))) {
host->ier = 0;
@@ -2794,8 +2802,10 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
{
unsigned long flags;
- mmc_retune_timer_stop(host->mmc);
- mmc_retune_needed(host->mmc);
+ if (host->tuning_mode == SDHCI_TUNING_MODE_1) {
+ mmc_retune_timer_stop(host->mmc);
+ mmc_retune_needed(host->mmc);
+ }
spin_lock_irqsave(&host->lock, flags);
host->ier &= SDHCI_INT_CARD_INT;