All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe
@ 2016-12-28 11:06 Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 1/8] mmc: sdhci-msm: Factor out sdhci_msm_hc_select_mode Ritesh Harjani
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

Hi, 

This patch series mainly provides enhanced strobe support to sdhci-msm driver
along with some additions of HW recommended sequence. This has been tested on
8996 based internal target & on db410c.

Patches 1-3 :- Factors out few functions to be re-used again.
	       To also simplify large functions and makes it more readable.

Patches 4-5 :- Few recommendations based on HW prog. guide.

Patches 6 :- Clear SDHCI_HS400_TUNING flag after platform_execute_tuning
	     so that ->platform_execute_tuning (underlying platform driver) can
	     know about HS400 tuning.

Patch 7 :- Implements an additional step as per HPG for HS400 tuning.

Patch 8 :- Implements enhanced strobe functionality in sdhci-msm driver.

Ritesh Harjani (6):
  mmc: sdhci-msm: Factor out sdhci_msm_hc_select_mode
  mmc: sdhci-msm: Factor out function to set/get msm clock rate
  mmc: sdhci-msm: Factor out sdhci_msm_hs400
  mmc: sdhci: Clear SDHCI_HS400_TUNING flag after
    platform_execute_tuning
  mmc: sdhci-msm: Make HS400 tuning follow as per recommeneded HW
    sequence
  mmc: sdhci-msm: Provide enhanced_strobe mode feature support

Subhash Jadavani (1):
  mmc: sdhci-msm: configure CORE_CSR_CDC_DELAY_CFG to recommended value

Venkat Gopalakrishnan (1):
  mmc: sdhci-msm: Reset vendor specific func register on probe

 drivers/mmc/host/sdhci-msm.c | 356 ++++++++++++++++++++++++++-----------------
 drivers/mmc/host/sdhci.c     |   6 +-
 2 files changed, 224 insertions(+), 138 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

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

* [PATCH 1/8] mmc: sdhci-msm: Factor out sdhci_msm_hc_select_mode
  2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
@ 2016-12-28 11:06 ` Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 2/8] mmc: sdhci-msm: Factor out function to set/get msm clock rate Ritesh Harjani
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

This factors out sdhci_msm_hc_select_mode to later use
it during enhanced_strobe mode select.
It also further breaks sdhci_msm_hc_select_mode
into separate functions for configuring HS400 mode
or other modes.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/host/sdhci-msm.c | 201 ++++++++++++++++++++++++-------------------
 1 file changed, 114 insertions(+), 87 deletions(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 32879b8..1e42647 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -464,6 +464,119 @@ static int msm_init_cm_dll(struct sdhci_host *host)
 	return 0;
 }
 
+static void msm_hc_select_default(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+	u32 config;
+
+	if (!msm_host->use_cdclp533) {
+		config = readl_relaxed(host->ioaddr +
+				CORE_VENDOR_SPEC3);
+		config &= ~CORE_PWRSAVE_DLL;
+		writel_relaxed(config, host->ioaddr +
+				CORE_VENDOR_SPEC3);
+	}
+
+	config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
+	config &= ~CORE_HC_MCLK_SEL_MASK;
+	config |= CORE_HC_MCLK_SEL_DFLT;
+	writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC);
+
+	/*
+	 * Disable HC_SELECT_IN to be able to use the UHS mode select
+	 * configuration from Host Control2 register for all other
+	 * modes.
+	 * Write 0 to HC_SELECT_IN and HC_SELECT_IN_EN field
+	 * in VENDOR_SPEC_FUNC
+	 */
+	config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
+	config &= ~CORE_HC_SELECT_IN_EN;
+	config &= ~CORE_HC_SELECT_IN_MASK;
+	writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC);
+
+	/*
+	 * Make sure above writes impacting free running MCLK are completed
+	 * before changing the clk_rate at GCC.
+	 */
+	wmb();
+}
+
+static void msm_hc_select_hs400(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+	u32 config, dll_lock;
+	int rc;
+
+	/* Select the divided clock (free running MCLK/2) */
+	config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
+	config &= ~CORE_HC_MCLK_SEL_MASK;
+	config |= CORE_HC_MCLK_SEL_HS400;
+
+	writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC);
+	/*
+	 * Select HS400 mode using the HC_SELECT_IN from VENDOR SPEC
+	 * register
+	 */
+	if (msm_host->tuning_done && !msm_host->calibration_done) {
+		config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
+		config |= CORE_HC_SELECT_IN_HS400;
+		config |= CORE_HC_SELECT_IN_EN;
+		writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC);
+	}
+	if (!msm_host->clk_rate && !msm_host->use_cdclp533) {
+		/*
+		 * Poll on DLL_LOCK or DDR_DLL_LOCK bits in
+		 * CORE_DLL_STATUS to be set.  This should get set
+		 * within 15 us at 200 MHz.
+		 */
+		rc = readl_relaxed_poll_timeout(host->ioaddr +
+						CORE_DLL_STATUS,
+						dll_lock,
+						(dll_lock &
+						(CORE_DLL_LOCK |
+						CORE_DDR_DLL_LOCK)), 10,
+						1000);
+		if (rc == -ETIMEDOUT)
+			pr_err("%s: Unable to get DLL_LOCK/DDR_DLL_LOCK, dll_status: 0x%08x\n",
+			       mmc_hostname(host->mmc), dll_lock);
+	}
+	/*
+	 * Make sure above writes impacting free running MCLK are completed
+	 * before changing the clk_rate at GCC.
+	 */
+	wmb();
+}
+
+/*
+ * sdhci_msm_hc_select_mode :- In general all timing modes are
+ * controlled via UHS mode select in Host Control2 register.
+ * eMMC specific HS200/HS400 doesn't have their respective modes
+ * defined here, hence we use these values.
+ *
+ * HS200 - SDR104 (Since they both are equivalent in functionality)
+ * HS400 - This involves multiple configurations
+ *		Initially SDR104 - when tuning is required as HS200
+ *		Then when switching to DDR @ 400MHz (HS400) we use
+ *		the vendor specific HC_SELECT_IN to control the mode.
+ *
+ * In addition to controlling the modes we also need to select the
+ * correct input clock for DLL depending on the mode.
+ *
+ * HS400 - divided clock (free running MCLK/2)
+ * All other modes - default (free running MCLK)
+ */
+void sdhci_msm_hc_select_mode(struct sdhci_host *host)
+{
+	struct mmc_ios ios = host->mmc->ios;
+
+	if (ios.timing == MMC_TIMING_MMC_HS400)
+		msm_hc_select_hs400(host);
+	else
+		msm_hc_select_default(host);
+}
+
 static int sdhci_msm_cdclp533_calibration(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -894,7 +1007,6 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
 	struct mmc_ios curr_ios = host->mmc->ios;
-	u32 config, dll_lock;
 	int rc;
 
 	if (!clock) {
@@ -913,93 +1025,8 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
 	    curr_ios.timing == MMC_TIMING_MMC_DDR52 ||
 	    curr_ios.timing == MMC_TIMING_MMC_HS400)
 		clock *= 2;
-	/*
-	 * In general all timing modes are controlled via UHS mode select in
-	 * Host Control2 register. eMMC specific HS200/HS400 doesn't have
-	 * their respective modes defined here, hence we use these values.
-	 *
-	 * HS200 - SDR104 (Since they both are equivalent in functionality)
-	 * HS400 - This involves multiple configurations
-	 *		Initially SDR104 - when tuning is required as HS200
-	 *		Then when switching to DDR @ 400MHz (HS400) we use
-	 *		the vendor specific HC_SELECT_IN to control the mode.
-	 *
-	 * In addition to controlling the modes we also need to select the
-	 * correct input clock for DLL depending on the mode.
-	 *
-	 * HS400 - divided clock (free running MCLK/2)
-	 * All other modes - default (free running MCLK)
-	 */
-	if (curr_ios.timing == MMC_TIMING_MMC_HS400) {
-		/* Select the divided clock (free running MCLK/2) */
-		config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
-		config &= ~CORE_HC_MCLK_SEL_MASK;
-		config |= CORE_HC_MCLK_SEL_HS400;
 
-		writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC);
-		/*
-		 * Select HS400 mode using the HC_SELECT_IN from VENDOR SPEC
-		 * register
-		 */
-		if (msm_host->tuning_done && !msm_host->calibration_done) {
-			/*
-			 * Write 0x6 to HC_SELECT_IN and 1 to HC_SELECT_IN_EN
-			 * field in VENDOR_SPEC_FUNC
-			 */
-			config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
-			config |= CORE_HC_SELECT_IN_HS400;
-			config |= CORE_HC_SELECT_IN_EN;
-			writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC);
-		}
-		if (!msm_host->clk_rate && !msm_host->use_cdclp533) {
-			/*
-			 * Poll on DLL_LOCK or DDR_DLL_LOCK bits in
-			 * CORE_DLL_STATUS to be set.  This should get set
-			 * within 15 us at 200 MHz.
-			 */
-			rc = readl_relaxed_poll_timeout(host->ioaddr +
-							CORE_DLL_STATUS,
-							dll_lock,
-							(dll_lock &
-							(CORE_DLL_LOCK |
-							CORE_DDR_DLL_LOCK)), 10,
-							1000);
-			if (rc == -ETIMEDOUT)
-				pr_err("%s: Unable to get DLL_LOCK/DDR_DLL_LOCK, dll_status: 0x%08x\n",
-				       mmc_hostname(host->mmc), dll_lock);
-		}
-	} else {
-		if (!msm_host->use_cdclp533) {
-			config = readl_relaxed(host->ioaddr +
-					CORE_VENDOR_SPEC3);
-			config &= ~CORE_PWRSAVE_DLL;
-			writel_relaxed(config, host->ioaddr +
-					CORE_VENDOR_SPEC3);
-		}
-
-		config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
-		config &= ~CORE_HC_MCLK_SEL_MASK;
-		config |= CORE_HC_MCLK_SEL_DFLT;
-		writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC);
-
-		/*
-		 * Disable HC_SELECT_IN to be able to use the UHS mode select
-		 * configuration from Host Control2 register for all other
-		 * modes.
-		 * Write 0 to HC_SELECT_IN and HC_SELECT_IN_EN field
-		 * in VENDOR_SPEC_FUNC
-		 */
-		config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
-		config &= ~CORE_HC_SELECT_IN_EN;
-		config &= ~CORE_HC_SELECT_IN_MASK;
-		writel_relaxed(config, host->ioaddr + CORE_VENDOR_SPEC);
-	}
-
-	/*
-	 * Make sure above writes impacting free running MCLK are completed
-	 * before changing the clk_rate at GCC.
-	 */
-	wmb();
+	sdhci_msm_hc_select_mode(host);
 
 	rc = clk_set_rate(msm_host->clk, clock);
 	if (rc) {
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.


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

* [PATCH 2/8] mmc: sdhci-msm: Factor out function to set/get msm clock rate
  2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 1/8] mmc: sdhci-msm: Factor out sdhci_msm_hc_select_mode Ritesh Harjani
@ 2016-12-28 11:06 ` Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 3/8] mmc: sdhci-msm: Factor out sdhci_msm_hs400 Ritesh Harjani
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

Factor out msm_set/get_clock_rate_for_bus_mode for it's later
use in changing the tuning sequence for selecting HS400
bus speed mode.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/host/sdhci-msm.c | 64 +++++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 24 deletions(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 1e42647..3fc496e 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -138,6 +138,45 @@ struct sdhci_msm_host {
 	bool use_cdclp533;
 };
 
+static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host,
+						    unsigned int clock)
+{
+	struct mmc_ios ios = host->mmc->ios;
+	/*
+	 * The SDHC requires internal clock frequency to be double the
+	 * actual clock that will be set for DDR mode. The controller
+	 * uses the faster clock(100/400MHz) for some of its parts and
+	 * send the actual required clock (50/200MHz) to the card.
+	 */
+	if (ios.timing == MMC_TIMING_UHS_DDR50 ||
+	    ios.timing == MMC_TIMING_MMC_DDR52 ||
+	    ios.timing == MMC_TIMING_MMC_HS400)
+		clock *= 2;
+	return clock;
+}
+
+static void msm_set_clock_rate_for_bus_mode(struct sdhci_host *host,
+					    unsigned int clock)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+	struct mmc_ios curr_ios = host->mmc->ios;
+	int rc;
+
+	clock = msm_get_clock_rate_for_bus_mode(host, clock);
+	rc = clk_set_rate(msm_host->clk, clock);
+	if (rc) {
+		pr_err("%s: Failed to set clock at rate %u at timing %d\n",
+		       mmc_hostname(host->mmc), clock,
+		       curr_ios.timing);
+		return;
+	}
+	msm_host->clk_rate = clock;
+	pr_debug("%s: Setting clock at rate %lu at timing %d\n",
+		 mmc_hostname(host->mmc), clk_get_rate(msm_host->clk),
+		 curr_ios.timing);
+}
+
 /* Platform specific tuning */
 static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host, u8 poll)
 {
@@ -1006,8 +1045,6 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
-	struct mmc_ios curr_ios = host->mmc->ios;
-	int rc;
 
 	if (!clock) {
 		msm_host->clk_rate = clock;
@@ -1015,32 +1052,11 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
 	}
 
 	spin_unlock_irq(&host->lock);
-	/*
-	 * The SDHC requires internal clock frequency to be double the
-	 * actual clock that will be set for DDR mode. The controller
-	 * uses the faster clock(100/400MHz) for some of its parts and
-	 * send the actual required clock (50/200MHz) to the card.
-	 */
-	if (curr_ios.timing == MMC_TIMING_UHS_DDR50 ||
-	    curr_ios.timing == MMC_TIMING_MMC_DDR52 ||
-	    curr_ios.timing == MMC_TIMING_MMC_HS400)
-		clock *= 2;
 
 	sdhci_msm_hc_select_mode(host);
 
-	rc = clk_set_rate(msm_host->clk, clock);
-	if (rc) {
-		pr_err("%s: Failed to set clock at rate %u at timing %d\n",
-		       mmc_hostname(host->mmc), clock,
-		       curr_ios.timing);
-		goto out_lock;
-	}
-	msm_host->clk_rate = clock;
-	pr_debug("%s: Setting clock at rate %lu at timing %d\n",
-		 mmc_hostname(host->mmc), clk_get_rate(msm_host->clk),
-		 curr_ios.timing);
+	msm_set_clock_rate_for_bus_mode(host, clock);
 
-out_lock:
 	spin_lock_irq(&host->lock);
 out:
 	__sdhci_msm_set_clock(host, clock);
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

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

* [PATCH 3/8] mmc: sdhci-msm: Factor out sdhci_msm_hs400
  2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 1/8] mmc: sdhci-msm: Factor out sdhci_msm_hc_select_mode Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 2/8] mmc: sdhci-msm: Factor out function to set/get msm clock rate Ritesh Harjani
@ 2016-12-28 11:06 ` Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 4/8] mmc: sdhci-msm: Reset vendor specific func register on probe Ritesh Harjani
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

Factor out sdhci_msm_hs400 used for DLL calibration in HS400
modes. This function will be needed for enhanced_strobe as well.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/host/sdhci-msm.c | 32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 3fc496e..5a37c29 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -884,6 +884,28 @@ static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
 	return rc;
 }
 
+/*
+ * sdhci_msm_hs400 - Calibrate the DLL for HS400 bus speed mode operation.
+ * DLL operation is only needed for clock > 100MHz. For clock <= 100MHz
+ * fixed feedback clock is used.
+ */
+static void sdhci_msm_hs400(struct sdhci_host *host, struct mmc_ios *ios)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+	int ret;
+
+	if (host->clock > CORE_FREQ_100MHZ &&
+	    msm_host->tuning_done && !msm_host->calibration_done) {
+		ret = sdhci_msm_hs400_dll_calibration(host);
+		if (!ret)
+			msm_host->calibration_done = true;
+		else
+			pr_err("%s: Failed to calibrate DLL for hs400 mode (%d)\n",
+			       mmc_hostname(host->mmc), ret);
+	}
+}
+
 static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host,
 					unsigned int uhs)
 {
@@ -952,12 +974,10 @@ static void sdhci_msm_set_uhs_signaling(struct sdhci_host *host,
 	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
 
 	spin_unlock_irq(&host->lock);
-	/* CDCLP533 HW calibration is only required for HS400 mode*/
-	if (host->clock > CORE_FREQ_100MHZ &&
-	    msm_host->tuning_done && !msm_host->calibration_done &&
-	    mmc->ios.timing == MMC_TIMING_MMC_HS400)
-		if (!sdhci_msm_hs400_dll_calibration(host))
-			msm_host->calibration_done = true;
+
+	if (mmc->ios.timing == MMC_TIMING_MMC_HS400)
+		sdhci_msm_hs400(host, &mmc->ios);
+
 	spin_lock_irq(&host->lock);
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.


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

* [PATCH 4/8] mmc: sdhci-msm: Reset vendor specific func register on probe
  2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
                   ` (2 preceding siblings ...)
  2016-12-28 11:06 ` [PATCH 3/8] mmc: sdhci-msm: Factor out sdhci_msm_hs400 Ritesh Harjani
@ 2016-12-28 11:06 ` Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 5/8] mmc: sdhci-msm: configure CORE_CSR_CDC_DELAY_CFG to recommended value Ritesh Harjani
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

From: Venkat Gopalakrishnan <venkatg@codeaurora.org>

The vendor specific func register doesn't get reset when using the
software reset register. The various bootloader's could leave this
in an unknown state, hence reset this register to it's power on reset
value during probe.

Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/host/sdhci-msm.c | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 5a37c29..a028568 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -69,6 +69,7 @@
 #define CORE_DLL_CLOCK_DISABLE	BIT(21)
 
 #define CORE_VENDOR_SPEC	0x10c
+#define CORE_VENDOR_SPEC_POR_VAL	0xa1c
 #define CORE_CLK_PWRSAVE	BIT(1)
 #define CORE_HC_MCLK_SEL_DFLT	(2 << 8)
 #define CORE_HC_MCLK_SEL_HS400	(3 << 8)
@@ -1197,17 +1198,9 @@ static int sdhci_msm_probe(struct platform_device *pdev)
 		goto clk_disable;
 	}
 
-	config = readl_relaxed(msm_host->core_mem + CORE_POWER);
-	config |= CORE_SW_RST;
-	writel_relaxed(config, msm_host->core_mem + CORE_POWER);
-
-	/* SW reset can take upto 10HCLK + 15MCLK cycles. (min 40us) */
-	usleep_range(1000, 5000);
-	if (readl(msm_host->core_mem + CORE_POWER) & CORE_SW_RST) {
-		dev_err(&pdev->dev, "Stuck in reset\n");
-		ret = -ETIMEDOUT;
-		goto clk_disable;
-	}
+	/* Reset the vendor spec register to power on reset state */
+	writel_relaxed(CORE_VENDOR_SPEC_POR_VAL,
+		       host->ioaddr + CORE_VENDOR_SPEC);
 
 	/* Set HC_MODE_EN bit in HC_MODE register */
 	writel_relaxed(HC_MODE_EN, (msm_host->core_mem + CORE_HC_MODE));
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

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

* [PATCH 5/8] mmc: sdhci-msm: configure CORE_CSR_CDC_DELAY_CFG to recommended value
  2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
                   ` (3 preceding siblings ...)
  2016-12-28 11:06 ` [PATCH 4/8] mmc: sdhci-msm: Reset vendor specific func register on probe Ritesh Harjani
@ 2016-12-28 11:06 ` Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 6/8] mmc: sdhci: Clear SDHCI_HS400_TUNING flag after platform_execute_tuning Ritesh Harjani
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

From: Subhash Jadavani <subhashj@codeaurora.org>

Program CORE_CSR_CDC_DELAY_CFG for hardware recommended 1.25ns delay.
We may see data CRC errors if it's programmed for any other delay
value.

Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/host/sdhci-msm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index a028568..84d29dd 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -679,7 +679,7 @@ static int sdhci_msm_cdclp533_calibration(struct sdhci_host *host)
 	writel_relaxed(0x4, host->ioaddr + CORE_CSR_CDC_CAL_TIMER_CFG1);
 	writel_relaxed(0xCB732020, host->ioaddr + CORE_CSR_CDC_REFCOUNT_CFG);
 	writel_relaxed(0xB19, host->ioaddr + CORE_CSR_CDC_COARSE_CAL_CFG);
-	writel_relaxed(0x3AC, host->ioaddr + CORE_CSR_CDC_DELAY_CFG);
+	writel_relaxed(0x4E2, host->ioaddr + CORE_CSR_CDC_DELAY_CFG);
 	writel_relaxed(0x0, host->ioaddr + CORE_CDC_OFFSET_CFG);
 	writel_relaxed(0x16334, host->ioaddr + CORE_CDC_SLAVE_DDA_CFG);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

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

* [PATCH 6/8] mmc: sdhci: Clear SDHCI_HS400_TUNING flag after platform_execute_tuning
  2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
                   ` (4 preceding siblings ...)
  2016-12-28 11:06 ` [PATCH 5/8] mmc: sdhci-msm: configure CORE_CSR_CDC_DELAY_CFG to recommended value Ritesh Harjani
@ 2016-12-28 11:06 ` Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 7/8] mmc: sdhci-msm: Make HS400 tuning follow as per recommeneded HW sequence Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 8/8] mmc: sdhci-msm: Provide enhanced_strobe mode feature support Ritesh Harjani
  7 siblings, 0 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

Clear SDHCI_HS400_TUNING flag after platform_execute_tuning
so that platform_execute_tuning may use it if needed.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/host/sdhci.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2390980..2658f89 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2114,7 +2114,6 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	spin_lock_irqsave(&host->lock, flags);
 
 	hs400_tuning = host->flags & SDHCI_HS400_TUNING;
-	host->flags &= ~SDHCI_HS400_TUNING;
 
 	if (host->tuning_mode == SDHCI_TUNING_MODE_1)
 		tuning_count = host->tuning_count;
@@ -2156,7 +2155,9 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
 	if (host->ops->platform_execute_tuning) {
 		spin_unlock_irqrestore(&host->lock, flags);
-		return host->ops->platform_execute_tuning(host, opcode);
+		err = host->ops->platform_execute_tuning(host, opcode);
+		spin_lock_irqsave(&host->lock, flags);
+		goto out_unlock;
 	}
 
 	host->mmc->retune_period = tuning_count;
@@ -2167,6 +2168,7 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
 	sdhci_end_tuning(host);
 out_unlock:
+	host->flags &= ~SDHCI_HS400_TUNING;
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	return err;
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

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

* [PATCH 7/8] mmc: sdhci-msm: Make HS400 tuning follow as per recommeneded HW sequence
  2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
                   ` (5 preceding siblings ...)
  2016-12-28 11:06 ` [PATCH 6/8] mmc: sdhci: Clear SDHCI_HS400_TUNING flag after platform_execute_tuning Ritesh Harjani
@ 2016-12-28 11:06 ` Ritesh Harjani
  2016-12-28 11:06 ` [PATCH 8/8] mmc: sdhci-msm: Provide enhanced_strobe mode feature support Ritesh Harjani
  7 siblings, 0 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

During tuning execution for HS400 mode, HW sequence recommends
to select MCLK_SEL/2(0x3) in VENDOR_SPEC & sdhc msm clock at GCC
to be 400MHZ (nearest supported clk). Add this change in tuning
sequence during HS400 tuning.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/host/sdhci-msm.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 84d29dd..fa9bce3 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -151,7 +151,8 @@ static unsigned int msm_get_clock_rate_for_bus_mode(struct sdhci_host *host,
 	 */
 	if (ios.timing == MMC_TIMING_UHS_DDR50 ||
 	    ios.timing == MMC_TIMING_MMC_DDR52 ||
-	    ios.timing == MMC_TIMING_MMC_HS400)
+	    ios.timing == MMC_TIMING_MMC_HS400 ||
+	    host->flags & SDHCI_HS400_TUNING)
 		clock *= 2;
 	return clock;
 }
@@ -611,7 +612,8 @@ void sdhci_msm_hc_select_mode(struct sdhci_host *host)
 {
 	struct mmc_ios ios = host->mmc->ios;
 
-	if (ios.timing == MMC_TIMING_MMC_HS400)
+	if (ios.timing == MMC_TIMING_MMC_HS400 ||
+	    host->flags & SDHCI_HS400_TUNING)
 		msm_hc_select_hs400(host);
 	else
 		msm_hc_select_default(host);
@@ -831,6 +833,16 @@ static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
 	    ios.timing == MMC_TIMING_UHS_SDR104))
 		return 0;
 
+	/*
+	 * For HS400 tuning in HS200 timing requires:
+	 * - select MCLK/2 in VENDOR_SPEC
+	 * - program MCLK to 400MHz (or nearest supported) in GCC
+	 */
+	if (host->flags & SDHCI_HS400_TUNING) {
+		sdhci_msm_hc_select_mode(host);
+		msm_set_clock_rate_for_bus_mode(host, ios.clock);
+	}
+
 retry:
 	/* First of all reset the tuning block */
 	rc = msm_init_cm_dll(host);
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

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

* [PATCH 8/8] mmc: sdhci-msm: Provide enhanced_strobe mode feature support
  2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
                   ` (6 preceding siblings ...)
  2016-12-28 11:06 ` [PATCH 7/8] mmc: sdhci-msm: Make HS400 tuning follow as per recommeneded HW sequence Ritesh Harjani
@ 2016-12-28 11:06 ` Ritesh Harjani
  7 siblings, 0 replies; 9+ messages in thread
From: Ritesh Harjani @ 2016-12-28 11:06 UTC (permalink / raw)
  To: ulf.hansson, adrian.hunter
  Cc: linux-mmc, linux-kernel, shawn.lin, stummala, georgi.djakov,
	linux-arm-msm, pramod.gurav, jeremymc, venkatg, asutoshd,
	subhashj, Ritesh Harjani

This provides enhanced_strobe mode feature support in sdhci-msm
driver.

Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
---
 drivers/mmc/host/sdhci-msm.c | 34 +++++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index fa9bce3..f958697 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -103,6 +103,7 @@
 
 #define CORE_DDR_200_CFG		0x184
 #define CORE_CDC_T4_DLY_SEL		BIT(0)
+#define CORE_CMDIN_RCLK_EN		BIT(1)
 #define CORE_START_CDC_TRAFFIC		BIT(6)
 #define CORE_VENDOR_SPEC3	0x1b0
 #define CORE_PWRSAVE_DLL	BIT(3)
@@ -547,6 +548,7 @@ static void msm_hc_select_hs400(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+	struct mmc_ios ios = host->mmc->ios;
 	u32 config, dll_lock;
 	int rc;
 
@@ -560,7 +562,8 @@ static void msm_hc_select_hs400(struct sdhci_host *host)
 	 * Select HS400 mode using the HC_SELECT_IN from VENDOR SPEC
 	 * register
 	 */
-	if (msm_host->tuning_done && !msm_host->calibration_done) {
+	if ((msm_host->tuning_done || ios.enhanced_strobe) &&
+	    !msm_host->calibration_done) {
 		config = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC);
 		config |= CORE_HC_SELECT_IN_HS400;
 		config |= CORE_HC_SELECT_IN_EN;
@@ -734,6 +737,7 @@ static int sdhci_msm_cdclp533_calibration(struct sdhci_host *host)
 
 static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host)
 {
+	struct mmc_host *mmc = host->mmc;
 	u32 dll_status, config;
 	int ret;
 
@@ -748,6 +752,12 @@ static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host)
 	 */
 	writel_relaxed(DDR_CONFIG_POR_VAL, host->ioaddr + CORE_DDR_CONFIG);
 
+	if (mmc->ios.enhanced_strobe) {
+		config = readl_relaxed(host->ioaddr + CORE_DDR_200_CFG);
+		config |= CORE_CMDIN_RCLK_EN;
+		writel_relaxed(config, host->ioaddr + CORE_DDR_200_CFG);
+	}
+
 	config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG_2);
 	config |= CORE_DDR_CAL_EN;
 	writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG_2);
@@ -782,6 +792,7 @@ static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+	struct mmc_host *mmc = host->mmc;
 	int ret;
 	u32 config;
 
@@ -795,14 +806,17 @@ static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host)
 	if (ret)
 		goto out;
 
-	/* Set the selected phase in delay line hw block */
-	ret = msm_config_cm_dll_phase(host, msm_host->saved_tuning_phase);
-	if (ret)
-		goto out;
+	if (!mmc->ios.enhanced_strobe) {
+		/* Set the selected phase in delay line hw block */
+		ret = msm_config_cm_dll_phase(host,
+					      msm_host->saved_tuning_phase);
+		if (ret)
+			goto out;
+		config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
+		config |= CORE_CMD_DAT_TRACK_SEL;
+		writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
+	}
 
-	config = readl_relaxed(host->ioaddr + CORE_DLL_CONFIG);
-	config |= CORE_CMD_DAT_TRACK_SEL;
-	writel_relaxed(config, host->ioaddr + CORE_DLL_CONFIG);
 	if (msm_host->use_cdclp533)
 		ret = sdhci_msm_cdclp533_calibration(host);
 	else
@@ -899,6 +913,7 @@ static int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
 
 /*
  * sdhci_msm_hs400 - Calibrate the DLL for HS400 bus speed mode operation.
+ * This needs to be done for both tuning and enhanced_strobe mode.
  * DLL operation is only needed for clock > 100MHz. For clock <= 100MHz
  * fixed feedback clock is used.
  */
@@ -909,7 +924,8 @@ static void sdhci_msm_hs400(struct sdhci_host *host, struct mmc_ios *ios)
 	int ret;
 
 	if (host->clock > CORE_FREQ_100MHZ &&
-	    msm_host->tuning_done && !msm_host->calibration_done) {
+	    (msm_host->tuning_done || ios->enhanced_strobe) &&
+	    !msm_host->calibration_done) {
 		ret = sdhci_msm_hs400_dll_calibration(host);
 		if (!ret)
 			msm_host->calibration_done = true;
-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
a Linux Foundation Collaborative Project.

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

end of thread, other threads:[~2016-12-28 11:06 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-28 11:06 [PATCH 0/8] mmc: sdhci-msm: Provide support for enhanced strobe Ritesh Harjani
2016-12-28 11:06 ` [PATCH 1/8] mmc: sdhci-msm: Factor out sdhci_msm_hc_select_mode Ritesh Harjani
2016-12-28 11:06 ` [PATCH 2/8] mmc: sdhci-msm: Factor out function to set/get msm clock rate Ritesh Harjani
2016-12-28 11:06 ` [PATCH 3/8] mmc: sdhci-msm: Factor out sdhci_msm_hs400 Ritesh Harjani
2016-12-28 11:06 ` [PATCH 4/8] mmc: sdhci-msm: Reset vendor specific func register on probe Ritesh Harjani
2016-12-28 11:06 ` [PATCH 5/8] mmc: sdhci-msm: configure CORE_CSR_CDC_DELAY_CFG to recommended value Ritesh Harjani
2016-12-28 11:06 ` [PATCH 6/8] mmc: sdhci: Clear SDHCI_HS400_TUNING flag after platform_execute_tuning Ritesh Harjani
2016-12-28 11:06 ` [PATCH 7/8] mmc: sdhci-msm: Make HS400 tuning follow as per recommeneded HW sequence Ritesh Harjani
2016-12-28 11:06 ` [PATCH 8/8] mmc: sdhci-msm: Provide enhanced_strobe mode feature support Ritesh Harjani

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.