diff mbox series

[V2,1/2] mmc: sdhci: Introduce max_timeout_count variable in sdhci_host

Message ID 1627534001-17256-2-git-send-email-sartgarg@codeaurora.org
State Superseded
Headers show
Series [V2,1/2] mmc: sdhci: Introduce max_timeout_count variable in sdhci_host | expand

Commit Message

Sarthak Garg July 29, 2021, 4:46 a.m. UTC
Introduce max_timeout_count variable in the sdhci_host structure
and use in timeout calculation. By default its set to 0xE
(max timeout register value as per SDHC spec). But at the same time
vendors drivers can update it if they support different max timeout
register value than 0xE.

Signed-off-by: Sarthak Garg <sartgarg@codeaurora.org>
---
 drivers/mmc/host/sdhci.c | 15 +++++++++------
 drivers/mmc/host/sdhci.h |  1 +
 2 files changed, 10 insertions(+), 6 deletions(-)

Comments

Adrian Hunter Aug. 3, 2021, 8:23 a.m. UTC | #1
On 29/07/21 7:46 am, Sarthak Garg wrote:
> Introduce max_timeout_count variable in the sdhci_host structure
> and use in timeout calculation. By default its set to 0xE
> (max timeout register value as per SDHC spec). But at the same time
> vendors drivers can update it if they support different max timeout
> register value than 0xE.

Looks fine.  A couple of minor comments below.

> 
> Signed-off-by: Sarthak Garg <sartgarg@codeaurora.org>
> ---
>  drivers/mmc/host/sdhci.c | 15 +++++++++------
>  drivers/mmc/host/sdhci.h |  1 +
>  2 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index aba6e10..2debda3 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -939,16 +939,16 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd,
>  	 * timeout value.
>  	 */
>  	if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
> -		return 0xE;
> +		return host->max_timeout_count;

Please adjust the comment above this that also refers to 0xE
e.g. "skip the check and use 0xE" -> "skip the check and use the maximum"

>  
>  	/* Unspecified command, asume max */
>  	if (cmd == NULL)
> -		return 0xE;
> +		return host->max_timeout_count;
>  
>  	data = cmd->data;
>  	/* Unspecified timeout, assume max */
>  	if (!data && !cmd->busy_timeout)
> -		return 0xE;
> +		return host->max_timeout_count;
>  
>  	/* timeout in us */
>  	target_timeout = sdhci_target_timeout(host, cmd, data);
> @@ -968,15 +968,15 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd,
>  	while (current_timeout < target_timeout) {
>  		count++;
>  		current_timeout <<= 1;
> -		if (count >= 0xF)
> +		if (count > host->max_timeout_count)
>  			break;
>  	}
>  
> -	if (count >= 0xF) {
> +	if (count > host->max_timeout_count) {
>  		if (!(host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT))
>  			DBG("Too large timeout 0x%x requested for CMD%d!\n",
>  			    count, cmd->opcode);
> -		count = 0xE;
> +		count = host->max_timeout_count;
>  	} else {
>  		*too_big = false;
>  	}
> @@ -3940,6 +3940,9 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
>  	 */
>  	host->adma_table_cnt = SDHCI_MAX_SEGS * 2 + 1;
>  
> +	if (!host->max_timeout_count)

'host' has just been (zero) allocated as part of 'mmc', so the 'if' is redundant here.

> +		host->max_timeout_count = 0xE;
> +
>  	return host;
>  }
>  
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 074dc18..e8d04e4 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -517,6 +517,7 @@ struct sdhci_host {
>  
>  	unsigned int max_clk;	/* Max possible freq (MHz) */
>  	unsigned int timeout_clk;	/* Timeout freq (KHz) */
> +	u8 max_timeout_count;	/* Vendor specific max timeout count */
>  	unsigned int clk_mul;	/* Clock Muliplier value */
>  
>  	unsigned int clock;	/* Current clock (MHz) */
>
Sarthak Garg Aug. 6, 2021, 6:54 a.m. UTC | #2
Introduce max_timeout_count in sdhci_host_struct to let vendor's modify
the max timeout value as per their needs.

Sahitya Tummala (1):
  mmc: sdhci-msm: Use maximum possible data timeout value

Sarthak Garg (1):
  mmc: sdhci: Introduce max_timeout_count variable in sdhci_host

 drivers/mmc/host/sdhci-msm.c |  3 +++
 drivers/mmc/host/sdhci.c     | 16 +++++++++-------
 drivers/mmc/host/sdhci.h     |  1 +
 3 files changed, 13 insertions(+), 7 deletions(-)
Adrian Hunter Aug. 6, 2021, 2:31 p.m. UTC | #3
On 6/08/21 9:55 am, Sarthak Garg wrote:
> From: Sahitya Tummala <stummala@codeaurora.org>

> 

> The Qcom SD controller defines the usage of 0xF in data

> timeout counter register (0x2E) which is actually a reserved

> bit as per specification. This would result in maximum of 21.26 secs

> timeout value.

> 

> Some SDcard taking more time than 2.67secs (timeout value corresponding

> to 0xE) and with that observed data timeout errors.

> So increasing the timeout value to max possible timeout.

> 

> Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>

> Signed-off-by: Sarthak Garg <sartgarg@codeaurora.org>


Acked-by: Adrian Hunter <adrian.hunter@intel.com>


> ---

>  drivers/mmc/host/sdhci-msm.c | 3 +++

>  1 file changed, 3 insertions(+)

> 

> diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c

> index e44b7a6..19e4673 100644

> --- a/drivers/mmc/host/sdhci-msm.c

> +++ b/drivers/mmc/host/sdhci-msm.c

> @@ -2696,6 +2696,9 @@ static int sdhci_msm_probe(struct platform_device *pdev)

>  

>  	msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;

>  

> +	/* Set the timeout value to max possible */

> +	host->max_timeout_count = 0xF;

> +

>  	pm_runtime_get_noresume(&pdev->dev);

>  	pm_runtime_set_active(&pdev->dev);

>  	pm_runtime_enable(&pdev->dev);

>
diff mbox series

Patch

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index aba6e10..2debda3 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -939,16 +939,16 @@  static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd,
 	 * timeout value.
 	 */
 	if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
-		return 0xE;
+		return host->max_timeout_count;
 
 	/* Unspecified command, asume max */
 	if (cmd == NULL)
-		return 0xE;
+		return host->max_timeout_count;
 
 	data = cmd->data;
 	/* Unspecified timeout, assume max */
 	if (!data && !cmd->busy_timeout)
-		return 0xE;
+		return host->max_timeout_count;
 
 	/* timeout in us */
 	target_timeout = sdhci_target_timeout(host, cmd, data);
@@ -968,15 +968,15 @@  static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd,
 	while (current_timeout < target_timeout) {
 		count++;
 		current_timeout <<= 1;
-		if (count >= 0xF)
+		if (count > host->max_timeout_count)
 			break;
 	}
 
-	if (count >= 0xF) {
+	if (count > host->max_timeout_count) {
 		if (!(host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT))
 			DBG("Too large timeout 0x%x requested for CMD%d!\n",
 			    count, cmd->opcode);
-		count = 0xE;
+		count = host->max_timeout_count;
 	} else {
 		*too_big = false;
 	}
@@ -3940,6 +3940,9 @@  struct sdhci_host *sdhci_alloc_host(struct device *dev,
 	 */
 	host->adma_table_cnt = SDHCI_MAX_SEGS * 2 + 1;
 
+	if (!host->max_timeout_count)
+		host->max_timeout_count = 0xE;
+
 	return host;
 }
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 074dc18..e8d04e4 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -517,6 +517,7 @@  struct sdhci_host {
 
 	unsigned int max_clk;	/* Max possible freq (MHz) */
 	unsigned int timeout_clk;	/* Timeout freq (KHz) */
+	u8 max_timeout_count;	/* Vendor specific max timeout count */
 	unsigned int clk_mul;	/* Clock Muliplier value */
 
 	unsigned int clock;	/* Current clock (MHz) */