All of lore.kernel.org
 help / color / mirror / Atom feed
* [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions
@ 2016-12-26  9:46 Yangbo Lu
  2016-12-26  9:46 ` [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing Yangbo Lu
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Yangbo Lu @ 2016-12-26  9:46 UTC (permalink / raw)
  To: linux-mmc, ulf.hansson, Adrian Hunter; +Cc: Yangbo Lu

The eSDHC register definitions in header file were messy and confusing.
This patch is to clean up these definitions.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- added Adrian into to list
---
 drivers/mmc/host/sdhci-esdhc.h | 39 ++++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index de132e2..8cd8449 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -24,30 +24,31 @@
 				SDHCI_QUIRK_PIO_NEEDS_DELAY | \
 				SDHCI_QUIRK_NO_HISPD_BIT)
 
-#define ESDHC_PROCTL		0x28
-
-#define ESDHC_SYSTEM_CONTROL	0x2c
-#define ESDHC_CLOCK_MASK	0x0000fff0
-#define ESDHC_PREDIV_SHIFT	8
-#define ESDHC_DIVIDER_SHIFT	4
-#define ESDHC_CLOCK_PEREN	0x00000004
-#define ESDHC_CLOCK_HCKEN	0x00000002
-#define ESDHC_CLOCK_IPGEN	0x00000001
-
 /* pltfm-specific */
 #define ESDHC_HOST_CONTROL_LE	0x20
 
 /*
- * P2020 interpretation of the SDHCI_HOST_CONTROL register
+ * eSDHC register definition
  */
-#define ESDHC_CTRL_4BITBUS          (0x1 << 1)
-#define ESDHC_CTRL_8BITBUS          (0x2 << 1)
-#define ESDHC_CTRL_BUSWIDTH_MASK    (0x3 << 1)
-
-/* OF-specific */
-#define ESDHC_DMA_SYSCTL	0x40c
-#define ESDHC_DMA_SNOOP		0x00000040
 
-#define ESDHC_HOST_CONTROL_RES	0x01
+/* Protocol Control Register */
+#define ESDHC_PROCTL			0x28
+#define ESDHC_CTRL_4BITBUS		(0x1 << 1)
+#define ESDHC_CTRL_8BITBUS		(0x2 << 1)
+#define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
+#define ESDHC_HOST_CONTROL_RES		0x01
+
+/* System Control Register */
+#define ESDHC_SYSTEM_CONTROL		0x2c
+#define ESDHC_CLOCK_MASK		0x0000fff0
+#define ESDHC_PREDIV_SHIFT		8
+#define ESDHC_DIVIDER_SHIFT		4
+#define ESDHC_CLOCK_PEREN		0x00000004
+#define ESDHC_CLOCK_HCKEN		0x00000002
+#define ESDHC_CLOCK_IPGEN		0x00000001
+
+/* Control Register for DMA transfer */
+#define ESDHC_DMA_SYSCTL		0x40c
+#define ESDHC_DMA_SNOOP			0x00000040
 
 #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing
  2016-12-26  9:46 [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Yangbo Lu
@ 2016-12-26  9:46 ` Yangbo Lu
  2017-01-12  7:09   ` Adrian Hunter
                     ` (2 more replies)
  2017-01-12  1:32 ` [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Y.B. Lu
                   ` (2 subsequent siblings)
  3 siblings, 3 replies; 10+ messages in thread
From: Yangbo Lu @ 2016-12-26  9:46 UTC (permalink / raw)
  To: linux-mmc, ulf.hansson, Adrian Hunter; +Cc: Yangbo Lu

The eSDHC_PRSSTAT[SDSTB] bit indicates whether the internal card clock is
stable. This bit is for the host driver to poll clock status when changing
the clock frequency. It is recommended to clear eSDHC_SYSCTL[SDCLKEN]
to remove glitch on the card clock when the frequency is changing. This
patch is to disable SDCLKEN bit before changing frequency and enable it
after SDSTB bit is set.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- added Adrian into to list
---
 drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
 drivers/mmc/host/sdhci-of-esdhc.c | 21 ++++++++++++++++++---
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index 8cd8449..ece8b37 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -31,6 +31,10 @@
  * eSDHC register definition
  */
 
+/* Present State Register */
+#define ESDHC_PRSSTAT			0x24
+#define ESDHC_CLOCK_STABLE		0x00000008
+
 /* Protocol Control Register */
 #define ESDHC_PROCTL			0x28
 #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
@@ -43,6 +47,7 @@
 #define ESDHC_CLOCK_MASK		0x0000fff0
 #define ESDHC_PREDIV_SHIFT		8
 #define ESDHC_DIVIDER_SHIFT		4
+#define ESDHC_CLOCK_SDCLKEN		0x00000008
 #define ESDHC_CLOCK_PEREN		0x00000004
 #define ESDHC_CLOCK_HCKEN		0x00000002
 #define ESDHC_CLOCK_IPGEN		0x00000001
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 9a6eb44..0849885 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -431,6 +431,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
 	int pre_div = 1;
 	int div = 1;
+	u32 timeout;
 	u32 temp;
 
 	host->mmc->actual_clock = 0;
@@ -451,8 +452,8 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 	}
 
 	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
-	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
-		| ESDHC_CLOCK_MASK);
+	temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
+		  ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
 	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
 
 	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
@@ -472,7 +473,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
 		| (div << ESDHC_DIVIDER_SHIFT)
 		| (pre_div << ESDHC_PREDIV_SHIFT));
 	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
-	mdelay(1);
+
+	/* Wait max 20 ms */
+	timeout = 20;
+	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
+		if (timeout == 0) {
+			pr_err("%s: Internal clock never stabilised.\n",
+				mmc_hostname(host->mmc));
+			return;
+		}
+		timeout--;
+		mdelay(1);
+	}
+
+	temp |= ESDHC_CLOCK_SDCLKEN;
+	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
 }
 
 static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* RE: [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions
  2016-12-26  9:46 [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Yangbo Lu
  2016-12-26  9:46 ` [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing Yangbo Lu
@ 2017-01-12  1:32 ` Y.B. Lu
  2017-01-12  6:55 ` Adrian Hunter
  2017-01-12 10:58 ` Ulf Hansson
  3 siblings, 0 replies; 10+ messages in thread
From: Y.B. Lu @ 2017-01-12  1:32 UTC (permalink / raw)
  To: Y.B. Lu, linux-mmc, ulf.hansson, Adrian Hunter

Hi Adrian and Uffe,

Could you give comments on these two patches?
Thank you very much. :)


Best regards,
Yangbo Lu

> -----Original Message-----
> From: Yangbo Lu [mailto:yangbo.lu@nxp.com]
> Sent: Monday, December 26, 2016 5:46 PM
> To: linux-mmc@vger.kernel.org; ulf.hansson@linaro.org; Adrian Hunter
> Cc: Y.B. Lu
> Subject: [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions
> 
> The eSDHC register definitions in header file were messy and confusing.
> This patch is to clean up these definitions.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> ---
> Changes for v2:
> 	- added Adrian into to list
> ---
>  drivers/mmc/host/sdhci-esdhc.h | 39 ++++++++++++++++++++----------------
> ---
>  1 file changed, 20 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-
> esdhc.h index de132e2..8cd8449 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -24,30 +24,31 @@
>  				SDHCI_QUIRK_PIO_NEEDS_DELAY | \
>  				SDHCI_QUIRK_NO_HISPD_BIT)
> 
> -#define ESDHC_PROCTL		0x28
> -
> -#define ESDHC_SYSTEM_CONTROL	0x2c
> -#define ESDHC_CLOCK_MASK	0x0000fff0
> -#define ESDHC_PREDIV_SHIFT	8
> -#define ESDHC_DIVIDER_SHIFT	4
> -#define ESDHC_CLOCK_PEREN	0x00000004
> -#define ESDHC_CLOCK_HCKEN	0x00000002
> -#define ESDHC_CLOCK_IPGEN	0x00000001
> -
>  /* pltfm-specific */
>  #define ESDHC_HOST_CONTROL_LE	0x20
> 
>  /*
> - * P2020 interpretation of the SDHCI_HOST_CONTROL register
> + * eSDHC register definition
>   */
> -#define ESDHC_CTRL_4BITBUS          (0x1 << 1)
> -#define ESDHC_CTRL_8BITBUS          (0x2 << 1)
> -#define ESDHC_CTRL_BUSWIDTH_MASK    (0x3 << 1)
> -
> -/* OF-specific */
> -#define ESDHC_DMA_SYSCTL	0x40c
> -#define ESDHC_DMA_SNOOP		0x00000040
> 
> -#define ESDHC_HOST_CONTROL_RES	0x01
> +/* Protocol Control Register */
> +#define ESDHC_PROCTL			0x28
> +#define ESDHC_CTRL_4BITBUS		(0x1 << 1)
> +#define ESDHC_CTRL_8BITBUS		(0x2 << 1)
> +#define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
> +#define ESDHC_HOST_CONTROL_RES		0x01
> +
> +/* System Control Register */
> +#define ESDHC_SYSTEM_CONTROL		0x2c
> +#define ESDHC_CLOCK_MASK		0x0000fff0
> +#define ESDHC_PREDIV_SHIFT		8
> +#define ESDHC_DIVIDER_SHIFT		4
> +#define ESDHC_CLOCK_PEREN		0x00000004
> +#define ESDHC_CLOCK_HCKEN		0x00000002
> +#define ESDHC_CLOCK_IPGEN		0x00000001
> +
> +/* Control Register for DMA transfer */
> +#define ESDHC_DMA_SYSCTL		0x40c
> +#define ESDHC_DMA_SNOOP			0x00000040
> 
>  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
> --
> 2.1.0.27.g96db324


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions
  2016-12-26  9:46 [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Yangbo Lu
  2016-12-26  9:46 ` [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing Yangbo Lu
  2017-01-12  1:32 ` [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Y.B. Lu
@ 2017-01-12  6:55 ` Adrian Hunter
  2017-01-12 10:58 ` Ulf Hansson
  3 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2017-01-12  6:55 UTC (permalink / raw)
  To: Yangbo Lu, linux-mmc, ulf.hansson

On 26/12/16 11:46, Yangbo Lu wrote:
> The eSDHC register definitions in header file were messy and confusing.
> This patch is to clean up these definitions.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

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

> ---
> Changes for v2:
> 	- added Adrian into to list
> ---
>  drivers/mmc/host/sdhci-esdhc.h | 39 ++++++++++++++++++++-------------------
>  1 file changed, 20 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index de132e2..8cd8449 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -24,30 +24,31 @@
>  				SDHCI_QUIRK_PIO_NEEDS_DELAY | \
>  				SDHCI_QUIRK_NO_HISPD_BIT)
>  
> -#define ESDHC_PROCTL		0x28
> -
> -#define ESDHC_SYSTEM_CONTROL	0x2c
> -#define ESDHC_CLOCK_MASK	0x0000fff0
> -#define ESDHC_PREDIV_SHIFT	8
> -#define ESDHC_DIVIDER_SHIFT	4
> -#define ESDHC_CLOCK_PEREN	0x00000004
> -#define ESDHC_CLOCK_HCKEN	0x00000002
> -#define ESDHC_CLOCK_IPGEN	0x00000001
> -
>  /* pltfm-specific */
>  #define ESDHC_HOST_CONTROL_LE	0x20
>  
>  /*
> - * P2020 interpretation of the SDHCI_HOST_CONTROL register
> + * eSDHC register definition
>   */
> -#define ESDHC_CTRL_4BITBUS          (0x1 << 1)
> -#define ESDHC_CTRL_8BITBUS          (0x2 << 1)
> -#define ESDHC_CTRL_BUSWIDTH_MASK    (0x3 << 1)
> -
> -/* OF-specific */
> -#define ESDHC_DMA_SYSCTL	0x40c
> -#define ESDHC_DMA_SNOOP		0x00000040
>  
> -#define ESDHC_HOST_CONTROL_RES	0x01
> +/* Protocol Control Register */
> +#define ESDHC_PROCTL			0x28
> +#define ESDHC_CTRL_4BITBUS		(0x1 << 1)
> +#define ESDHC_CTRL_8BITBUS		(0x2 << 1)
> +#define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
> +#define ESDHC_HOST_CONTROL_RES		0x01
> +
> +/* System Control Register */
> +#define ESDHC_SYSTEM_CONTROL		0x2c
> +#define ESDHC_CLOCK_MASK		0x0000fff0
> +#define ESDHC_PREDIV_SHIFT		8
> +#define ESDHC_DIVIDER_SHIFT		4
> +#define ESDHC_CLOCK_PEREN		0x00000004
> +#define ESDHC_CLOCK_HCKEN		0x00000002
> +#define ESDHC_CLOCK_IPGEN		0x00000001
> +
> +/* Control Register for DMA transfer */
> +#define ESDHC_DMA_SYSCTL		0x40c
> +#define ESDHC_DMA_SNOOP			0x00000040
>  
>  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing
  2016-12-26  9:46 ` [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing Yangbo Lu
@ 2017-01-12  7:09   ` Adrian Hunter
  2017-01-13  2:12     ` Y.B. Lu
  2017-01-13  9:30   ` Adrian Hunter
  2017-01-17 15:07   ` Ulf Hansson
  2 siblings, 1 reply; 10+ messages in thread
From: Adrian Hunter @ 2017-01-12  7:09 UTC (permalink / raw)
  To: Yangbo Lu, linux-mmc, ulf.hansson

On 26/12/16 11:46, Yangbo Lu wrote:
> The eSDHC_PRSSTAT[SDSTB] bit indicates whether the internal card clock is
> stable. This bit is for the host driver to poll clock status when changing
> the clock frequency. It is recommended to clear eSDHC_SYSCTL[SDCLKEN]
> to remove glitch on the card clock when the frequency is changing. This
> patch is to disable SDCLKEN bit before changing frequency and enable it
> after SDSTB bit is set.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> ---
> Changes for v2:
> 	- added Adrian into to list
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
>  drivers/mmc/host/sdhci-of-esdhc.c | 21 ++++++++++++++++++---
>  2 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 8cd8449..ece8b37 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -31,6 +31,10 @@
>   * eSDHC register definition
>   */
>  
> +/* Present State Register */
> +#define ESDHC_PRSSTAT			0x24
> +#define ESDHC_CLOCK_STABLE		0x00000008
> +
>  /* Protocol Control Register */
>  #define ESDHC_PROCTL			0x28
>  #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
> @@ -43,6 +47,7 @@
>  #define ESDHC_CLOCK_MASK		0x0000fff0
>  #define ESDHC_PREDIV_SHIFT		8
>  #define ESDHC_DIVIDER_SHIFT		4
> +#define ESDHC_CLOCK_SDCLKEN		0x00000008
>  #define ESDHC_CLOCK_PEREN		0x00000004
>  #define ESDHC_CLOCK_HCKEN		0x00000002
>  #define ESDHC_CLOCK_IPGEN		0x00000001
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 9a6eb44..0849885 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -431,6 +431,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>  	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
>  	int pre_div = 1;
>  	int div = 1;
> +	u32 timeout;
>  	u32 temp;
>  
>  	host->mmc->actual_clock = 0;
> @@ -451,8 +452,8 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>  	}
>  
>  	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> -	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
> -		| ESDHC_CLOCK_MASK);
> +	temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
> +		  ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
>  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
>  
>  	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
> @@ -472,7 +473,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>  		| (div << ESDHC_DIVIDER_SHIFT)
>  		| (pre_div << ESDHC_PREDIV_SHIFT));
>  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
> -	mdelay(1);
> +
> +	/* Wait max 20 ms */
> +	timeout = 20;
> +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
> +		if (timeout == 0) {
> +			pr_err("%s: Internal clock never stabilised.\n",
> +				mmc_hostname(host->mmc));
> +			return;
> +		}
> +		timeout--;
> +		mdelay(1);
> +	}

Please try to do this with readx_poll_timeout_atomic().  However we are not
racing with anything (and one of the things that needs doing in SDHCI is to
reduce the use of the spin lock) so you could drop the spin lock while using
readx_poll_timeout() instead.

> +
> +	temp |= ESDHC_CLOCK_SDCLKEN;
> +	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
>  }
>  
>  static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions
  2016-12-26  9:46 [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Yangbo Lu
                   ` (2 preceding siblings ...)
  2017-01-12  6:55 ` Adrian Hunter
@ 2017-01-12 10:58 ` Ulf Hansson
  3 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2017-01-12 10:58 UTC (permalink / raw)
  To: Yangbo Lu; +Cc: linux-mmc, Adrian Hunter

On 26 December 2016 at 10:46, Yangbo Lu <yangbo.lu@nxp.com> wrote:
> The eSDHC register definitions in header file were messy and confusing.
> This patch is to clean up these definitions.
>
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
> Changes for v2:
>         - added Adrian into to list
> ---
>  drivers/mmc/host/sdhci-esdhc.h | 39 ++++++++++++++++++++-------------------
>  1 file changed, 20 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index de132e2..8cd8449 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -24,30 +24,31 @@
>                                 SDHCI_QUIRK_PIO_NEEDS_DELAY | \
>                                 SDHCI_QUIRK_NO_HISPD_BIT)
>
> -#define ESDHC_PROCTL           0x28
> -
> -#define ESDHC_SYSTEM_CONTROL   0x2c
> -#define ESDHC_CLOCK_MASK       0x0000fff0
> -#define ESDHC_PREDIV_SHIFT     8
> -#define ESDHC_DIVIDER_SHIFT    4
> -#define ESDHC_CLOCK_PEREN      0x00000004
> -#define ESDHC_CLOCK_HCKEN      0x00000002
> -#define ESDHC_CLOCK_IPGEN      0x00000001
> -
>  /* pltfm-specific */
>  #define ESDHC_HOST_CONTROL_LE  0x20
>
>  /*
> - * P2020 interpretation of the SDHCI_HOST_CONTROL register
> + * eSDHC register definition
>   */
> -#define ESDHC_CTRL_4BITBUS          (0x1 << 1)
> -#define ESDHC_CTRL_8BITBUS          (0x2 << 1)
> -#define ESDHC_CTRL_BUSWIDTH_MASK    (0x3 << 1)
> -
> -/* OF-specific */
> -#define ESDHC_DMA_SYSCTL       0x40c
> -#define ESDHC_DMA_SNOOP                0x00000040
>
> -#define ESDHC_HOST_CONTROL_RES 0x01
> +/* Protocol Control Register */
> +#define ESDHC_PROCTL                   0x28
> +#define ESDHC_CTRL_4BITBUS             (0x1 << 1)
> +#define ESDHC_CTRL_8BITBUS             (0x2 << 1)
> +#define ESDHC_CTRL_BUSWIDTH_MASK       (0x3 << 1)
> +#define ESDHC_HOST_CONTROL_RES         0x01
> +
> +/* System Control Register */
> +#define ESDHC_SYSTEM_CONTROL           0x2c
> +#define ESDHC_CLOCK_MASK               0x0000fff0
> +#define ESDHC_PREDIV_SHIFT             8
> +#define ESDHC_DIVIDER_SHIFT            4
> +#define ESDHC_CLOCK_PEREN              0x00000004
> +#define ESDHC_CLOCK_HCKEN              0x00000002
> +#define ESDHC_CLOCK_IPGEN              0x00000001
> +
> +/* Control Register for DMA transfer */
> +#define ESDHC_DMA_SYSCTL               0x40c
> +#define ESDHC_DMA_SNOOP                        0x00000040
>
>  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
> --
> 2.1.0.27.g96db324
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing
  2017-01-12  7:09   ` Adrian Hunter
@ 2017-01-13  2:12     ` Y.B. Lu
  2017-01-13  9:31       ` Adrian Hunter
  0 siblings, 1 reply; 10+ messages in thread
From: Y.B. Lu @ 2017-01-13  2:12 UTC (permalink / raw)
  To: Adrian Hunter, linux-mmc, ulf.hansson

Hi Adrian,

Thanks a lot for reviewing my patches.
Please see my comments inline.

Best regards,
Yangbo Lu

> -----Original Message-----
> From: Adrian Hunter [mailto:adrian.hunter@intel.com]
> Sent: Thursday, January 12, 2017 3:09 PM
> To: Y.B. Lu; linux-mmc@vger.kernel.org; ulf.hansson@linaro.org
> Subject: Re: [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when
> frequency is changing
> 
> On 26/12/16 11:46, Yangbo Lu wrote:
> > The eSDHC_PRSSTAT[SDSTB] bit indicates whether the internal card clock
> > is stable. This bit is for the host driver to poll clock status when
> > changing the clock frequency. It is recommended to clear
> > eSDHC_SYSCTL[SDCLKEN] to remove glitch on the card clock when the
> > frequency is changing. This patch is to disable SDCLKEN bit before
> > changing frequency and enable it after SDSTB bit is set.
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> > ---
> > Changes for v2:
> > 	- added Adrian into to list
> > ---
> >  drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
> >  drivers/mmc/host/sdhci-of-esdhc.c | 21 ++++++++++++++++++---
> >  2 files changed, 23 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc.h
> > b/drivers/mmc/host/sdhci-esdhc.h index 8cd8449..ece8b37 100644
> > --- a/drivers/mmc/host/sdhci-esdhc.h
> > +++ b/drivers/mmc/host/sdhci-esdhc.h
> > @@ -31,6 +31,10 @@
> >   * eSDHC register definition
> >   */
> >
> > +/* Present State Register */
> > +#define ESDHC_PRSSTAT			0x24
> > +#define ESDHC_CLOCK_STABLE		0x00000008
> > +
> >  /* Protocol Control Register */
> >  #define ESDHC_PROCTL			0x28
> >  #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
> > @@ -43,6 +47,7 @@
> >  #define ESDHC_CLOCK_MASK		0x0000fff0
> >  #define ESDHC_PREDIV_SHIFT		8
> >  #define ESDHC_DIVIDER_SHIFT		4
> > +#define ESDHC_CLOCK_SDCLKEN		0x00000008
> >  #define ESDHC_CLOCK_PEREN		0x00000004
> >  #define ESDHC_CLOCK_HCKEN		0x00000002
> >  #define ESDHC_CLOCK_IPGEN		0x00000001
> > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
> > b/drivers/mmc/host/sdhci-of-esdhc.c
> > index 9a6eb44..0849885 100644
> > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > @@ -431,6 +431,7 @@ static void esdhc_of_set_clock(struct sdhci_host
> *host, unsigned int clock)
> >  	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> >  	int pre_div = 1;
> >  	int div = 1;
> > +	u32 timeout;
> >  	u32 temp;
> >
> >  	host->mmc->actual_clock = 0;
> > @@ -451,8 +452,8 @@ static void esdhc_of_set_clock(struct sdhci_host
> *host, unsigned int clock)
> >  	}
> >
> >  	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> > -	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
> > -		| ESDHC_CLOCK_MASK);
> > +	temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN |
> ESDHC_CLOCK_HCKEN |
> > +		  ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
> >  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
> >
> >  	while (host->max_clk / pre_div / 16 > clock && pre_div < 256) @@
> > -472,7 +473,21 @@ static void esdhc_of_set_clock(struct sdhci_host
> *host, unsigned int clock)
> >  		| (div << ESDHC_DIVIDER_SHIFT)
> >  		| (pre_div << ESDHC_PREDIV_SHIFT));
> >  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
> > -	mdelay(1);
> > +
> > +	/* Wait max 20 ms */
> > +	timeout = 20;
> > +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
> > +		if (timeout == 0) {
> > +			pr_err("%s: Internal clock never stabilised.\n",
> > +				mmc_hostname(host->mmc));
> > +			return;
> > +		}
> > +		timeout--;
> > +		mdelay(1);
> > +	}
> 
> Please try to do this with readx_poll_timeout_atomic().  However we are
> not racing with anything (and one of the things that needs doing in SDHCI
> is to reduce the use of the spin lock) so you could drop the spin lock
> while using
> readx_poll_timeout() instead.
> 

[Lu Yangbo-B47093] The function readx_poll_timeout_atomic() periodically polls an address, but the addr must be
the only argument for op. Our sdhci_readl has two arguments. Any suggestion for this?

readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us)

Thanks :)


> > +
> > +	temp |= ESDHC_CLOCK_SDCLKEN;
> > +	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
> >  }
> >
> >  static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int
> > width)
> >


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing
  2016-12-26  9:46 ` [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing Yangbo Lu
  2017-01-12  7:09   ` Adrian Hunter
@ 2017-01-13  9:30   ` Adrian Hunter
  2017-01-17 15:07   ` Ulf Hansson
  2 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2017-01-13  9:30 UTC (permalink / raw)
  To: Yangbo Lu, linux-mmc, ulf.hansson

On 26/12/16 11:46, Yangbo Lu wrote:
> The eSDHC_PRSSTAT[SDSTB] bit indicates whether the internal card clock is
> stable. This bit is for the host driver to poll clock status when changing
> the clock frequency. It is recommended to clear eSDHC_SYSCTL[SDCLKEN]
> to remove glitch on the card clock when the frequency is changing. This
> patch is to disable SDCLKEN bit before changing frequency and enable it
> after SDSTB bit is set.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

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

> ---
> Changes for v2:
> 	- added Adrian into to list
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
>  drivers/mmc/host/sdhci-of-esdhc.c | 21 ++++++++++++++++++---
>  2 files changed, 23 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 8cd8449..ece8b37 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -31,6 +31,10 @@
>   * eSDHC register definition
>   */
>  
> +/* Present State Register */
> +#define ESDHC_PRSSTAT			0x24
> +#define ESDHC_CLOCK_STABLE		0x00000008
> +
>  /* Protocol Control Register */
>  #define ESDHC_PROCTL			0x28
>  #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
> @@ -43,6 +47,7 @@
>  #define ESDHC_CLOCK_MASK		0x0000fff0
>  #define ESDHC_PREDIV_SHIFT		8
>  #define ESDHC_DIVIDER_SHIFT		4
> +#define ESDHC_CLOCK_SDCLKEN		0x00000008
>  #define ESDHC_CLOCK_PEREN		0x00000004
>  #define ESDHC_CLOCK_HCKEN		0x00000002
>  #define ESDHC_CLOCK_IPGEN		0x00000001
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 9a6eb44..0849885 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -431,6 +431,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>  	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
>  	int pre_div = 1;
>  	int div = 1;
> +	u32 timeout;
>  	u32 temp;
>  
>  	host->mmc->actual_clock = 0;
> @@ -451,8 +452,8 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>  	}
>  
>  	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> -	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
> -		| ESDHC_CLOCK_MASK);
> +	temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
> +		  ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
>  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
>  
>  	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
> @@ -472,7 +473,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>  		| (div << ESDHC_DIVIDER_SHIFT)
>  		| (pre_div << ESDHC_PREDIV_SHIFT));
>  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
> -	mdelay(1);
> +
> +	/* Wait max 20 ms */
> +	timeout = 20;
> +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
> +		if (timeout == 0) {
> +			pr_err("%s: Internal clock never stabilised.\n",
> +				mmc_hostname(host->mmc));
> +			return;
> +		}
> +		timeout--;
> +		mdelay(1);
> +	}
> +
> +	temp |= ESDHC_CLOCK_SDCLKEN;
> +	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
>  }
>  
>  static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing
  2017-01-13  2:12     ` Y.B. Lu
@ 2017-01-13  9:31       ` Adrian Hunter
  0 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2017-01-13  9:31 UTC (permalink / raw)
  To: Y.B. Lu, linux-mmc, ulf.hansson

On 13/01/17 04:12, Y.B. Lu wrote:
> Hi Adrian,
> 
> Thanks a lot for reviewing my patches.
> Please see my comments inline.
> 
> Best regards,
> Yangbo Lu
> 
>> -----Original Message-----
>> From: Adrian Hunter [mailto:adrian.hunter@intel.com]
>> Sent: Thursday, January 12, 2017 3:09 PM
>> To: Y.B. Lu; linux-mmc@vger.kernel.org; ulf.hansson@linaro.org
>> Subject: Re: [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when
>> frequency is changing
>>
>> On 26/12/16 11:46, Yangbo Lu wrote:
>>> The eSDHC_PRSSTAT[SDSTB] bit indicates whether the internal card clock
>>> is stable. This bit is for the host driver to poll clock status when
>>> changing the clock frequency. It is recommended to clear
>>> eSDHC_SYSCTL[SDCLKEN] to remove glitch on the card clock when the
>>> frequency is changing. This patch is to disable SDCLKEN bit before
>>> changing frequency and enable it after SDSTB bit is set.
>>>
>>> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
>>> ---
>>> Changes for v2:
>>> 	- added Adrian into to list
>>> ---
>>>  drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
>>>  drivers/mmc/host/sdhci-of-esdhc.c | 21 ++++++++++++++++++---
>>>  2 files changed, 23 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/mmc/host/sdhci-esdhc.h
>>> b/drivers/mmc/host/sdhci-esdhc.h index 8cd8449..ece8b37 100644
>>> --- a/drivers/mmc/host/sdhci-esdhc.h
>>> +++ b/drivers/mmc/host/sdhci-esdhc.h
>>> @@ -31,6 +31,10 @@
>>>   * eSDHC register definition
>>>   */
>>>
>>> +/* Present State Register */
>>> +#define ESDHC_PRSSTAT			0x24
>>> +#define ESDHC_CLOCK_STABLE		0x00000008
>>> +
>>>  /* Protocol Control Register */
>>>  #define ESDHC_PROCTL			0x28
>>>  #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
>>> @@ -43,6 +47,7 @@
>>>  #define ESDHC_CLOCK_MASK		0x0000fff0
>>>  #define ESDHC_PREDIV_SHIFT		8
>>>  #define ESDHC_DIVIDER_SHIFT		4
>>> +#define ESDHC_CLOCK_SDCLKEN		0x00000008
>>>  #define ESDHC_CLOCK_PEREN		0x00000004
>>>  #define ESDHC_CLOCK_HCKEN		0x00000002
>>>  #define ESDHC_CLOCK_IPGEN		0x00000001
>>> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
>>> b/drivers/mmc/host/sdhci-of-esdhc.c
>>> index 9a6eb44..0849885 100644
>>> --- a/drivers/mmc/host/sdhci-of-esdhc.c
>>> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
>>> @@ -431,6 +431,7 @@ static void esdhc_of_set_clock(struct sdhci_host
>> *host, unsigned int clock)
>>>  	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
>>>  	int pre_div = 1;
>>>  	int div = 1;
>>> +	u32 timeout;
>>>  	u32 temp;
>>>
>>>  	host->mmc->actual_clock = 0;
>>> @@ -451,8 +452,8 @@ static void esdhc_of_set_clock(struct sdhci_host
>> *host, unsigned int clock)
>>>  	}
>>>
>>>  	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
>>> -	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
>>> -		| ESDHC_CLOCK_MASK);
>>> +	temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN |
>> ESDHC_CLOCK_HCKEN |
>>> +		  ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
>>>  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
>>>
>>>  	while (host->max_clk / pre_div / 16 > clock && pre_div < 256) @@
>>> -472,7 +473,21 @@ static void esdhc_of_set_clock(struct sdhci_host
>> *host, unsigned int clock)
>>>  		| (div << ESDHC_DIVIDER_SHIFT)
>>>  		| (pre_div << ESDHC_PREDIV_SHIFT));
>>>  	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
>>> -	mdelay(1);
>>> +
>>> +	/* Wait max 20 ms */
>>> +	timeout = 20;
>>> +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
>>> +		if (timeout == 0) {
>>> +			pr_err("%s: Internal clock never stabilised.\n",
>>> +				mmc_hostname(host->mmc));
>>> +			return;
>>> +		}
>>> +		timeout--;
>>> +		mdelay(1);
>>> +	}
>>
>> Please try to do this with readx_poll_timeout_atomic().  However we are
>> not racing with anything (and one of the things that needs doing in SDHCI
>> is to reduce the use of the spin lock) so you could drop the spin lock
>> while using
>> readx_poll_timeout() instead.
>>
> 
> [Lu Yangbo-B47093] The function readx_poll_timeout_atomic() periodically polls an address, but the addr must be
> the only argument for op. Our sdhci_readl has two arguments. Any suggestion for this?
> 
> readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us)

Yeah, I forgot about that, sorry.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing
  2016-12-26  9:46 ` [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing Yangbo Lu
  2017-01-12  7:09   ` Adrian Hunter
  2017-01-13  9:30   ` Adrian Hunter
@ 2017-01-17 15:07   ` Ulf Hansson
  2 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2017-01-17 15:07 UTC (permalink / raw)
  To: Yangbo Lu; +Cc: linux-mmc, Adrian Hunter

On 26 December 2016 at 10:46, Yangbo Lu <yangbo.lu@nxp.com> wrote:
> The eSDHC_PRSSTAT[SDSTB] bit indicates whether the internal card clock is
> stable. This bit is for the host driver to poll clock status when changing
> the clock frequency. It is recommended to clear eSDHC_SYSCTL[SDCLKEN]
> to remove glitch on the card clock when the frequency is changing. This
> patch is to disable SDCLKEN bit before changing frequency and enable it
> after SDSTB bit is set.
>
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
> Changes for v2:
>         - added Adrian into to list
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
>  drivers/mmc/host/sdhci-of-esdhc.c | 21 ++++++++++++++++++---
>  2 files changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 8cd8449..ece8b37 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -31,6 +31,10 @@
>   * eSDHC register definition
>   */
>
> +/* Present State Register */
> +#define ESDHC_PRSSTAT                  0x24
> +#define ESDHC_CLOCK_STABLE             0x00000008
> +
>  /* Protocol Control Register */
>  #define ESDHC_PROCTL                   0x28
>  #define ESDHC_CTRL_4BITBUS             (0x1 << 1)
> @@ -43,6 +47,7 @@
>  #define ESDHC_CLOCK_MASK               0x0000fff0
>  #define ESDHC_PREDIV_SHIFT             8
>  #define ESDHC_DIVIDER_SHIFT            4
> +#define ESDHC_CLOCK_SDCLKEN            0x00000008
>  #define ESDHC_CLOCK_PEREN              0x00000004
>  #define ESDHC_CLOCK_HCKEN              0x00000002
>  #define ESDHC_CLOCK_IPGEN              0x00000001
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 9a6eb44..0849885 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -431,6 +431,7 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>         struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
>         int pre_div = 1;
>         int div = 1;
> +       u32 timeout;
>         u32 temp;
>
>         host->mmc->actual_clock = 0;
> @@ -451,8 +452,8 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>         }
>
>         temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> -       temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
> -               | ESDHC_CLOCK_MASK);
> +       temp &= ~(ESDHC_CLOCK_SDCLKEN | ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN |
> +                 ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
>         sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
>
>         while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
> @@ -472,7 +473,21 @@ static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
>                 | (div << ESDHC_DIVIDER_SHIFT)
>                 | (pre_div << ESDHC_PREDIV_SHIFT));
>         sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
> -       mdelay(1);
> +
> +       /* Wait max 20 ms */
> +       timeout = 20;
> +       while (!(sdhci_readl(host, ESDHC_PRSSTAT) & ESDHC_CLOCK_STABLE)) {
> +               if (timeout == 0) {
> +                       pr_err("%s: Internal clock never stabilised.\n",
> +                               mmc_hostname(host->mmc));
> +                       return;
> +               }
> +               timeout--;
> +               mdelay(1);
> +       }
> +
> +       temp |= ESDHC_CLOCK_SDCLKEN;
> +       sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
>  }
>
>  static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
> --
> 2.1.0.27.g96db324
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-01-17 15:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-26  9:46 [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Yangbo Lu
2016-12-26  9:46 ` [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing Yangbo Lu
2017-01-12  7:09   ` Adrian Hunter
2017-01-13  2:12     ` Y.B. Lu
2017-01-13  9:31       ` Adrian Hunter
2017-01-13  9:30   ` Adrian Hunter
2017-01-17 15:07   ` Ulf Hansson
2017-01-12  1:32 ` [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Y.B. Lu
2017-01-12  6:55 ` Adrian Hunter
2017-01-12 10:58 ` Ulf Hansson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.