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: Dong Aisheng <aisheng.dong@nxp.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
		
							parent
							
								
									152f05c783
								
							
						
					
					
						commit
						f37b20ebc4
					
				| @ -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,7 +2794,8 @@ 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_3) | ||||
| 		mmc_retune_needed(host->mmc); | ||||
| 
 | ||||
| 	if (!device_may_wakeup(mmc_dev(host->mmc))) { | ||||
| 		host->ier = 0; | ||||
| @ -2848,7 +2856,8 @@ 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_3) | ||||
| 		mmc_retune_needed(host->mmc); | ||||
| 
 | ||||
| 	spin_lock_irqsave(&host->lock, flags); | ||||
| 	host->ier &= SDHCI_INT_CARD_INT; | ||||
|  | ||||
| @ -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; | ||||
| }; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user