Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f37b20eb authored by Dong Aisheng's avatar Dong Aisheng Committed by Ulf Hansson
Browse files

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 repeatedly retuning during small file system
data access and improve the performance.

Signed-off-by: default avatarDong Aisheng <aisheng.dong@nxp.com>
Acked-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 152f05c7
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -229,6 +229,10 @@ 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_2 ||
	    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);

@@ -2673,6 +2677,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) {
			sdhci_enable_sdio_irq_nolock(host, false);
			host->thread_isr |= SDHCI_INT_CARD_INT;
@@ -2682,7 +2689,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
		intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE |
			     SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK |
			     SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER |
			     SDHCI_INT_CARD_INT);
			     SDHCI_INT_RETUNE | SDHCI_INT_CARD_INT);

		if (intmask) {
			unexpected |= intmask;
@@ -2787,6 +2794,7 @@ int sdhci_suspend_host(struct sdhci_host *host)
	sdhci_disable_card_detection(host);

	mmc_retune_timer_stop(host->mmc);
	if (host->tuning_mode != SDHCI_TUNING_MODE_3)
		mmc_retune_needed(host->mmc);

	if (!device_may_wakeup(mmc_dev(host->mmc))) {
@@ -2848,6 +2856,7 @@ int sdhci_runtime_suspend_host(struct sdhci_host *host)
	unsigned long flags;

	mmc_retune_timer_stop(host->mmc);
	if (host->tuning_mode != SDHCI_TUNING_MODE_3)
		mmc_retune_needed(host->mmc);

	spin_lock_irqsave(&host->lock, flags);
+3 −0
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@
#define  SDHCI_INT_CARD_INSERT	0x00000040
#define  SDHCI_INT_CARD_REMOVE	0x00000080
#define  SDHCI_INT_CARD_INT	0x00000100
#define  SDHCI_INT_RETUNE	0x00001000
#define  SDHCI_INT_ERROR	0x00008000
#define  SDHCI_INT_TIMEOUT	0x00010000
#define  SDHCI_INT_CRC		0x00020000
@@ -518,6 +519,8 @@ struct sdhci_host {
	unsigned int		tuning_count;	/* Timer count for re-tuning */
	unsigned int		tuning_mode;	/* Re-tuning mode supported by host */
#define SDHCI_TUNING_MODE_1	0
#define SDHCI_TUNING_MODE_2	1
#define SDHCI_TUNING_MODE_3	2

	unsigned long private[0] ____cacheline_aligned;
};