All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yangbo Lu <yangbo.lu@nxp.com>
To: linux-mmc@vger.kernel.org, ulf.hansson@linaro.org,
	Adrian Hunter <adrian.hunter@intel.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Subject: [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing
Date: Mon, 26 Dec 2016 17:46:30 +0800	[thread overview]
Message-ID: <1482745590-29718-2-git-send-email-yangbo.lu@nxp.com> (raw)
In-Reply-To: <1482745590-29718-1-git-send-email-yangbo.lu@nxp.com>

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


  reply	other threads:[~2016-12-26  9:59 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-26  9:46 [v2, 1/2] mmc: sdhci-esdhc: clean up register definitions Yangbo Lu
2016-12-26  9:46 ` Yangbo Lu [this message]
2017-01-12  7:09   ` [v2, 2/2] mmc: sdhci-of-esdhc: avoid clock glitch when frequency is changing 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1482745590-29718-2-git-send-email-yangbo.lu@nxp.com \
    --to=yangbo.lu@nxp.com \
    --cc=adrian.hunter@intel.com \
    --cc=linux-mmc@vger.kernel.org \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.