All of lore.kernel.org
 help / color / mirror / Atom feed
* [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
@ 2017-03-27  7:49 ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Adrian Hunter, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie, Yangbo Lu

It's complicated to support SD UHS-I and eMMC HS200 for eSDHC because
there're many differences between eSDHC and SD/eMMC spec. Several
differences as below must be considered:
1. Peripheral clock must be used instead of platform clock.
    - eSDHC could select peripheral clock or platform clock as its clock
      source. According to RM, UHS-I/HS200 must use peripheral clock since
      it supports higher frequency than platform clock.
    - Patch 1 and patch 6 is to support this.
2. Signal voltage switching requires a control circuit out of eSDHC.
    - eSDHC supports signal voltage switch from 3.3v to 1.8v by
      eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
      signal SDHC_VS, and there must be a control circuit out of eSDHC
      to change the signal voltage according to SDHC_VS output signal.
    - Patch 2 is to support this.
3. eSDHC uses tuning block for tuning procedure.
    - Tuning clock control register must be configured before tuning.
    - Patch 3 is to support this.
4. Delay is needed between tuning cycles for HS200 tuning.
    - Once a patch removed mdelay between tuning cycles.
      But eSDHC needs it.
    - Patch 4 and patch 5 is to support this.
5. UHS-I/HS200 modes could be enabled in dts node.
    - Patch 7 is to support this.

Please review and merge these patches on mmc git tree if no changes
are required.

Adrian Hunter (1):
  mmc: sdhci: Control the delay between tuning commands

Yangbo Lu (6):
  mmc: sdhci-of-esdhc: add peripheral clock support
  mmc: sdhci-of-esdhc: add support for signal voltage switch
  mmc: sdhci-of-esdhc: add tuning support
  mmc: sdhci-of-esdhc: add delay between tuning cycles
  arm64: dts: ls1046a: add clocks property and compatible for eSDHC node
  arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support

 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts |   8 ++
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi    |   3 +-
 drivers/mmc/host/sdhci-esdhc.h                    |   7 +
 drivers/mmc/host/sdhci-of-esdhc.c                 | 165 +++++++++++++++++++++-
 drivers/mmc/host/sdhci.c                          |  11 +-
 drivers/mmc/host/sdhci.h                          |   2 +
 6 files changed, 190 insertions(+), 6 deletions(-)

-- 
2.1.0.27.g96db324

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

* [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
@ 2017-03-27  7:49 ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

It's complicated to support SD UHS-I and eMMC HS200 for eSDHC because
there're many differences between eSDHC and SD/eMMC spec. Several
differences as below must be considered:
1. Peripheral clock must be used instead of platform clock.
    - eSDHC could select peripheral clock or platform clock as its clock
      source. According to RM, UHS-I/HS200 must use peripheral clock since
      it supports higher frequency than platform clock.
    - Patch 1 and patch 6 is to support this.
2. Signal voltage switching requires a control circuit out of eSDHC.
    - eSDHC supports signal voltage switch from 3.3v to 1.8v by
      eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
      signal SDHC_VS, and there must be a control circuit out of eSDHC
      to change the signal voltage according to SDHC_VS output signal.
    - Patch 2 is to support this.
3. eSDHC uses tuning block for tuning procedure.
    - Tuning clock control register must be configured before tuning.
    - Patch 3 is to support this.
4. Delay is needed between tuning cycles for HS200 tuning.
    - Once a patch removed mdelay between tuning cycles.
      But eSDHC needs it.
    - Patch 4 and patch 5 is to support this.
5. UHS-I/HS200 modes could be enabled in dts node.
    - Patch 7 is to support this.

Please review and merge these patches on mmc git tree if no changes
are required.

Adrian Hunter (1):
  mmc: sdhci: Control the delay between tuning commands

Yangbo Lu (6):
  mmc: sdhci-of-esdhc: add peripheral clock support
  mmc: sdhci-of-esdhc: add support for signal voltage switch
  mmc: sdhci-of-esdhc: add tuning support
  mmc: sdhci-of-esdhc: add delay between tuning cycles
  arm64: dts: ls1046a: add clocks property and compatible for eSDHC node
  arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support

 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts |   8 ++
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi    |   3 +-
 drivers/mmc/host/sdhci-esdhc.h                    |   7 +
 drivers/mmc/host/sdhci-of-esdhc.c                 | 165 +++++++++++++++++++++-
 drivers/mmc/host/sdhci.c                          |  11 +-
 drivers/mmc/host/sdhci.h                          |   2 +
 6 files changed, 190 insertions(+), 6 deletions(-)

-- 
2.1.0.27.g96db324

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

* [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-03-27  7:49   ` Yangbo Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Adrian Hunter, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie, Yangbo Lu

eSDHC could select peripheral clock or platform clock as clock source by
the PCS bit of eSDHC Control Register, and this bit couldn't be reset by
software reset for all. In default, the platform clock is used. But we have
to use peripheral clock since it has a higher frequency to support eMMC
HS200 mode and SD UHS-I mode. This patch is to add peripheral clock support
and use it instead of platform clock if it's declared in eSDHC dts node.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- None
---
 drivers/mmc/host/sdhci-esdhc.h    |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c | 70 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index ece8b37..5343fc0 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -54,6 +54,7 @@
 
 /* Control Register for DMA transfer */
 #define ESDHC_DMA_SYSCTL		0x40c
+#define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
 #define ESDHC_DMA_SNOOP			0x00000040
 
 #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index ff37e74..7ce1caf 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/sys_soc.h>
+#include <linux/clk.h>
 #include <linux/mmc/host.h>
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
@@ -30,6 +31,7 @@ struct sdhci_esdhc {
 	u8 vendor_ver;
 	u8 spec_ver;
 	bool quirk_incorrect_hostver;
+	unsigned int peripheral_clock;
 };
 
 /**
@@ -414,15 +416,25 @@ static int esdhc_of_enable_dma(struct sdhci_host *host)
 static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
 
-	return pltfm_host->clock;
+	if (esdhc->peripheral_clock)
+		return esdhc->peripheral_clock;
+	else
+		return pltfm_host->clock;
 }
 
 static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
+	unsigned int clock;
 
-	return pltfm_host->clock / 256 / 16;
+	if (esdhc->peripheral_clock)
+		clock = esdhc->peripheral_clock;
+	else
+		clock = pltfm_host->clock;
+	return clock / 256 / 16;
 }
 
 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
@@ -512,6 +524,33 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 	sdhci_writel(host, ctrl, ESDHC_PROCTL);
 }
 
+static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
+{
+	u32 val;
+	u32 timeout;
+
+	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
+
+	if (enable)
+		val |= ESDHC_CLOCK_SDCLKEN;
+	else
+		val &= ~ESDHC_CLOCK_SDCLKEN;
+
+	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
+
+	timeout = 20;
+	val = ESDHC_CLOCK_STABLE;
+	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
+		if (timeout == 0) {
+			pr_err("%s: Internal clock never stabilised.\n",
+				mmc_hostname(host->mmc));
+			break;
+		}
+		timeout--;
+		mdelay(1);
+	}
+}
+
 static void esdhc_reset(struct sdhci_host *host, u8 mask)
 {
 	sdhci_reset(host, mask);
@@ -613,6 +652,9 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_esdhc *esdhc;
+	struct device_node *np;
+	struct clk *clk;
+	u32 val;
 	u16 host_ver;
 
 	pltfm_host = sdhci_priv(host);
@@ -626,6 +668,30 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
 		esdhc->quirk_incorrect_hostver = true;
 	else
 		esdhc->quirk_incorrect_hostver = false;
+
+	np = pdev->dev.of_node;
+	clk = of_clk_get(np, 0);
+	if (!IS_ERR(clk)) {
+		/*
+		 * esdhc->peripheral_clock would be assigned with a value
+		 * which is eSDHC base clock when use periperal clock.
+		 * For ls1046a, the clock value got by common clk API is
+		 * peripheral clock while the eSDHC base clock is 1/2
+		 * peripheral clock.
+		 */
+		if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
+			esdhc->peripheral_clock = clk_get_rate(clk) / 2;
+		else
+			esdhc->peripheral_clock = clk_get_rate(clk);
+	}
+
+	if (esdhc->peripheral_clock) {
+		esdhc_clock_enable(host, false);
+		val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+		val |= ESDHC_PERIPHERAL_CLK_SEL;
+		sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
+		esdhc_clock_enable(host, true);
+	}
 }
 
 static int sdhci_esdhc_probe(struct platform_device *pdev)
-- 
2.1.0.27.g96db324


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

* [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
@ 2017-03-27  7:49   ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

eSDHC could select peripheral clock or platform clock as clock source by
the PCS bit of eSDHC Control Register, and this bit couldn't be reset by
software reset for all. In default, the platform clock is used. But we have
to use peripheral clock since it has a higher frequency to support eMMC
HS200 mode and SD UHS-I mode. This patch is to add peripheral clock support
and use it instead of platform clock if it's declared in eSDHC dts node.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- None
---
 drivers/mmc/host/sdhci-esdhc.h    |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c | 70 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index ece8b37..5343fc0 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -54,6 +54,7 @@
 
 /* Control Register for DMA transfer */
 #define ESDHC_DMA_SYSCTL		0x40c
+#define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
 #define ESDHC_DMA_SNOOP			0x00000040
 
 #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index ff37e74..7ce1caf 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/sys_soc.h>
+#include <linux/clk.h>
 #include <linux/mmc/host.h>
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
@@ -30,6 +31,7 @@ struct sdhci_esdhc {
 	u8 vendor_ver;
 	u8 spec_ver;
 	bool quirk_incorrect_hostver;
+	unsigned int peripheral_clock;
 };
 
 /**
@@ -414,15 +416,25 @@ static int esdhc_of_enable_dma(struct sdhci_host *host)
 static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
 
-	return pltfm_host->clock;
+	if (esdhc->peripheral_clock)
+		return esdhc->peripheral_clock;
+	else
+		return pltfm_host->clock;
 }
 
 static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
+	unsigned int clock;
 
-	return pltfm_host->clock / 256 / 16;
+	if (esdhc->peripheral_clock)
+		clock = esdhc->peripheral_clock;
+	else
+		clock = pltfm_host->clock;
+	return clock / 256 / 16;
 }
 
 static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
@@ -512,6 +524,33 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
 	sdhci_writel(host, ctrl, ESDHC_PROCTL);
 }
 
+static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
+{
+	u32 val;
+	u32 timeout;
+
+	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
+
+	if (enable)
+		val |= ESDHC_CLOCK_SDCLKEN;
+	else
+		val &= ~ESDHC_CLOCK_SDCLKEN;
+
+	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
+
+	timeout = 20;
+	val = ESDHC_CLOCK_STABLE;
+	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
+		if (timeout == 0) {
+			pr_err("%s: Internal clock never stabilised.\n",
+				mmc_hostname(host->mmc));
+			break;
+		}
+		timeout--;
+		mdelay(1);
+	}
+}
+
 static void esdhc_reset(struct sdhci_host *host, u8 mask)
 {
 	sdhci_reset(host, mask);
@@ -613,6 +652,9 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
 {
 	struct sdhci_pltfm_host *pltfm_host;
 	struct sdhci_esdhc *esdhc;
+	struct device_node *np;
+	struct clk *clk;
+	u32 val;
 	u16 host_ver;
 
 	pltfm_host = sdhci_priv(host);
@@ -626,6 +668,30 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
 		esdhc->quirk_incorrect_hostver = true;
 	else
 		esdhc->quirk_incorrect_hostver = false;
+
+	np = pdev->dev.of_node;
+	clk = of_clk_get(np, 0);
+	if (!IS_ERR(clk)) {
+		/*
+		 * esdhc->peripheral_clock would be assigned with a value
+		 * which is eSDHC base clock when use periperal clock.
+		 * For ls1046a, the clock value got by common clk API is
+		 * peripheral clock while the eSDHC base clock is 1/2
+		 * peripheral clock.
+		 */
+		if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
+			esdhc->peripheral_clock = clk_get_rate(clk) / 2;
+		else
+			esdhc->peripheral_clock = clk_get_rate(clk);
+	}
+
+	if (esdhc->peripheral_clock) {
+		esdhc_clock_enable(host, false);
+		val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+		val |= ESDHC_PERIPHERAL_CLK_SEL;
+		sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
+		esdhc_clock_enable(host, true);
+	}
 }
 
 static int sdhci_esdhc_probe(struct platform_device *pdev)
-- 
2.1.0.27.g96db324

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

* [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal voltage switch
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-03-27  7:49   ` Yangbo Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Adrian Hunter, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie, Yangbo Lu

eSDHC supports signal voltage switch from 3.3v to 1.8v by
eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
signal SDHC_VS, and there must be a control circuit out of eSDHC
to change the signal voltage according to SDHC_VS output signal.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- Used Adrain's method to support voltage switching:
          host->mmc_host_ops.start_signal_voltage_switch =
                     esdhc_signal_voltage_switch;
Changes for v3:
	- Put .start_signal_voltage_switch assigning after IS_ERR(host) check.
---
 drivers/mmc/host/sdhci-esdhc.h    |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c | 74 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index 5343fc0..6869567 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -37,6 +37,7 @@
 
 /* Protocol Control Register */
 #define ESDHC_PROCTL			0x28
+#define ESDHC_VOLT_SEL			0x00000400
 #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
 #define ESDHC_CTRL_8BITBUS		(0x2 << 1)
 #define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 7ce1caf..a70499a 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/sys_soc.h>
@@ -559,6 +560,76 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask)
 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 }
 
+/* The SCFG, Supplemental Configuration Unit, provides SoC specific
+ * configuration and status registers for the device. There is a
+ * SDHC IO VSEL control register on SCFG for some platforms. It's
+ * used to support SDHC IO voltage switching.
+ */
+static const struct of_device_id scfg_device_ids[] = {
+	{ .compatible = "fsl,t1040-scfg", },
+	{ .compatible = "fsl,ls1012a-scfg", },
+	{ .compatible = "fsl,ls1046a-scfg", },
+	{}
+};
+
+/* SDHC IO VSEL control register definition */
+#define SCFG_SDHCIOVSELCR	0x408
+#define SDHCIOVSELCR_TGLEN	0x80000000
+#define SDHCIOVSELCR_VSELVAL	0x60000000
+#define SDHCIOVSELCR_SDHC_VS	0x00000001
+
+static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
+				       struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct device_node *scfg_node;
+	void __iomem *scfg_base = NULL;
+	u32 sdhciovselcr;
+	u32 val;
+
+	/*
+	 * Signal Voltage Switching is only applicable for Host Controllers
+	 * v3.00 and above.
+	 */
+	if (host->version < SDHCI_SPEC_300)
+		return 0;
+
+	val = sdhci_readl(host, ESDHC_PROCTL);
+
+	switch (ios->signal_voltage) {
+	case MMC_SIGNAL_VOLTAGE_330:
+		val &= ~ESDHC_VOLT_SEL;
+		sdhci_writel(host, val, ESDHC_PROCTL);
+		return 0;
+	case MMC_SIGNAL_VOLTAGE_180:
+		scfg_node = of_find_matching_node(NULL, scfg_device_ids);
+		if (scfg_node)
+			scfg_base = of_iomap(scfg_node, 0);
+		if (scfg_base) {
+			sdhciovselcr = SDHCIOVSELCR_TGLEN |
+				       SDHCIOVSELCR_VSELVAL;
+			iowrite32be(sdhciovselcr,
+				scfg_base + SCFG_SDHCIOVSELCR);
+
+			val |= ESDHC_VOLT_SEL;
+			sdhci_writel(host, val, ESDHC_PROCTL);
+			mdelay(5);
+
+			sdhciovselcr = SDHCIOVSELCR_TGLEN |
+				       SDHCIOVSELCR_SDHC_VS;
+			iowrite32be(sdhciovselcr,
+				scfg_base + SCFG_SDHCIOVSELCR);
+			iounmap(scfg_base);
+		} else {
+			val |= ESDHC_VOLT_SEL;
+			sdhci_writel(host, val, ESDHC_PROCTL);
+		}
+		return 0;
+	default:
+		return 0;
+	}
+}
+
 #ifdef CONFIG_PM_SLEEP
 static u32 esdhc_proctl;
 static int esdhc_of_suspend(struct device *dev)
@@ -714,6 +785,9 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
+	host->mmc_host_ops.start_signal_voltage_switch =
+		esdhc_signal_voltage_switch;
+
 	esdhc_init(pdev, host);
 
 	sdhci_get_of_property(pdev);
-- 
2.1.0.27.g96db324


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

* [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal voltage switch
@ 2017-03-27  7:49   ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

eSDHC supports signal voltage switch from 3.3v to 1.8v by
eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
signal SDHC_VS, and there must be a control circuit out of eSDHC
to change the signal voltage according to SDHC_VS output signal.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- Used Adrain's method to support voltage switching:
          host->mmc_host_ops.start_signal_voltage_switch =
                     esdhc_signal_voltage_switch;
Changes for v3:
	- Put .start_signal_voltage_switch assigning after IS_ERR(host) check.
---
 drivers/mmc/host/sdhci-esdhc.h    |  1 +
 drivers/mmc/host/sdhci-of-esdhc.c | 74 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 75 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index 5343fc0..6869567 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -37,6 +37,7 @@
 
 /* Protocol Control Register */
 #define ESDHC_PROCTL			0x28
+#define ESDHC_VOLT_SEL			0x00000400
 #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
 #define ESDHC_CTRL_8BITBUS		(0x2 << 1)
 #define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 7ce1caf..a70499a 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/sys_soc.h>
@@ -559,6 +560,76 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask)
 	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
 }
 
+/* The SCFG, Supplemental Configuration Unit, provides SoC specific
+ * configuration and status registers for the device. There is a
+ * SDHC IO VSEL control register on SCFG for some platforms. It's
+ * used to support SDHC IO voltage switching.
+ */
+static const struct of_device_id scfg_device_ids[] = {
+	{ .compatible = "fsl,t1040-scfg", },
+	{ .compatible = "fsl,ls1012a-scfg", },
+	{ .compatible = "fsl,ls1046a-scfg", },
+	{}
+};
+
+/* SDHC IO VSEL control register definition */
+#define SCFG_SDHCIOVSELCR	0x408
+#define SDHCIOVSELCR_TGLEN	0x80000000
+#define SDHCIOVSELCR_VSELVAL	0x60000000
+#define SDHCIOVSELCR_SDHC_VS	0x00000001
+
+static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
+				       struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct device_node *scfg_node;
+	void __iomem *scfg_base = NULL;
+	u32 sdhciovselcr;
+	u32 val;
+
+	/*
+	 * Signal Voltage Switching is only applicable for Host Controllers
+	 * v3.00 and above.
+	 */
+	if (host->version < SDHCI_SPEC_300)
+		return 0;
+
+	val = sdhci_readl(host, ESDHC_PROCTL);
+
+	switch (ios->signal_voltage) {
+	case MMC_SIGNAL_VOLTAGE_330:
+		val &= ~ESDHC_VOLT_SEL;
+		sdhci_writel(host, val, ESDHC_PROCTL);
+		return 0;
+	case MMC_SIGNAL_VOLTAGE_180:
+		scfg_node = of_find_matching_node(NULL, scfg_device_ids);
+		if (scfg_node)
+			scfg_base = of_iomap(scfg_node, 0);
+		if (scfg_base) {
+			sdhciovselcr = SDHCIOVSELCR_TGLEN |
+				       SDHCIOVSELCR_VSELVAL;
+			iowrite32be(sdhciovselcr,
+				scfg_base + SCFG_SDHCIOVSELCR);
+
+			val |= ESDHC_VOLT_SEL;
+			sdhci_writel(host, val, ESDHC_PROCTL);
+			mdelay(5);
+
+			sdhciovselcr = SDHCIOVSELCR_TGLEN |
+				       SDHCIOVSELCR_SDHC_VS;
+			iowrite32be(sdhciovselcr,
+				scfg_base + SCFG_SDHCIOVSELCR);
+			iounmap(scfg_base);
+		} else {
+			val |= ESDHC_VOLT_SEL;
+			sdhci_writel(host, val, ESDHC_PROCTL);
+		}
+		return 0;
+	default:
+		return 0;
+	}
+}
+
 #ifdef CONFIG_PM_SLEEP
 static u32 esdhc_proctl;
 static int esdhc_of_suspend(struct device *dev)
@@ -714,6 +785,9 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
 	if (IS_ERR(host))
 		return PTR_ERR(host);
 
+	host->mmc_host_ops.start_signal_voltage_switch =
+		esdhc_signal_voltage_switch;
+
 	esdhc_init(pdev, host);
 
 	sdhci_get_of_property(pdev);
-- 
2.1.0.27.g96db324

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

* [v3, 3/7] mmc: sdhci-of-esdhc: add tuning support
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-03-27  7:49   ` Yangbo Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Adrian Hunter, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie, Yangbo Lu

eSDHC uses tuning block for tuning procedure. So the tuning
block control register must be configured properly before tuning.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- Replaced old function for mmc_host_ops.execute_tuning with
	  esdhc_execute_tuning to support eSDHC tuning.
Changes for v3:
	- Put .execute_tuning assigning after after IS_ERR(host) check.
---
 drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
 drivers/mmc/host/sdhci-of-esdhc.c | 20 ++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index 6869567..c4bbd74 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -53,9 +53,14 @@
 #define ESDHC_CLOCK_HCKEN		0x00000002
 #define ESDHC_CLOCK_IPGEN		0x00000001
 
+/* Tuning Block Control Register */
+#define ESDHC_TBCTL			0x120
+#define ESDHC_TB_EN			0x00000004
+
 /* Control Register for DMA transfer */
 #define ESDHC_DMA_SYSCTL		0x40c
 #define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
+#define ESDHC_FLUSH_ASYNC_FIFO		0x00040000
 #define ESDHC_DMA_SNOOP			0x00000040
 
 #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index a70499a..8c8e147 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -630,6 +630,25 @@ static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
 	}
 }
 
+static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	u32 val;
+
+	/* Use tuning block for tuning procedure */
+	esdhc_clock_enable(host, false);
+	val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+	val |= ESDHC_FLUSH_ASYNC_FIFO;
+	sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
+
+	val = sdhci_readl(host, ESDHC_TBCTL);
+	val |= ESDHC_TB_EN;
+	sdhci_writel(host, val, ESDHC_TBCTL);
+	esdhc_clock_enable(host, true);
+
+	return sdhci_execute_tuning(mmc, opcode);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static u32 esdhc_proctl;
 static int esdhc_of_suspend(struct device *dev)
@@ -787,6 +806,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
 
 	host->mmc_host_ops.start_signal_voltage_switch =
 		esdhc_signal_voltage_switch;
+	host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
 
 	esdhc_init(pdev, host);
 
-- 
2.1.0.27.g96db324


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

* [v3, 3/7] mmc: sdhci-of-esdhc: add tuning support
@ 2017-03-27  7:49   ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

eSDHC uses tuning block for tuning procedure. So the tuning
block control register must be configured properly before tuning.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- Replaced old function for mmc_host_ops.execute_tuning with
	  esdhc_execute_tuning to support eSDHC tuning.
Changes for v3:
	- Put .execute_tuning assigning after after IS_ERR(host) check.
---
 drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
 drivers/mmc/host/sdhci-of-esdhc.c | 20 ++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index 6869567..c4bbd74 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -53,9 +53,14 @@
 #define ESDHC_CLOCK_HCKEN		0x00000002
 #define ESDHC_CLOCK_IPGEN		0x00000001
 
+/* Tuning Block Control Register */
+#define ESDHC_TBCTL			0x120
+#define ESDHC_TB_EN			0x00000004
+
 /* Control Register for DMA transfer */
 #define ESDHC_DMA_SYSCTL		0x40c
 #define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
+#define ESDHC_FLUSH_ASYNC_FIFO		0x00040000
 #define ESDHC_DMA_SNOOP			0x00000040
 
 #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index a70499a..8c8e147 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -630,6 +630,25 @@ static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
 	}
 }
 
+static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	u32 val;
+
+	/* Use tuning block for tuning procedure */
+	esdhc_clock_enable(host, false);
+	val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
+	val |= ESDHC_FLUSH_ASYNC_FIFO;
+	sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
+
+	val = sdhci_readl(host, ESDHC_TBCTL);
+	val |= ESDHC_TB_EN;
+	sdhci_writel(host, val, ESDHC_TBCTL);
+	esdhc_clock_enable(host, true);
+
+	return sdhci_execute_tuning(mmc, opcode);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static u32 esdhc_proctl;
 static int esdhc_of_suspend(struct device *dev)
@@ -787,6 +806,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
 
 	host->mmc_host_ops.start_signal_voltage_switch =
 		esdhc_signal_voltage_switch;
+	host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
 
 	esdhc_init(pdev, host);
 
-- 
2.1.0.27.g96db324

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

* [v3, 4/7] mmc: sdhci: Control the delay between tuning commands
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-03-27  7:49   ` Yangbo Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Adrian Hunter, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie, Yangbo Lu

From: Adrian Hunter <adrian.hunter@intel.com>

The delay between tuning commands for SD cards is not part of the
specification. A driver that needs it probably needs it for eMMC
too, whereas most drivers would probably like to set it to 0. Make
it a host member (host->tuning_delay) that defaults to the existing
behaviour. Drivers can set it to zero to eliminate the delay, or
set it to a positive value to always have a delay.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- Used a host member for tuning delay instead of a quirk.(Adrian's patch)
	- Addressed warning in checkpatch.
---
 drivers/mmc/host/sdhci.c | 11 ++++++++---
 drivers/mmc/host/sdhci.h |  2 ++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 0d4485d..ffd1607 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2100,9 +2100,9 @@ static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
 			break;
 		}
 
-		/* eMMC spec does not require a delay between tuning cycles */
-		if (opcode == MMC_SEND_TUNING_BLOCK)
-			mdelay(1);
+		/* Spec does not require a delay between tuning cycles */
+		if (host->tuning_delay > 0)
+			mdelay(host->tuning_delay);
 	}
 
 	pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
@@ -2164,6 +2164,9 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
 	host->mmc->retune_period = tuning_count;
 
+	if (host->tuning_delay < 0)
+		host->tuning_delay = opcode == MMC_SEND_TUNING_BLOCK;
+
 	sdhci_start_tuning(host);
 
 	__sdhci_execute_tuning(host, opcode);
@@ -3108,6 +3111,8 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
 	host->cqe_ier     = SDHCI_CQE_INT_MASK;
 	host->cqe_err_ier = SDHCI_CQE_INT_ERR_MASK;
 
+	host->tuning_delay = -1;
+
 	return host;
 }
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index fdb5d7e..2407960 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -538,6 +538,8 @@ struct sdhci_host {
 #define SDHCI_TUNING_MODE_1	0
 #define SDHCI_TUNING_MODE_2	1
 #define SDHCI_TUNING_MODE_3	2
+	/* Delay (ms) between tuning commands */
+	int			tuning_delay;
 
 	unsigned long private[0] ____cacheline_aligned;
 };
-- 
2.1.0.27.g96db324


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

* [v3, 4/7] mmc: sdhci: Control the delay between tuning commands
@ 2017-03-27  7:49   ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

From: Adrian Hunter <adrian.hunter@intel.com>

The delay between tuning commands for SD cards is not part of the
specification. A driver that needs it probably needs it for eMMC
too, whereas most drivers would probably like to set it to 0. Make
it a host member (host->tuning_delay) that defaults to the existing
behaviour. Drivers can set it to zero to eliminate the delay, or
set it to a positive value to always have a delay.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- Used a host member for tuning delay instead of a quirk.(Adrian's patch)
	- Addressed warning in checkpatch.
---
 drivers/mmc/host/sdhci.c | 11 ++++++++---
 drivers/mmc/host/sdhci.h |  2 ++
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 0d4485d..ffd1607 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2100,9 +2100,9 @@ static void __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
 			break;
 		}
 
-		/* eMMC spec does not require a delay between tuning cycles */
-		if (opcode == MMC_SEND_TUNING_BLOCK)
-			mdelay(1);
+		/* Spec does not require a delay between tuning cycles */
+		if (host->tuning_delay > 0)
+			mdelay(host->tuning_delay);
 	}
 
 	pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
@@ -2164,6 +2164,9 @@ int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 
 	host->mmc->retune_period = tuning_count;
 
+	if (host->tuning_delay < 0)
+		host->tuning_delay = opcode == MMC_SEND_TUNING_BLOCK;
+
 	sdhci_start_tuning(host);
 
 	__sdhci_execute_tuning(host, opcode);
@@ -3108,6 +3111,8 @@ struct sdhci_host *sdhci_alloc_host(struct device *dev,
 	host->cqe_ier     = SDHCI_CQE_INT_MASK;
 	host->cqe_err_ier = SDHCI_CQE_INT_ERR_MASK;
 
+	host->tuning_delay = -1;
+
 	return host;
 }
 
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index fdb5d7e..2407960 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -538,6 +538,8 @@ struct sdhci_host {
 #define SDHCI_TUNING_MODE_1	0
 #define SDHCI_TUNING_MODE_2	1
 #define SDHCI_TUNING_MODE_3	2
+	/* Delay (ms) between tuning commands */
+	int			tuning_delay;
 
 	unsigned long private[0] ____cacheline_aligned;
 };
-- 
2.1.0.27.g96db324

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

* [v3, 5/7] mmc: sdhci-of-esdhc: add delay between tuning cycles
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-03-27  7:49   ` Yangbo Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Adrian Hunter, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie, Yangbo Lu

It's observed that eSDHC needed delay between tuning cycles for
HS200 successful tuning. This patch is to set 1ms delay for that.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- Used a host member for tuning delay instead of a quirk.
---
 drivers/mmc/host/sdhci-of-esdhc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 8c8e147..0754ef4 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -807,6 +807,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
 	host->mmc_host_ops.start_signal_voltage_switch =
 		esdhc_signal_voltage_switch;
 	host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
+	host->tuning_delay = 1;
 
 	esdhc_init(pdev, host);
 
-- 
2.1.0.27.g96db324


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

* [v3, 5/7] mmc: sdhci-of-esdhc: add delay between tuning cycles
@ 2017-03-27  7:49   ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

It's observed that eSDHC needed delay between tuning cycles for
HS200 successful tuning. This patch is to set 1ms delay for that.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- Used a host member for tuning delay instead of a quirk.
---
 drivers/mmc/host/sdhci-of-esdhc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 8c8e147..0754ef4 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -807,6 +807,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
 	host->mmc_host_ops.start_signal_voltage_switch =
 		esdhc_signal_voltage_switch;
 	host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
+	host->tuning_delay = 1;
 
 	esdhc_init(pdev, host);
 
-- 
2.1.0.27.g96db324

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

* [v3, 6/7] arm64: dts: ls1046a: add clocks property and compatible for eSDHC node
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-03-27  7:49     ` Yangbo Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Adrian Hunter, Rob Herring,
	Mark Rutland, Catalin Marinas, Will Deacon
  Cc: Xiaobo Xie, Yangbo Lu

The eSDHC could select peripheral clock or platform clock as clock source.
In default, we use platform clock. This patch is to add clocks property
describing peripheral clock for eSDHC node. The driver could use common clk
APIs to get peripheral clock. Also add a compatible for ls1046a eSDHC node.

Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
---
Changes for v2:
	- None
Changes for v3:
	- None
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 4a164b8..141a513 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -209,10 +209,11 @@
 		};
 
 		esdhc: esdhc@1560000 {
-			compatible = "fsl,esdhc";
+			compatible = "fsl,ls1046a-esdhc", "fsl,esdhc";
 			reg = <0x0 0x1560000 0x0 0x10000>;
 			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
 			clock-frequency = <0>;
+			clocks = <&clockgen 2 1>;
 			voltage-ranges = <1800 1800 3300 3300>;
 			sdhci,auto-cmd12;
 			big-endian;
-- 
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [v3, 6/7] arm64: dts: ls1046a: add clocks property and compatible for eSDHC node
@ 2017-03-27  7:49     ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

The eSDHC could select peripheral clock or platform clock as clock source.
In default, we use platform clock. This patch is to add clocks property
describing peripheral clock for eSDHC node. The driver could use common clk
APIs to get peripheral clock. Also add a compatible for ls1046a eSDHC node.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- None
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 4a164b8..141a513 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -209,10 +209,11 @@
 		};
 
 		esdhc: esdhc at 1560000 {
-			compatible = "fsl,esdhc";
+			compatible = "fsl,ls1046a-esdhc", "fsl,esdhc";
 			reg = <0x0 0x1560000 0x0 0x10000>;
 			interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
 			clock-frequency = <0>;
+			clocks = <&clockgen 2 1>;
 			voltage-ranges = <1800 1800 3300 3300>;
 			sdhci,auto-cmd12;
 			big-endian;
-- 
2.1.0.27.g96db324

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

* [v3, 7/7] arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-03-27  7:49   ` Yangbo Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Adrian Hunter, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie, Yangbo Lu

Add HS200/UHS-1 properties in eSDHC node to support these
speed modes in driver.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- None
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
index d1ccc00..08528c2 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
@@ -64,6 +64,14 @@
 	};
 };
 
+&esdhc {
+	mmc-hs200-1_8v;
+	sd-uhs-sdr104;
+	sd-uhs-sdr50;
+	sd-uhs-sdr25;
+	sd-uhs-sdr12;
+};
+
 &duart0 {
 	status = "okay";
 };
-- 
2.1.0.27.g96db324


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

* [v3, 7/7] arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support
@ 2017-03-27  7:49   ` Yangbo Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Yangbo Lu @ 2017-03-27  7:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add HS200/UHS-1 properties in eSDHC node to support these
speed modes in driver.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
---
Changes for v2:
	- None
Changes for v3:
	- None
---
 arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
index d1ccc00..08528c2 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
@@ -64,6 +64,14 @@
 	};
 };
 
+&esdhc {
+	mmc-hs200-1_8v;
+	sd-uhs-sdr104;
+	sd-uhs-sdr50;
+	sd-uhs-sdr25;
+	sd-uhs-sdr12;
+};
+
 &duart0 {
 	status = "okay";
 };
-- 
2.1.0.27.g96db324

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

* RE: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-04-06  8:02   ` Y.B. Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-06  8:02 UTC (permalink / raw)
  To: Y.B. Lu, linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Adrian Hunter, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie

Hi all,

Any comments? Thanks.


Best regards,
Yangbo Lu

> -----Original Message-----
> From: Yangbo Lu [mailto:yangbo.lu@nxp.com]
> Sent: Monday, March 27, 2017 3:50 PM
> To: linux-mmc@vger.kernel.org; devicetree@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; ulf.hansson@linaro.org; Adrian Hunter; Rob
> Herring; Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie; Y.B. Lu
> Subject: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
> 
> It's complicated to support SD UHS-I and eMMC HS200 for eSDHC because
> there're many differences between eSDHC and SD/eMMC spec. Several
> differences as below must be considered:
> 1. Peripheral clock must be used instead of platform clock.
>     - eSDHC could select peripheral clock or platform clock as its clock
>       source. According to RM, UHS-I/HS200 must use peripheral clock
> since
>       it supports higher frequency than platform clock.
>     - Patch 1 and patch 6 is to support this.
> 2. Signal voltage switching requires a control circuit out of eSDHC.
>     - eSDHC supports signal voltage switch from 3.3v to 1.8v by
>       eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
>       signal SDHC_VS, and there must be a control circuit out of eSDHC
>       to change the signal voltage according to SDHC_VS output signal.
>     - Patch 2 is to support this.
> 3. eSDHC uses tuning block for tuning procedure.
>     - Tuning clock control register must be configured before tuning.
>     - Patch 3 is to support this.
> 4. Delay is needed between tuning cycles for HS200 tuning.
>     - Once a patch removed mdelay between tuning cycles.
>       But eSDHC needs it.
>     - Patch 4 and patch 5 is to support this.
> 5. UHS-I/HS200 modes could be enabled in dts node.
>     - Patch 7 is to support this.
> 
> Please review and merge these patches on mmc git tree if no changes are
> required.
> 
> Adrian Hunter (1):
>   mmc: sdhci: Control the delay between tuning commands
> 
> Yangbo Lu (6):
>   mmc: sdhci-of-esdhc: add peripheral clock support
>   mmc: sdhci-of-esdhc: add support for signal voltage switch
>   mmc: sdhci-of-esdhc: add tuning support
>   mmc: sdhci-of-esdhc: add delay between tuning cycles
>   arm64: dts: ls1046a: add clocks property and compatible for eSDHC node
>   arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support
> 
>  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts |   8 ++
>  arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi    |   3 +-
>  drivers/mmc/host/sdhci-esdhc.h                    |   7 +
>  drivers/mmc/host/sdhci-of-esdhc.c                 | 165
> +++++++++++++++++++++-
>  drivers/mmc/host/sdhci.c                          |  11 +-
>  drivers/mmc/host/sdhci.h                          |   2 +
>  6 files changed, 190 insertions(+), 6 deletions(-)
> 
> --
> 2.1.0.27.g96db324


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

* [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
@ 2017-04-06  8:02   ` Y.B. Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-06  8:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi all,

Any comments? Thanks.


Best regards,
Yangbo Lu

> -----Original Message-----
> From: Yangbo Lu [mailto:yangbo.lu at nxp.com]
> Sent: Monday, March 27, 2017 3:50 PM
> To: linux-mmc at vger.kernel.org; devicetree at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; ulf.hansson at linaro.org; Adrian Hunter; Rob
> Herring; Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie; Y.B. Lu
> Subject: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
> 
> It's complicated to support SD UHS-I and eMMC HS200 for eSDHC because
> there're many differences between eSDHC and SD/eMMC spec. Several
> differences as below must be considered:
> 1. Peripheral clock must be used instead of platform clock.
>     - eSDHC could select peripheral clock or platform clock as its clock
>       source. According to RM, UHS-I/HS200 must use peripheral clock
> since
>       it supports higher frequency than platform clock.
>     - Patch 1 and patch 6 is to support this.
> 2. Signal voltage switching requires a control circuit out of eSDHC.
>     - eSDHC supports signal voltage switch from 3.3v to 1.8v by
>       eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
>       signal SDHC_VS, and there must be a control circuit out of eSDHC
>       to change the signal voltage according to SDHC_VS output signal.
>     - Patch 2 is to support this.
> 3. eSDHC uses tuning block for tuning procedure.
>     - Tuning clock control register must be configured before tuning.
>     - Patch 3 is to support this.
> 4. Delay is needed between tuning cycles for HS200 tuning.
>     - Once a patch removed mdelay between tuning cycles.
>       But eSDHC needs it.
>     - Patch 4 and patch 5 is to support this.
> 5. UHS-I/HS200 modes could be enabled in dts node.
>     - Patch 7 is to support this.
> 
> Please review and merge these patches on mmc git tree if no changes are
> required.
> 
> Adrian Hunter (1):
>   mmc: sdhci: Control the delay between tuning commands
> 
> Yangbo Lu (6):
>   mmc: sdhci-of-esdhc: add peripheral clock support
>   mmc: sdhci-of-esdhc: add support for signal voltage switch
>   mmc: sdhci-of-esdhc: add tuning support
>   mmc: sdhci-of-esdhc: add delay between tuning cycles
>   arm64: dts: ls1046a: add clocks property and compatible for eSDHC node
>   arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support
> 
>  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts |   8 ++
>  arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi    |   3 +-
>  drivers/mmc/host/sdhci-esdhc.h                    |   7 +
>  drivers/mmc/host/sdhci-of-esdhc.c                 | 165
> +++++++++++++++++++++-
>  drivers/mmc/host/sdhci.c                          |  11 +-
>  drivers/mmc/host/sdhci.h                          |   2 +
>  6 files changed, 190 insertions(+), 6 deletions(-)
> 
> --
> 2.1.0.27.g96db324

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

* RE: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
  2017-03-27  7:49 ` Yangbo Lu
@ 2017-04-10  8:20   ` Y.B. Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-10  8:20 UTC (permalink / raw)
  To: linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Adrian Hunter, Rob Herring,
	Mark Rutland, Catalin Marinas, Will Deacon
  Cc: Xiaobo Xie

Hi Andrian and Uffe,

Do you have any comments on MMC patches?
Could you help to merge the mmc patches if there is no changes requested?

Regarding to the dts patches, I have some more platforms to support.
So I'd like to drop them currently, and send them all to arm mailing list for reviewing.

Thanks a lot.

Best regards,
Yangbo Lu

> -----Original Message-----
> From: Y.B. Lu
> Sent: Thursday, April 06, 2017 4:02 PM
> To: Y.B. Lu; linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org; ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org; Adrian
> Hunter; Rob Herring; Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie
> Subject: RE: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
> 
> Hi all,
> 
> Any comments? Thanks.
> 
> 
> Best regards,
> Yangbo Lu
> 
> > -----Original Message-----
> > From: Yangbo Lu [mailto:yangbo.lu-3arQi8VN3Tc@public.gmane.org]
> > Sent: Monday, March 27, 2017 3:50 PM
> > To: linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; linux-arm-
> > kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org; ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org; Adrian Hunter; Rob
> > Herring; Mark Rutland; Catalin Marinas; Will Deacon
> > Cc: Xiaobo Xie; Y.B. Lu
> > Subject: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
> >
> > It's complicated to support SD UHS-I and eMMC HS200 for eSDHC because
> > there're many differences between eSDHC and SD/eMMC spec. Several
> > differences as below must be considered:
> > 1. Peripheral clock must be used instead of platform clock.
> >     - eSDHC could select peripheral clock or platform clock as its
> clock
> >       source. According to RM, UHS-I/HS200 must use peripheral clock
> > since
> >       it supports higher frequency than platform clock.
> >     - Patch 1 and patch 6 is to support this.
> > 2. Signal voltage switching requires a control circuit out of eSDHC.
> >     - eSDHC supports signal voltage switch from 3.3v to 1.8v by
> >       eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
> >       signal SDHC_VS, and there must be a control circuit out of eSDHC
> >       to change the signal voltage according to SDHC_VS output signal.
> >     - Patch 2 is to support this.
> > 3. eSDHC uses tuning block for tuning procedure.
> >     - Tuning clock control register must be configured before tuning.
> >     - Patch 3 is to support this.
> > 4. Delay is needed between tuning cycles for HS200 tuning.
> >     - Once a patch removed mdelay between tuning cycles.
> >       But eSDHC needs it.
> >     - Patch 4 and patch 5 is to support this.
> > 5. UHS-I/HS200 modes could be enabled in dts node.
> >     - Patch 7 is to support this.
> >
> > Please review and merge these patches on mmc git tree if no changes
> > are required.
> >
> > Adrian Hunter (1):
> >   mmc: sdhci: Control the delay between tuning commands
> >
> > Yangbo Lu (6):
> >   mmc: sdhci-of-esdhc: add peripheral clock support
> >   mmc: sdhci-of-esdhc: add support for signal voltage switch
> >   mmc: sdhci-of-esdhc: add tuning support
> >   mmc: sdhci-of-esdhc: add delay between tuning cycles
> >   arm64: dts: ls1046a: add clocks property and compatible for eSDHC
> node
> >   arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support
> >
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts |   8 ++
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi    |   3 +-
> >  drivers/mmc/host/sdhci-esdhc.h                    |   7 +
> >  drivers/mmc/host/sdhci-of-esdhc.c                 | 165
> > +++++++++++++++++++++-
> >  drivers/mmc/host/sdhci.c                          |  11 +-
> >  drivers/mmc/host/sdhci.h                          |   2 +
> >  6 files changed, 190 insertions(+), 6 deletions(-)
> >
> > --
> > 2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
@ 2017-04-10  8:20   ` Y.B. Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-10  8:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Andrian and Uffe,

Do you have any comments on MMC patches?
Could you help to merge the mmc patches if there is no changes requested?

Regarding to the dts patches, I have some more platforms to support.
So I'd like to drop them currently, and send them all to arm mailing list for reviewing.

Thanks a lot.

Best regards,
Yangbo Lu

> -----Original Message-----
> From: Y.B. Lu
> Sent: Thursday, April 06, 2017 4:02 PM
> To: Y.B. Lu; linux-mmc at vger.kernel.org; devicetree at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; ulf.hansson at linaro.org; Adrian
> Hunter; Rob Herring; Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie
> Subject: RE: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
> 
> Hi all,
> 
> Any comments? Thanks.
> 
> 
> Best regards,
> Yangbo Lu
> 
> > -----Original Message-----
> > From: Yangbo Lu [mailto:yangbo.lu at nxp.com]
> > Sent: Monday, March 27, 2017 3:50 PM
> > To: linux-mmc at vger.kernel.org; devicetree at vger.kernel.org; linux-arm-
> > kernel at lists.infradead.org; ulf.hansson at linaro.org; Adrian Hunter; Rob
> > Herring; Mark Rutland; Catalin Marinas; Will Deacon
> > Cc: Xiaobo Xie; Y.B. Lu
> > Subject: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
> >
> > It's complicated to support SD UHS-I and eMMC HS200 for eSDHC because
> > there're many differences between eSDHC and SD/eMMC spec. Several
> > differences as below must be considered:
> > 1. Peripheral clock must be used instead of platform clock.
> >     - eSDHC could select peripheral clock or platform clock as its
> clock
> >       source. According to RM, UHS-I/HS200 must use peripheral clock
> > since
> >       it supports higher frequency than platform clock.
> >     - Patch 1 and patch 6 is to support this.
> > 2. Signal voltage switching requires a control circuit out of eSDHC.
> >     - eSDHC supports signal voltage switch from 3.3v to 1.8v by
> >       eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
> >       signal SDHC_VS, and there must be a control circuit out of eSDHC
> >       to change the signal voltage according to SDHC_VS output signal.
> >     - Patch 2 is to support this.
> > 3. eSDHC uses tuning block for tuning procedure.
> >     - Tuning clock control register must be configured before tuning.
> >     - Patch 3 is to support this.
> > 4. Delay is needed between tuning cycles for HS200 tuning.
> >     - Once a patch removed mdelay between tuning cycles.
> >       But eSDHC needs it.
> >     - Patch 4 and patch 5 is to support this.
> > 5. UHS-I/HS200 modes could be enabled in dts node.
> >     - Patch 7 is to support this.
> >
> > Please review and merge these patches on mmc git tree if no changes
> > are required.
> >
> > Adrian Hunter (1):
> >   mmc: sdhci: Control the delay between tuning commands
> >
> > Yangbo Lu (6):
> >   mmc: sdhci-of-esdhc: add peripheral clock support
> >   mmc: sdhci-of-esdhc: add support for signal voltage switch
> >   mmc: sdhci-of-esdhc: add tuning support
> >   mmc: sdhci-of-esdhc: add delay between tuning cycles
> >   arm64: dts: ls1046a: add clocks property and compatible for eSDHC
> node
> >   arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support
> >
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts |   8 ++
> >  arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi    |   3 +-
> >  drivers/mmc/host/sdhci-esdhc.h                    |   7 +
> >  drivers/mmc/host/sdhci-of-esdhc.c                 | 165
> > +++++++++++++++++++++-
> >  drivers/mmc/host/sdhci.c                          |  11 +-
> >  drivers/mmc/host/sdhci.h                          |   2 +
> >  6 files changed, 190 insertions(+), 6 deletions(-)
> >
> > --
> > 2.1.0.27.g96db324

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

* Re: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
  2017-04-10  8:20   ` Y.B. Lu
@ 2017-04-10 10:48     ` Ulf Hansson
  -1 siblings, 0 replies; 37+ messages in thread
From: Ulf Hansson @ 2017-04-10 10:48 UTC (permalink / raw)
  To: Y.B. Lu
  Cc: linux-mmc, devicetree, linux-arm-kernel, Adrian Hunter,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Xiaobo Xie

On 10 April 2017 at 10:20, Y.B. Lu <yangbo.lu@nxp.com> wrote:
> Hi Andrian and Uffe,
>
> Do you have any comments on MMC patches?
> Could you help to merge the mmc patches if there is no changes requested?

I am waiting for Adrian's acks.

>
> Regarding to the dts patches, I have some more platforms to support.
> So I'd like to drop them currently, and send them all to arm mailing list for reviewing.

If it's new bindings/compatibles, the DT doc changes needs to be
discussed and agreed upon first. Actual changes to the DTS files,
should preferably go via the arm soc tree.

Kind regards
Uffe

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

* [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
@ 2017-04-10 10:48     ` Ulf Hansson
  0 siblings, 0 replies; 37+ messages in thread
From: Ulf Hansson @ 2017-04-10 10:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 10 April 2017 at 10:20, Y.B. Lu <yangbo.lu@nxp.com> wrote:
> Hi Andrian and Uffe,
>
> Do you have any comments on MMC patches?
> Could you help to merge the mmc patches if there is no changes requested?

I am waiting for Adrian's acks.

>
> Regarding to the dts patches, I have some more platforms to support.
> So I'd like to drop them currently, and send them all to arm mailing list for reviewing.

If it's new bindings/compatibles, the DT doc changes needs to be
discussed and agreed upon first. Actual changes to the DTS files,
should preferably go via the arm soc tree.

Kind regards
Uffe

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

* Re: [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
  2017-03-27  7:49   ` Yangbo Lu
@ 2017-04-10 12:36     ` Adrian Hunter
  -1 siblings, 0 replies; 37+ messages in thread
From: Adrian Hunter @ 2017-04-10 12:36 UTC (permalink / raw)
  To: Yangbo Lu, linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon
  Cc: Xiaobo Xie

On 27/03/17 10:49, Yangbo Lu wrote:
> eSDHC could select peripheral clock or platform clock as clock source by
> the PCS bit of eSDHC Control Register, and this bit couldn't be reset by
> software reset for all. In default, the platform clock is used. But we have
> to use peripheral clock since it has a higher frequency to support eMMC
> HS200 mode and SD UHS-I mode. This patch is to add peripheral clock support
> and use it instead of platform clock if it's declared in eSDHC dts node.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

Apart from minor comments:

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

> ---
> Changes for v2:
> 	- None
> Changes for v3:
> 	- None
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  1 +
>  drivers/mmc/host/sdhci-of-esdhc.c | 70 +++++++++++++++++++++++++++++++++++++--
>  2 files changed, 69 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index ece8b37..5343fc0 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -54,6 +54,7 @@
>  
>  /* Control Register for DMA transfer */
>  #define ESDHC_DMA_SYSCTL		0x40c
> +#define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
>  #define ESDHC_DMA_SNOOP			0x00000040
>  
>  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index ff37e74..7ce1caf 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -19,6 +19,7 @@
>  #include <linux/delay.h>
>  #include <linux/module.h>
>  #include <linux/sys_soc.h>
> +#include <linux/clk.h>
>  #include <linux/mmc/host.h>
>  #include "sdhci-pltfm.h"
>  #include "sdhci-esdhc.h"
> @@ -30,6 +31,7 @@ struct sdhci_esdhc {
>  	u8 vendor_ver;
>  	u8 spec_ver;
>  	bool quirk_incorrect_hostver;
> +	unsigned int peripheral_clock;
>  };
>  
>  /**
> @@ -414,15 +416,25 @@ static int esdhc_of_enable_dma(struct sdhci_host *host)
>  static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
>  {
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
>  
> -	return pltfm_host->clock;
> +	if (esdhc->peripheral_clock)
> +		return esdhc->peripheral_clock;
> +	else
> +		return pltfm_host->clock;
>  }
>  
>  static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
>  {
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> +	unsigned int clock;
>  
> -	return pltfm_host->clock / 256 / 16;
> +	if (esdhc->peripheral_clock)
> +		clock = esdhc->peripheral_clock;
> +	else
> +		clock = pltfm_host->clock;
> +	return clock / 256 / 16;
>  }
>  
>  static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
> @@ -512,6 +524,33 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
>  	sdhci_writel(host, ctrl, ESDHC_PROCTL);
>  }
>  
> +static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
> +{
> +	u32 val;
> +	u32 timeout;
> +
> +	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> +
> +	if (enable)
> +		val |= ESDHC_CLOCK_SDCLKEN;
> +	else
> +		val &= ~ESDHC_CLOCK_SDCLKEN;
> +
> +	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
> +
> +	timeout = 20;
> +	val = ESDHC_CLOCK_STABLE;
> +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
> +		if (timeout == 0) {
> +			pr_err("%s: Internal clock never stabilised.\n",
> +				mmc_hostname(host->mmc));
> +			break;
> +		}
> +		timeout--;
> +		mdelay(1);

If the time to stabilize is much less that 1 ms then this loop can waste
time.  Have a look at the change in sdhci.c.

> +	}
> +}
> +
>  static void esdhc_reset(struct sdhci_host *host, u8 mask)
>  {
>  	sdhci_reset(host, mask);
> @@ -613,6 +652,9 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
>  {
>  	struct sdhci_pltfm_host *pltfm_host;
>  	struct sdhci_esdhc *esdhc;
> +	struct device_node *np;
> +	struct clk *clk;
> +	u32 val;
>  	u16 host_ver;
>  
>  	pltfm_host = sdhci_priv(host);
> @@ -626,6 +668,30 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
>  		esdhc->quirk_incorrect_hostver = true;
>  	else
>  		esdhc->quirk_incorrect_hostver = false;
> +
> +	np = pdev->dev.of_node;
> +	clk = of_clk_get(np, 0);

Should there be a clk_put somewhere?

> +	if (!IS_ERR(clk)) {
> +		/*
> +		 * esdhc->peripheral_clock would be assigned with a value
> +		 * which is eSDHC base clock when use periperal clock.
> +		 * For ls1046a, the clock value got by common clk API is
> +		 * peripheral clock while the eSDHC base clock is 1/2
> +		 * peripheral clock.
> +		 */
> +		if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
> +			esdhc->peripheral_clock = clk_get_rate(clk) / 2;
> +		else
> +			esdhc->peripheral_clock = clk_get_rate(clk);
> +	}
> +
> +	if (esdhc->peripheral_clock) {
> +		esdhc_clock_enable(host, false);
> +		val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> +		val |= ESDHC_PERIPHERAL_CLK_SEL;
> +		sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> +		esdhc_clock_enable(host, true);
> +	}
>  }
>  
>  static int sdhci_esdhc_probe(struct platform_device *pdev)
> 


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

* [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
@ 2017-04-10 12:36     ` Adrian Hunter
  0 siblings, 0 replies; 37+ messages in thread
From: Adrian Hunter @ 2017-04-10 12:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 27/03/17 10:49, Yangbo Lu wrote:
> eSDHC could select peripheral clock or platform clock as clock source by
> the PCS bit of eSDHC Control Register, and this bit couldn't be reset by
> software reset for all. In default, the platform clock is used. But we have
> to use peripheral clock since it has a higher frequency to support eMMC
> HS200 mode and SD UHS-I mode. This patch is to add peripheral clock support
> and use it instead of platform clock if it's declared in eSDHC dts node.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

Apart from minor comments:

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

> ---
> Changes for v2:
> 	- None
> Changes for v3:
> 	- None
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  1 +
>  drivers/mmc/host/sdhci-of-esdhc.c | 70 +++++++++++++++++++++++++++++++++++++--
>  2 files changed, 69 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index ece8b37..5343fc0 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -54,6 +54,7 @@
>  
>  /* Control Register for DMA transfer */
>  #define ESDHC_DMA_SYSCTL		0x40c
> +#define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
>  #define ESDHC_DMA_SNOOP			0x00000040
>  
>  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index ff37e74..7ce1caf 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -19,6 +19,7 @@
>  #include <linux/delay.h>
>  #include <linux/module.h>
>  #include <linux/sys_soc.h>
> +#include <linux/clk.h>
>  #include <linux/mmc/host.h>
>  #include "sdhci-pltfm.h"
>  #include "sdhci-esdhc.h"
> @@ -30,6 +31,7 @@ struct sdhci_esdhc {
>  	u8 vendor_ver;
>  	u8 spec_ver;
>  	bool quirk_incorrect_hostver;
> +	unsigned int peripheral_clock;
>  };
>  
>  /**
> @@ -414,15 +416,25 @@ static int esdhc_of_enable_dma(struct sdhci_host *host)
>  static unsigned int esdhc_of_get_max_clock(struct sdhci_host *host)
>  {
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
>  
> -	return pltfm_host->clock;
> +	if (esdhc->peripheral_clock)
> +		return esdhc->peripheral_clock;
> +	else
> +		return pltfm_host->clock;
>  }
>  
>  static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
>  {
>  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> +	unsigned int clock;
>  
> -	return pltfm_host->clock / 256 / 16;
> +	if (esdhc->peripheral_clock)
> +		clock = esdhc->peripheral_clock;
> +	else
> +		clock = pltfm_host->clock;
> +	return clock / 256 / 16;
>  }
>  
>  static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int clock)
> @@ -512,6 +524,33 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
>  	sdhci_writel(host, ctrl, ESDHC_PROCTL);
>  }
>  
> +static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
> +{
> +	u32 val;
> +	u32 timeout;
> +
> +	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> +
> +	if (enable)
> +		val |= ESDHC_CLOCK_SDCLKEN;
> +	else
> +		val &= ~ESDHC_CLOCK_SDCLKEN;
> +
> +	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
> +
> +	timeout = 20;
> +	val = ESDHC_CLOCK_STABLE;
> +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
> +		if (timeout == 0) {
> +			pr_err("%s: Internal clock never stabilised.\n",
> +				mmc_hostname(host->mmc));
> +			break;
> +		}
> +		timeout--;
> +		mdelay(1);

If the time to stabilize is much less that 1 ms then this loop can waste
time.  Have a look at the change in sdhci.c.

> +	}
> +}
> +
>  static void esdhc_reset(struct sdhci_host *host, u8 mask)
>  {
>  	sdhci_reset(host, mask);
> @@ -613,6 +652,9 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
>  {
>  	struct sdhci_pltfm_host *pltfm_host;
>  	struct sdhci_esdhc *esdhc;
> +	struct device_node *np;
> +	struct clk *clk;
> +	u32 val;
>  	u16 host_ver;
>  
>  	pltfm_host = sdhci_priv(host);
> @@ -626,6 +668,30 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host)
>  		esdhc->quirk_incorrect_hostver = true;
>  	else
>  		esdhc->quirk_incorrect_hostver = false;
> +
> +	np = pdev->dev.of_node;
> +	clk = of_clk_get(np, 0);

Should there be a clk_put somewhere?

> +	if (!IS_ERR(clk)) {
> +		/*
> +		 * esdhc->peripheral_clock would be assigned with a value
> +		 * which is eSDHC base clock when use periperal clock.
> +		 * For ls1046a, the clock value got by common clk API is
> +		 * peripheral clock while the eSDHC base clock is 1/2
> +		 * peripheral clock.
> +		 */
> +		if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
> +			esdhc->peripheral_clock = clk_get_rate(clk) / 2;
> +		else
> +			esdhc->peripheral_clock = clk_get_rate(clk);
> +	}
> +
> +	if (esdhc->peripheral_clock) {
> +		esdhc_clock_enable(host, false);
> +		val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> +		val |= ESDHC_PERIPHERAL_CLK_SEL;
> +		sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> +		esdhc_clock_enable(host, true);
> +	}
>  }
>  
>  static int sdhci_esdhc_probe(struct platform_device *pdev)
> 

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

* Re: [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal voltage switch
  2017-03-27  7:49   ` Yangbo Lu
@ 2017-04-10 12:37     ` Adrian Hunter
  -1 siblings, 0 replies; 37+ messages in thread
From: Adrian Hunter @ 2017-04-10 12:37 UTC (permalink / raw)
  To: Yangbo Lu, linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon
  Cc: Xiaobo Xie

On 27/03/17 10:49, Yangbo Lu wrote:
> eSDHC supports signal voltage switch from 3.3v to 1.8v by
> eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
> signal SDHC_VS, and there must be a control circuit out of eSDHC
> to change the signal voltage according to SDHC_VS output signal.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

Apart from minor comment below:

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

> ---
> Changes for v2:
> 	- Used Adrain's method to support voltage switching:
>           host->mmc_host_ops.start_signal_voltage_switch =
>                      esdhc_signal_voltage_switch;
> Changes for v3:
> 	- Put .start_signal_voltage_switch assigning after IS_ERR(host) check.
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  1 +
>  drivers/mmc/host/sdhci-of-esdhc.c | 74 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 75 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 5343fc0..6869567 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -37,6 +37,7 @@
>  
>  /* Protocol Control Register */
>  #define ESDHC_PROCTL			0x28
> +#define ESDHC_VOLT_SEL			0x00000400
>  #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
>  #define ESDHC_CTRL_8BITBUS		(0x2 << 1)
>  #define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 7ce1caf..a70499a 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -16,6 +16,7 @@
>  #include <linux/err.h>
>  #include <linux/io.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/delay.h>
>  #include <linux/module.h>
>  #include <linux/sys_soc.h>
> @@ -559,6 +560,76 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask)
>  	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
>  }
>  
> +/* The SCFG, Supplemental Configuration Unit, provides SoC specific
> + * configuration and status registers for the device. There is a
> + * SDHC IO VSEL control register on SCFG for some platforms. It's
> + * used to support SDHC IO voltage switching.
> + */
> +static const struct of_device_id scfg_device_ids[] = {
> +	{ .compatible = "fsl,t1040-scfg", },
> +	{ .compatible = "fsl,ls1012a-scfg", },
> +	{ .compatible = "fsl,ls1046a-scfg", },
> +	{}
> +};
> +
> +/* SDHC IO VSEL control register definition */
> +#define SCFG_SDHCIOVSELCR	0x408
> +#define SDHCIOVSELCR_TGLEN	0x80000000
> +#define SDHCIOVSELCR_VSELVAL	0x60000000
> +#define SDHCIOVSELCR_SDHC_VS	0x00000001
> +
> +static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
> +				       struct mmc_ios *ios)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	struct device_node *scfg_node;
> +	void __iomem *scfg_base = NULL;
> +	u32 sdhciovselcr;
> +	u32 val;
> +
> +	/*
> +	 * Signal Voltage Switching is only applicable for Host Controllers
> +	 * v3.00 and above.
> +	 */
> +	if (host->version < SDHCI_SPEC_300)
> +		return 0;
> +
> +	val = sdhci_readl(host, ESDHC_PROCTL);
> +
> +	switch (ios->signal_voltage) {
> +	case MMC_SIGNAL_VOLTAGE_330:
> +		val &= ~ESDHC_VOLT_SEL;
> +		sdhci_writel(host, val, ESDHC_PROCTL);
> +		return 0;
> +	case MMC_SIGNAL_VOLTAGE_180:
> +		scfg_node = of_find_matching_node(NULL, scfg_device_ids);
> +		if (scfg_node)
> +			scfg_base = of_iomap(scfg_node, 0);
> +		if (scfg_base) {
> +			sdhciovselcr = SDHCIOVSELCR_TGLEN |
> +				       SDHCIOVSELCR_VSELVAL;
> +			iowrite32be(sdhciovselcr,
> +				scfg_base + SCFG_SDHCIOVSELCR);

In other places there is support for little endian also, so why not here?

> +
> +			val |= ESDHC_VOLT_SEL;
> +			sdhci_writel(host, val, ESDHC_PROCTL);
> +			mdelay(5);
> +
> +			sdhciovselcr = SDHCIOVSELCR_TGLEN |
> +				       SDHCIOVSELCR_SDHC_VS;
> +			iowrite32be(sdhciovselcr,
> +				scfg_base + SCFG_SDHCIOVSELCR);
> +			iounmap(scfg_base);
> +		} else {
> +			val |= ESDHC_VOLT_SEL;
> +			sdhci_writel(host, val, ESDHC_PROCTL);
> +		}
> +		return 0;
> +	default:
> +		return 0;
> +	}
> +}
> +
>  #ifdef CONFIG_PM_SLEEP
>  static u32 esdhc_proctl;
>  static int esdhc_of_suspend(struct device *dev)
> @@ -714,6 +785,9 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
>  	if (IS_ERR(host))
>  		return PTR_ERR(host);
>  
> +	host->mmc_host_ops.start_signal_voltage_switch =
> +		esdhc_signal_voltage_switch;
> +
>  	esdhc_init(pdev, host);
>  
>  	sdhci_get_of_property(pdev);
> 


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

* [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal voltage switch
@ 2017-04-10 12:37     ` Adrian Hunter
  0 siblings, 0 replies; 37+ messages in thread
From: Adrian Hunter @ 2017-04-10 12:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 27/03/17 10:49, Yangbo Lu wrote:
> eSDHC supports signal voltage switch from 3.3v to 1.8v by
> eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
> signal SDHC_VS, and there must be a control circuit out of eSDHC
> to change the signal voltage according to SDHC_VS output signal.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

Apart from minor comment below:

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

> ---
> Changes for v2:
> 	- Used Adrain's method to support voltage switching:
>           host->mmc_host_ops.start_signal_voltage_switch =
>                      esdhc_signal_voltage_switch;
> Changes for v3:
> 	- Put .start_signal_voltage_switch assigning after IS_ERR(host) check.
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  1 +
>  drivers/mmc/host/sdhci-of-esdhc.c | 74 +++++++++++++++++++++++++++++++++++++++
>  2 files changed, 75 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 5343fc0..6869567 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -37,6 +37,7 @@
>  
>  /* Protocol Control Register */
>  #define ESDHC_PROCTL			0x28
> +#define ESDHC_VOLT_SEL			0x00000400
>  #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
>  #define ESDHC_CTRL_8BITBUS		(0x2 << 1)
>  #define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 7ce1caf..a70499a 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -16,6 +16,7 @@
>  #include <linux/err.h>
>  #include <linux/io.h>
>  #include <linux/of.h>
> +#include <linux/of_address.h>
>  #include <linux/delay.h>
>  #include <linux/module.h>
>  #include <linux/sys_soc.h>
> @@ -559,6 +560,76 @@ static void esdhc_reset(struct sdhci_host *host, u8 mask)
>  	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
>  }
>  
> +/* The SCFG, Supplemental Configuration Unit, provides SoC specific
> + * configuration and status registers for the device. There is a
> + * SDHC IO VSEL control register on SCFG for some platforms. It's
> + * used to support SDHC IO voltage switching.
> + */
> +static const struct of_device_id scfg_device_ids[] = {
> +	{ .compatible = "fsl,t1040-scfg", },
> +	{ .compatible = "fsl,ls1012a-scfg", },
> +	{ .compatible = "fsl,ls1046a-scfg", },
> +	{}
> +};
> +
> +/* SDHC IO VSEL control register definition */
> +#define SCFG_SDHCIOVSELCR	0x408
> +#define SDHCIOVSELCR_TGLEN	0x80000000
> +#define SDHCIOVSELCR_VSELVAL	0x60000000
> +#define SDHCIOVSELCR_SDHC_VS	0x00000001
> +
> +static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
> +				       struct mmc_ios *ios)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	struct device_node *scfg_node;
> +	void __iomem *scfg_base = NULL;
> +	u32 sdhciovselcr;
> +	u32 val;
> +
> +	/*
> +	 * Signal Voltage Switching is only applicable for Host Controllers
> +	 * v3.00 and above.
> +	 */
> +	if (host->version < SDHCI_SPEC_300)
> +		return 0;
> +
> +	val = sdhci_readl(host, ESDHC_PROCTL);
> +
> +	switch (ios->signal_voltage) {
> +	case MMC_SIGNAL_VOLTAGE_330:
> +		val &= ~ESDHC_VOLT_SEL;
> +		sdhci_writel(host, val, ESDHC_PROCTL);
> +		return 0;
> +	case MMC_SIGNAL_VOLTAGE_180:
> +		scfg_node = of_find_matching_node(NULL, scfg_device_ids);
> +		if (scfg_node)
> +			scfg_base = of_iomap(scfg_node, 0);
> +		if (scfg_base) {
> +			sdhciovselcr = SDHCIOVSELCR_TGLEN |
> +				       SDHCIOVSELCR_VSELVAL;
> +			iowrite32be(sdhciovselcr,
> +				scfg_base + SCFG_SDHCIOVSELCR);

In other places there is support for little endian also, so why not here?

> +
> +			val |= ESDHC_VOLT_SEL;
> +			sdhci_writel(host, val, ESDHC_PROCTL);
> +			mdelay(5);
> +
> +			sdhciovselcr = SDHCIOVSELCR_TGLEN |
> +				       SDHCIOVSELCR_SDHC_VS;
> +			iowrite32be(sdhciovselcr,
> +				scfg_base + SCFG_SDHCIOVSELCR);
> +			iounmap(scfg_base);
> +		} else {
> +			val |= ESDHC_VOLT_SEL;
> +			sdhci_writel(host, val, ESDHC_PROCTL);
> +		}
> +		return 0;
> +	default:
> +		return 0;
> +	}
> +}
> +
>  #ifdef CONFIG_PM_SLEEP
>  static u32 esdhc_proctl;
>  static int esdhc_of_suspend(struct device *dev)
> @@ -714,6 +785,9 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
>  	if (IS_ERR(host))
>  		return PTR_ERR(host);
>  
> +	host->mmc_host_ops.start_signal_voltage_switch =
> +		esdhc_signal_voltage_switch;
> +
>  	esdhc_init(pdev, host);
>  
>  	sdhci_get_of_property(pdev);
> 

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

* Re: [v3, 3/7] mmc: sdhci-of-esdhc: add tuning support
  2017-03-27  7:49   ` Yangbo Lu
@ 2017-04-10 12:38       ` Adrian Hunter
  -1 siblings, 0 replies; 37+ messages in thread
From: Adrian Hunter @ 2017-04-10 12:38 UTC (permalink / raw)
  To: Yangbo Lu, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Rob Herring, Mark Rutland,
	Catalin Marinas, Will Deacon
  Cc: Xiaobo Xie

On 27/03/17 10:49, Yangbo Lu wrote:
> eSDHC uses tuning block for tuning procedure. So the tuning
> block control register must be configured properly before tuning.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>

Acked-by: Adrian Hunter <adrian.hunter-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

> ---
> Changes for v2:
> 	- Replaced old function for mmc_host_ops.execute_tuning with
> 	  esdhc_execute_tuning to support eSDHC tuning.
> Changes for v3:
> 	- Put .execute_tuning assigning after after IS_ERR(host) check.
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
>  drivers/mmc/host/sdhci-of-esdhc.c | 20 ++++++++++++++++++++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 6869567..c4bbd74 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -53,9 +53,14 @@
>  #define ESDHC_CLOCK_HCKEN		0x00000002
>  #define ESDHC_CLOCK_IPGEN		0x00000001
>  
> +/* Tuning Block Control Register */
> +#define ESDHC_TBCTL			0x120
> +#define ESDHC_TB_EN			0x00000004
> +
>  /* Control Register for DMA transfer */
>  #define ESDHC_DMA_SYSCTL		0x40c
>  #define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
> +#define ESDHC_FLUSH_ASYNC_FIFO		0x00040000
>  #define ESDHC_DMA_SNOOP			0x00000040
>  
>  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index a70499a..8c8e147 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -630,6 +630,25 @@ static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
>  	}
>  }
>  
> +static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	u32 val;
> +
> +	/* Use tuning block for tuning procedure */
> +	esdhc_clock_enable(host, false);
> +	val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> +	val |= ESDHC_FLUSH_ASYNC_FIFO;
> +	sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> +
> +	val = sdhci_readl(host, ESDHC_TBCTL);
> +	val |= ESDHC_TB_EN;
> +	sdhci_writel(host, val, ESDHC_TBCTL);
> +	esdhc_clock_enable(host, true);
> +
> +	return sdhci_execute_tuning(mmc, opcode);
> +}
> +
>  #ifdef CONFIG_PM_SLEEP
>  static u32 esdhc_proctl;
>  static int esdhc_of_suspend(struct device *dev)
> @@ -787,6 +806,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
>  
>  	host->mmc_host_ops.start_signal_voltage_switch =
>  		esdhc_signal_voltage_switch;
> +	host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
>  
>  	esdhc_init(pdev, host);
>  
> 

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [v3, 3/7] mmc: sdhci-of-esdhc: add tuning support
@ 2017-04-10 12:38       ` Adrian Hunter
  0 siblings, 0 replies; 37+ messages in thread
From: Adrian Hunter @ 2017-04-10 12:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 27/03/17 10:49, Yangbo Lu wrote:
> eSDHC uses tuning block for tuning procedure. So the tuning
> block control register must be configured properly before tuning.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

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

> ---
> Changes for v2:
> 	- Replaced old function for mmc_host_ops.execute_tuning with
> 	  esdhc_execute_tuning to support eSDHC tuning.
> Changes for v3:
> 	- Put .execute_tuning assigning after after IS_ERR(host) check.
> ---
>  drivers/mmc/host/sdhci-esdhc.h    |  5 +++++
>  drivers/mmc/host/sdhci-of-esdhc.c | 20 ++++++++++++++++++++
>  2 files changed, 25 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
> index 6869567..c4bbd74 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -53,9 +53,14 @@
>  #define ESDHC_CLOCK_HCKEN		0x00000002
>  #define ESDHC_CLOCK_IPGEN		0x00000001
>  
> +/* Tuning Block Control Register */
> +#define ESDHC_TBCTL			0x120
> +#define ESDHC_TB_EN			0x00000004
> +
>  /* Control Register for DMA transfer */
>  #define ESDHC_DMA_SYSCTL		0x40c
>  #define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
> +#define ESDHC_FLUSH_ASYNC_FIFO		0x00040000
>  #define ESDHC_DMA_SNOOP			0x00000040
>  
>  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index a70499a..8c8e147 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -630,6 +630,25 @@ static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
>  	}
>  }
>  
> +static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	u32 val;
> +
> +	/* Use tuning block for tuning procedure */
> +	esdhc_clock_enable(host, false);
> +	val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> +	val |= ESDHC_FLUSH_ASYNC_FIFO;
> +	sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> +
> +	val = sdhci_readl(host, ESDHC_TBCTL);
> +	val |= ESDHC_TB_EN;
> +	sdhci_writel(host, val, ESDHC_TBCTL);
> +	esdhc_clock_enable(host, true);
> +
> +	return sdhci_execute_tuning(mmc, opcode);
> +}
> +
>  #ifdef CONFIG_PM_SLEEP
>  static u32 esdhc_proctl;
>  static int esdhc_of_suspend(struct device *dev)
> @@ -787,6 +806,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
>  
>  	host->mmc_host_ops.start_signal_voltage_switch =
>  		esdhc_signal_voltage_switch;
> +	host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
>  
>  	esdhc_init(pdev, host);
>  
> 

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

* Re: [v3, 5/7] mmc: sdhci-of-esdhc: add delay between tuning cycles
  2017-03-27  7:49   ` Yangbo Lu
@ 2017-04-10 12:39     ` Adrian Hunter
  -1 siblings, 0 replies; 37+ messages in thread
From: Adrian Hunter @ 2017-04-10 12:39 UTC (permalink / raw)
  To: Yangbo Lu, linux-mmc, devicetree, linux-arm-kernel, ulf.hansson,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon
  Cc: Xiaobo Xie

On 27/03/17 10:49, Yangbo Lu wrote:
> It's observed that eSDHC needed delay between tuning cycles for
> HS200 successful tuning. This patch is to set 1ms delay for that.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

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

> ---
> Changes for v2:
> 	- None
> Changes for v3:
> 	- Used a host member for tuning delay instead of a quirk.
> ---
>  drivers/mmc/host/sdhci-of-esdhc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 8c8e147..0754ef4 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -807,6 +807,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
>  	host->mmc_host_ops.start_signal_voltage_switch =
>  		esdhc_signal_voltage_switch;
>  	host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
> +	host->tuning_delay = 1;
>  
>  	esdhc_init(pdev, host);
>  
> 


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

* [v3, 5/7] mmc: sdhci-of-esdhc: add delay between tuning cycles
@ 2017-04-10 12:39     ` Adrian Hunter
  0 siblings, 0 replies; 37+ messages in thread
From: Adrian Hunter @ 2017-04-10 12:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 27/03/17 10:49, Yangbo Lu wrote:
> It's observed that eSDHC needed delay between tuning cycles for
> HS200 successful tuning. This patch is to set 1ms delay for that.
> 
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>

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

> ---
> Changes for v2:
> 	- None
> Changes for v3:
> 	- Used a host member for tuning delay instead of a quirk.
> ---
>  drivers/mmc/host/sdhci-of-esdhc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
> index 8c8e147..0754ef4 100644
> --- a/drivers/mmc/host/sdhci-of-esdhc.c
> +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> @@ -807,6 +807,7 @@ static int sdhci_esdhc_probe(struct platform_device *pdev)
>  	host->mmc_host_ops.start_signal_voltage_switch =
>  		esdhc_signal_voltage_switch;
>  	host->mmc_host_ops.execute_tuning = esdhc_execute_tuning;
> +	host->tuning_delay = 1;
>  
>  	esdhc_init(pdev, host);
>  
> 

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

* RE: [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
  2017-04-10 12:36     ` Adrian Hunter
@ 2017-04-11  5:14       ` Y.B. Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-11  5:14 UTC (permalink / raw)
  To: Adrian Hunter, linux-mmc, devicetree, linux-arm-kernel,
	ulf.hansson, Rob Herring, Mark Rutland, Catalin Marinas,
	Will Deacon
  Cc: Xiaobo Xie

Hi Adrian,


> -----Original Message-----
> From: Adrian Hunter [mailto:adrian.hunter@intel.com]
> Sent: Monday, April 10, 2017 8:36 PM
> To: Y.B. Lu; linux-mmc@vger.kernel.org; devicetree@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; ulf.hansson@linaro.org; Rob Herring;
> Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie
> Subject: Re: [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
> 
> On 27/03/17 10:49, Yangbo Lu wrote:
> > eSDHC could select peripheral clock or platform clock as clock source
> > by the PCS bit of eSDHC Control Register, and this bit couldn't be
> > reset by software reset for all. In default, the platform clock is
> > used. But we have to use peripheral clock since it has a higher
> > frequency to support eMMC
> > HS200 mode and SD UHS-I mode. This patch is to add peripheral clock
> > support and use it instead of platform clock if it's declared in eSDHC
> dts node.
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> 
> Apart from minor comments:
> 
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> 
> > ---
> > Changes for v2:
> > 	- None
> > Changes for v3:
> > 	- None
> > ---
> >  drivers/mmc/host/sdhci-esdhc.h    |  1 +
> >  drivers/mmc/host/sdhci-of-esdhc.c | 70
> > +++++++++++++++++++++++++++++++++++++--
> >  2 files changed, 69 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc.h
> > b/drivers/mmc/host/sdhci-esdhc.h index ece8b37..5343fc0 100644
> > --- a/drivers/mmc/host/sdhci-esdhc.h
> > +++ b/drivers/mmc/host/sdhci-esdhc.h
> > @@ -54,6 +54,7 @@
> >
> >  /* Control Register for DMA transfer */
> >  #define ESDHC_DMA_SYSCTL		0x40c
> > +#define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
> >  #define ESDHC_DMA_SNOOP			0x00000040
> >
> >  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */ diff --git
> > a/drivers/mmc/host/sdhci-of-esdhc.c
> > b/drivers/mmc/host/sdhci-of-esdhc.c
> > index ff37e74..7ce1caf 100644
> > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/delay.h>
> >  #include <linux/module.h>
> >  #include <linux/sys_soc.h>
> > +#include <linux/clk.h>
> >  #include <linux/mmc/host.h>
> >  #include "sdhci-pltfm.h"
> >  #include "sdhci-esdhc.h"
> > @@ -30,6 +31,7 @@ struct sdhci_esdhc {
> >  	u8 vendor_ver;
> >  	u8 spec_ver;
> >  	bool quirk_incorrect_hostver;
> > +	unsigned int peripheral_clock;
> >  };
> >
> >  /**
> > @@ -414,15 +416,25 @@ static int esdhc_of_enable_dma(struct sdhci_host
> > *host)  static unsigned int esdhc_of_get_max_clock(struct sdhci_host
> > *host)  {
> >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> >
> > -	return pltfm_host->clock;
> > +	if (esdhc->peripheral_clock)
> > +		return esdhc->peripheral_clock;
> > +	else
> > +		return pltfm_host->clock;
> >  }
> >
> >  static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
> > {
> >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> > +	unsigned int clock;
> >
> > -	return pltfm_host->clock / 256 / 16;
> > +	if (esdhc->peripheral_clock)
> > +		clock = esdhc->peripheral_clock;
> > +	else
> > +		clock = pltfm_host->clock;
> > +	return clock / 256 / 16;
> >  }
> >
> >  static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int
> > clock) @@ -512,6 +524,33 @@ static void
> esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
> >  	sdhci_writel(host, ctrl, ESDHC_PROCTL);  }
> >
> > +static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
> > +{
> > +	u32 val;
> > +	u32 timeout;
> > +
> > +	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> > +
> > +	if (enable)
> > +		val |= ESDHC_CLOCK_SDCLKEN;
> > +	else
> > +		val &= ~ESDHC_CLOCK_SDCLKEN;
> > +
> > +	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
> > +
> > +	timeout = 20;
> > +	val = ESDHC_CLOCK_STABLE;
> > +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
> > +		if (timeout == 0) {
> > +			pr_err("%s: Internal clock never stabilised.\n",
> > +				mmc_hostname(host->mmc));
> > +			break;
> > +		}
> > +		timeout--;
> > +		mdelay(1);
> 
> If the time to stabilize is much less that 1 ms then this loop can waste
> time.  Have a look at the change in sdhci.c.
> 

[Lu Yangbo-B47093] Thanks a lot. The method in sdhci.c is really better.
I will send next version to use it soon.

Currently another place in esdhc driver could also change to use this method. I will send a separate patch for that later.


> > +	}
> > +}
> > +
> >  static void esdhc_reset(struct sdhci_host *host, u8 mask)  {
> >  	sdhci_reset(host, mask);
> > @@ -613,6 +652,9 @@ static void esdhc_init(struct platform_device
> > *pdev, struct sdhci_host *host)  {
> >  	struct sdhci_pltfm_host *pltfm_host;
> >  	struct sdhci_esdhc *esdhc;
> > +	struct device_node *np;
> > +	struct clk *clk;
> > +	u32 val;
> >  	u16 host_ver;
> >
> >  	pltfm_host = sdhci_priv(host);
> > @@ -626,6 +668,30 @@ static void esdhc_init(struct platform_device
> *pdev, struct sdhci_host *host)
> >  		esdhc->quirk_incorrect_hostver = true;
> >  	else
> >  		esdhc->quirk_incorrect_hostver = false;
> > +
> > +	np = pdev->dev.of_node;
> > +	clk = of_clk_get(np, 0);
> 
> Should there be a clk_put somewhere?

[Lu Yangbo-B47093] Will add it after driver gets the clock value.

> 
> > +	if (!IS_ERR(clk)) {
> > +		/*
> > +		 * esdhc->peripheral_clock would be assigned with a value
> > +		 * which is eSDHC base clock when use periperal clock.
> > +		 * For ls1046a, the clock value got by common clk API is
> > +		 * peripheral clock while the eSDHC base clock is 1/2
> > +		 * peripheral clock.
> > +		 */
> > +		if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
> > +			esdhc->peripheral_clock = clk_get_rate(clk) / 2;
> > +		else
> > +			esdhc->peripheral_clock = clk_get_rate(clk);
> > +	}
> > +
> > +	if (esdhc->peripheral_clock) {
> > +		esdhc_clock_enable(host, false);
> > +		val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> > +		val |= ESDHC_PERIPHERAL_CLK_SEL;
> > +		sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> > +		esdhc_clock_enable(host, true);
> > +	}
> >  }
> >
> >  static int sdhci_esdhc_probe(struct platform_device *pdev)
> >


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

* [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
@ 2017-04-11  5:14       ` Y.B. Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-11  5:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Adrian,


> -----Original Message-----
> From: Adrian Hunter [mailto:adrian.hunter at intel.com]
> Sent: Monday, April 10, 2017 8:36 PM
> To: Y.B. Lu; linux-mmc at vger.kernel.org; devicetree at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; ulf.hansson at linaro.org; Rob Herring;
> Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie
> Subject: Re: [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
> 
> On 27/03/17 10:49, Yangbo Lu wrote:
> > eSDHC could select peripheral clock or platform clock as clock source
> > by the PCS bit of eSDHC Control Register, and this bit couldn't be
> > reset by software reset for all. In default, the platform clock is
> > used. But we have to use peripheral clock since it has a higher
> > frequency to support eMMC
> > HS200 mode and SD UHS-I mode. This patch is to add peripheral clock
> > support and use it instead of platform clock if it's declared in eSDHC
> dts node.
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> 
> Apart from minor comments:
> 
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> 
> > ---
> > Changes for v2:
> > 	- None
> > Changes for v3:
> > 	- None
> > ---
> >  drivers/mmc/host/sdhci-esdhc.h    |  1 +
> >  drivers/mmc/host/sdhci-of-esdhc.c | 70
> > +++++++++++++++++++++++++++++++++++++--
> >  2 files changed, 69 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc.h
> > b/drivers/mmc/host/sdhci-esdhc.h index ece8b37..5343fc0 100644
> > --- a/drivers/mmc/host/sdhci-esdhc.h
> > +++ b/drivers/mmc/host/sdhci-esdhc.h
> > @@ -54,6 +54,7 @@
> >
> >  /* Control Register for DMA transfer */
> >  #define ESDHC_DMA_SYSCTL		0x40c
> > +#define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
> >  #define ESDHC_DMA_SNOOP			0x00000040
> >
> >  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */ diff --git
> > a/drivers/mmc/host/sdhci-of-esdhc.c
> > b/drivers/mmc/host/sdhci-of-esdhc.c
> > index ff37e74..7ce1caf 100644
> > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > @@ -19,6 +19,7 @@
> >  #include <linux/delay.h>
> >  #include <linux/module.h>
> >  #include <linux/sys_soc.h>
> > +#include <linux/clk.h>
> >  #include <linux/mmc/host.h>
> >  #include "sdhci-pltfm.h"
> >  #include "sdhci-esdhc.h"
> > @@ -30,6 +31,7 @@ struct sdhci_esdhc {
> >  	u8 vendor_ver;
> >  	u8 spec_ver;
> >  	bool quirk_incorrect_hostver;
> > +	unsigned int peripheral_clock;
> >  };
> >
> >  /**
> > @@ -414,15 +416,25 @@ static int esdhc_of_enable_dma(struct sdhci_host
> > *host)  static unsigned int esdhc_of_get_max_clock(struct sdhci_host
> > *host)  {
> >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> >
> > -	return pltfm_host->clock;
> > +	if (esdhc->peripheral_clock)
> > +		return esdhc->peripheral_clock;
> > +	else
> > +		return pltfm_host->clock;
> >  }
> >
> >  static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
> > {
> >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> > +	unsigned int clock;
> >
> > -	return pltfm_host->clock / 256 / 16;
> > +	if (esdhc->peripheral_clock)
> > +		clock = esdhc->peripheral_clock;
> > +	else
> > +		clock = pltfm_host->clock;
> > +	return clock / 256 / 16;
> >  }
> >
> >  static void esdhc_of_set_clock(struct sdhci_host *host, unsigned int
> > clock) @@ -512,6 +524,33 @@ static void
> esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
> >  	sdhci_writel(host, ctrl, ESDHC_PROCTL);  }
> >
> > +static void esdhc_clock_enable(struct sdhci_host *host, bool enable)
> > +{
> > +	u32 val;
> > +	u32 timeout;
> > +
> > +	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> > +
> > +	if (enable)
> > +		val |= ESDHC_CLOCK_SDCLKEN;
> > +	else
> > +		val &= ~ESDHC_CLOCK_SDCLKEN;
> > +
> > +	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
> > +
> > +	timeout = 20;
> > +	val = ESDHC_CLOCK_STABLE;
> > +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
> > +		if (timeout == 0) {
> > +			pr_err("%s: Internal clock never stabilised.\n",
> > +				mmc_hostname(host->mmc));
> > +			break;
> > +		}
> > +		timeout--;
> > +		mdelay(1);
> 
> If the time to stabilize is much less that 1 ms then this loop can waste
> time.  Have a look at the change in sdhci.c.
> 

[Lu Yangbo-B47093] Thanks a lot. The method in sdhci.c is really better.
I will send next version to use it soon.

Currently another place in esdhc driver could also change to use this method. I will send a separate patch for that later.


> > +	}
> > +}
> > +
> >  static void esdhc_reset(struct sdhci_host *host, u8 mask)  {
> >  	sdhci_reset(host, mask);
> > @@ -613,6 +652,9 @@ static void esdhc_init(struct platform_device
> > *pdev, struct sdhci_host *host)  {
> >  	struct sdhci_pltfm_host *pltfm_host;
> >  	struct sdhci_esdhc *esdhc;
> > +	struct device_node *np;
> > +	struct clk *clk;
> > +	u32 val;
> >  	u16 host_ver;
> >
> >  	pltfm_host = sdhci_priv(host);
> > @@ -626,6 +668,30 @@ static void esdhc_init(struct platform_device
> *pdev, struct sdhci_host *host)
> >  		esdhc->quirk_incorrect_hostver = true;
> >  	else
> >  		esdhc->quirk_incorrect_hostver = false;
> > +
> > +	np = pdev->dev.of_node;
> > +	clk = of_clk_get(np, 0);
> 
> Should there be a clk_put somewhere?

[Lu Yangbo-B47093] Will add it after driver gets the clock value.

> 
> > +	if (!IS_ERR(clk)) {
> > +		/*
> > +		 * esdhc->peripheral_clock would be assigned with a value
> > +		 * which is eSDHC base clock when use periperal clock.
> > +		 * For ls1046a, the clock value got by common clk API is
> > +		 * peripheral clock while the eSDHC base clock is 1/2
> > +		 * peripheral clock.
> > +		 */
> > +		if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
> > +			esdhc->peripheral_clock = clk_get_rate(clk) / 2;
> > +		else
> > +			esdhc->peripheral_clock = clk_get_rate(clk);
> > +	}
> > +
> > +	if (esdhc->peripheral_clock) {
> > +		esdhc_clock_enable(host, false);
> > +		val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> > +		val |= ESDHC_PERIPHERAL_CLK_SEL;
> > +		sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> > +		esdhc_clock_enable(host, true);
> > +	}
> >  }
> >
> >  static int sdhci_esdhc_probe(struct platform_device *pdev)
> >

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

* RE: [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal voltage switch
  2017-04-10 12:37     ` Adrian Hunter
@ 2017-04-11  5:20         ` Y.B. Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-11  5:20 UTC (permalink / raw)
  To: Adrian Hunter, linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	ulf.hansson-QSEj5FYQhm4dnm+yROfE0A, Rob Herring, Mark Rutland,
	Catalin Marinas, Will Deacon
  Cc: Xiaobo Xie

Hi Adrian,


> -----Original Message-----
> From: linux-mmc-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org [mailto:linux-mmc-
> owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org] On Behalf Of Adrian Hunter
> Sent: Monday, April 10, 2017 8:38 PM
> To: Y.B. Lu; linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org; ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org; Rob Herring;
> Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie
> Subject: Re: [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal
> voltage switch
> 
> On 27/03/17 10:49, Yangbo Lu wrote:
> > eSDHC supports signal voltage switch from 3.3v to 1.8v by
> > eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
> > signal SDHC_VS, and there must be a control circuit out of eSDHC to
> > change the signal voltage according to SDHC_VS output signal.
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu-3arQi8VN3Tc@public.gmane.org>
> 
> Apart from minor comment below:
> 
> Acked-by: Adrian Hunter <adrian.hunter-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> 
> > ---
> > Changes for v2:
> > 	- Used Adrain's method to support voltage switching:
> >           host->mmc_host_ops.start_signal_voltage_switch =
> >                      esdhc_signal_voltage_switch; Changes for v3:
> > 	- Put .start_signal_voltage_switch assigning after IS_ERR(host)
> check.
> > ---
> >  drivers/mmc/host/sdhci-esdhc.h    |  1 +
> >  drivers/mmc/host/sdhci-of-esdhc.c | 74
> > +++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 75 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc.h
> > b/drivers/mmc/host/sdhci-esdhc.h index 5343fc0..6869567 100644
> > --- a/drivers/mmc/host/sdhci-esdhc.h
> > +++ b/drivers/mmc/host/sdhci-esdhc.h
> > @@ -37,6 +37,7 @@
> >
> >  /* Protocol Control Register */
> >  #define ESDHC_PROCTL			0x28
> > +#define ESDHC_VOLT_SEL			0x00000400
> >  #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
> >  #define ESDHC_CTRL_8BITBUS		(0x2 << 1)
> >  #define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
> > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
> > b/drivers/mmc/host/sdhci-of-esdhc.c
> > index 7ce1caf..a70499a 100644
> > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/err.h>
> >  #include <linux/io.h>
> >  #include <linux/of.h>
> > +#include <linux/of_address.h>
> >  #include <linux/delay.h>
> >  #include <linux/module.h>
> >  #include <linux/sys_soc.h>
> > @@ -559,6 +560,76 @@ static void esdhc_reset(struct sdhci_host *host,
> u8 mask)
> >  	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);  }
> >
> > +/* The SCFG, Supplemental Configuration Unit, provides SoC specific
> > + * configuration and status registers for the device. There is a
> > + * SDHC IO VSEL control register on SCFG for some platforms. It's
> > + * used to support SDHC IO voltage switching.
> > + */
> > +static const struct of_device_id scfg_device_ids[] = {
> > +	{ .compatible = "fsl,t1040-scfg", },
> > +	{ .compatible = "fsl,ls1012a-scfg", },
> > +	{ .compatible = "fsl,ls1046a-scfg", },
> > +	{}
> > +};
> > +
> > +/* SDHC IO VSEL control register definition */
> > +#define SCFG_SDHCIOVSELCR	0x408
> > +#define SDHCIOVSELCR_TGLEN	0x80000000
> > +#define SDHCIOVSELCR_VSELVAL	0x60000000
> > +#define SDHCIOVSELCR_SDHC_VS	0x00000001
> > +
> > +static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
> > +				       struct mmc_ios *ios)
> > +{
> > +	struct sdhci_host *host = mmc_priv(mmc);
> > +	struct device_node *scfg_node;
> > +	void __iomem *scfg_base = NULL;
> > +	u32 sdhciovselcr;
> > +	u32 val;
> > +
> > +	/*
> > +	 * Signal Voltage Switching is only applicable for Host Controllers
> > +	 * v3.00 and above.
> > +	 */
> > +	if (host->version < SDHCI_SPEC_300)
> > +		return 0;
> > +
> > +	val = sdhci_readl(host, ESDHC_PROCTL);
> > +
> > +	switch (ios->signal_voltage) {
> > +	case MMC_SIGNAL_VOLTAGE_330:
> > +		val &= ~ESDHC_VOLT_SEL;
> > +		sdhci_writel(host, val, ESDHC_PROCTL);
> > +		return 0;
> > +	case MMC_SIGNAL_VOLTAGE_180:
> > +		scfg_node = of_find_matching_node(NULL, scfg_device_ids);
> > +		if (scfg_node)
> > +			scfg_base = of_iomap(scfg_node, 0);
> > +		if (scfg_base) {
> > +			sdhciovselcr = SDHCIOVSELCR_TGLEN |
> > +				       SDHCIOVSELCR_VSELVAL;
> > +			iowrite32be(sdhciovselcr,
> > +				scfg_base + SCFG_SDHCIOVSELCR);
> 
> In other places there is support for little endian also, so why not here?

[Lu Yangbo-B47093] The SCFG unit is always a big-endian module on both ARM and PPC QorIQ platforms.
There is little possibility to have little-endian in future.

> 
> > +
> > +			val |= ESDHC_VOLT_SEL;
> > +			sdhci_writel(host, val, ESDHC_PROCTL);
> > +			mdelay(5);
> > +
> > +			sdhciovselcr = SDHCIOVSELCR_TGLEN |
> > +				       SDHCIOVSELCR_SDHC_VS;
> > +			iowrite32be(sdhciovselcr,
> > +				scfg_base + SCFG_SDHCIOVSELCR);
> > +			iounmap(scfg_base);
> > +		} else {
> > +			val |= ESDHC_VOLT_SEL;
> > +			sdhci_writel(host, val, ESDHC_PROCTL);
> > +		}
> > +		return 0;
> > +	default:
> > +		return 0;
> > +	}
> > +}
> > +
> >  #ifdef CONFIG_PM_SLEEP
> >  static u32 esdhc_proctl;
> >  static int esdhc_of_suspend(struct device *dev) @@ -714,6 +785,9 @@
> > static int sdhci_esdhc_probe(struct platform_device *pdev)
> >  	if (IS_ERR(host))
> >  		return PTR_ERR(host);
> >
> > +	host->mmc_host_ops.start_signal_voltage_switch =
> > +		esdhc_signal_voltage_switch;
> > +
> >  	esdhc_init(pdev, host);
> >
> >  	sdhci_get_of_property(pdev);
> >
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal voltage switch
@ 2017-04-11  5:20         ` Y.B. Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-11  5:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Adrian,


> -----Original Message-----
> From: linux-mmc-owner at vger.kernel.org [mailto:linux-mmc-
> owner at vger.kernel.org] On Behalf Of Adrian Hunter
> Sent: Monday, April 10, 2017 8:38 PM
> To: Y.B. Lu; linux-mmc at vger.kernel.org; devicetree at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; ulf.hansson at linaro.org; Rob Herring;
> Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie
> Subject: Re: [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal
> voltage switch
> 
> On 27/03/17 10:49, Yangbo Lu wrote:
> > eSDHC supports signal voltage switch from 3.3v to 1.8v by
> > eSDHC_PROCTL[VOLT_SEL] bit. This bit changes the value of output
> > signal SDHC_VS, and there must be a control circuit out of eSDHC to
> > change the signal voltage according to SDHC_VS output signal.
> >
> > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> 
> Apart from minor comment below:
> 
> Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> 
> > ---
> > Changes for v2:
> > 	- Used Adrain's method to support voltage switching:
> >           host->mmc_host_ops.start_signal_voltage_switch =
> >                      esdhc_signal_voltage_switch; Changes for v3:
> > 	- Put .start_signal_voltage_switch assigning after IS_ERR(host)
> check.
> > ---
> >  drivers/mmc/host/sdhci-esdhc.h    |  1 +
> >  drivers/mmc/host/sdhci-of-esdhc.c | 74
> > +++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 75 insertions(+)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc.h
> > b/drivers/mmc/host/sdhci-esdhc.h index 5343fc0..6869567 100644
> > --- a/drivers/mmc/host/sdhci-esdhc.h
> > +++ b/drivers/mmc/host/sdhci-esdhc.h
> > @@ -37,6 +37,7 @@
> >
> >  /* Protocol Control Register */
> >  #define ESDHC_PROCTL			0x28
> > +#define ESDHC_VOLT_SEL			0x00000400
> >  #define ESDHC_CTRL_4BITBUS		(0x1 << 1)
> >  #define ESDHC_CTRL_8BITBUS		(0x2 << 1)
> >  #define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)
> > diff --git a/drivers/mmc/host/sdhci-of-esdhc.c
> > b/drivers/mmc/host/sdhci-of-esdhc.c
> > index 7ce1caf..a70499a 100644
> > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > @@ -16,6 +16,7 @@
> >  #include <linux/err.h>
> >  #include <linux/io.h>
> >  #include <linux/of.h>
> > +#include <linux/of_address.h>
> >  #include <linux/delay.h>
> >  #include <linux/module.h>
> >  #include <linux/sys_soc.h>
> > @@ -559,6 +560,76 @@ static void esdhc_reset(struct sdhci_host *host,
> u8 mask)
> >  	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);  }
> >
> > +/* The SCFG, Supplemental Configuration Unit, provides SoC specific
> > + * configuration and status registers for the device. There is a
> > + * SDHC IO VSEL control register on SCFG for some platforms. It's
> > + * used to support SDHC IO voltage switching.
> > + */
> > +static const struct of_device_id scfg_device_ids[] = {
> > +	{ .compatible = "fsl,t1040-scfg", },
> > +	{ .compatible = "fsl,ls1012a-scfg", },
> > +	{ .compatible = "fsl,ls1046a-scfg", },
> > +	{}
> > +};
> > +
> > +/* SDHC IO VSEL control register definition */
> > +#define SCFG_SDHCIOVSELCR	0x408
> > +#define SDHCIOVSELCR_TGLEN	0x80000000
> > +#define SDHCIOVSELCR_VSELVAL	0x60000000
> > +#define SDHCIOVSELCR_SDHC_VS	0x00000001
> > +
> > +static int esdhc_signal_voltage_switch(struct mmc_host *mmc,
> > +				       struct mmc_ios *ios)
> > +{
> > +	struct sdhci_host *host = mmc_priv(mmc);
> > +	struct device_node *scfg_node;
> > +	void __iomem *scfg_base = NULL;
> > +	u32 sdhciovselcr;
> > +	u32 val;
> > +
> > +	/*
> > +	 * Signal Voltage Switching is only applicable for Host Controllers
> > +	 * v3.00 and above.
> > +	 */
> > +	if (host->version < SDHCI_SPEC_300)
> > +		return 0;
> > +
> > +	val = sdhci_readl(host, ESDHC_PROCTL);
> > +
> > +	switch (ios->signal_voltage) {
> > +	case MMC_SIGNAL_VOLTAGE_330:
> > +		val &= ~ESDHC_VOLT_SEL;
> > +		sdhci_writel(host, val, ESDHC_PROCTL);
> > +		return 0;
> > +	case MMC_SIGNAL_VOLTAGE_180:
> > +		scfg_node = of_find_matching_node(NULL, scfg_device_ids);
> > +		if (scfg_node)
> > +			scfg_base = of_iomap(scfg_node, 0);
> > +		if (scfg_base) {
> > +			sdhciovselcr = SDHCIOVSELCR_TGLEN |
> > +				       SDHCIOVSELCR_VSELVAL;
> > +			iowrite32be(sdhciovselcr,
> > +				scfg_base + SCFG_SDHCIOVSELCR);
> 
> In other places there is support for little endian also, so why not here?

[Lu Yangbo-B47093] The SCFG unit is always a big-endian module on both ARM and PPC QorIQ platforms.
There is little possibility to have little-endian in future.

> 
> > +
> > +			val |= ESDHC_VOLT_SEL;
> > +			sdhci_writel(host, val, ESDHC_PROCTL);
> > +			mdelay(5);
> > +
> > +			sdhciovselcr = SDHCIOVSELCR_TGLEN |
> > +				       SDHCIOVSELCR_SDHC_VS;
> > +			iowrite32be(sdhciovselcr,
> > +				scfg_base + SCFG_SDHCIOVSELCR);
> > +			iounmap(scfg_base);
> > +		} else {
> > +			val |= ESDHC_VOLT_SEL;
> > +			sdhci_writel(host, val, ESDHC_PROCTL);
> > +		}
> > +		return 0;
> > +	default:
> > +		return 0;
> > +	}
> > +}
> > +
> >  #ifdef CONFIG_PM_SLEEP
> >  static u32 esdhc_proctl;
> >  static int esdhc_of_suspend(struct device *dev) @@ -714,6 +785,9 @@
> > static int sdhci_esdhc_probe(struct platform_device *pdev)
> >  	if (IS_ERR(host))
> >  		return PTR_ERR(host);
> >
> > +	host->mmc_host_ops.start_signal_voltage_switch =
> > +		esdhc_signal_voltage_switch;
> > +
> >  	esdhc_init(pdev, host);
> >
> >  	sdhci_get_of_property(pdev);
> >
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo at vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

* RE: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
  2017-04-10 10:48     ` Ulf Hansson
@ 2017-04-11  5:24       ` Y.B. Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-11  5:24 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc, devicetree, linux-arm-kernel, Adrian Hunter,
	Rob Herring, Mark Rutland, Catalin Marinas, Will Deacon,
	Xiaobo Xie

Hi Uffe and Adrian,

Thanks for your quick response.
I dropped the dts patches and would send the new version mmc patchset which addressed Adrian's comments.
The dts patches would be sent separately to arm soc and will not have new bindings/compatibles to discuss.

Thanks.


Best regards,
Yangbo Lu

> -----Original Message-----
> From: Ulf Hansson [mailto:ulf.hansson@linaro.org]
> Sent: Monday, April 10, 2017 6:49 PM
> To: Y.B. Lu
> Cc: linux-mmc@vger.kernel.org; devicetree@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; Adrian Hunter; Rob Herring; Mark Rutland;
> Catalin Marinas; Will Deacon; Xiaobo Xie
> Subject: Re: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
> 
> On 10 April 2017 at 10:20, Y.B. Lu <yangbo.lu@nxp.com> wrote:
> > Hi Andrian and Uffe,
> >
> > Do you have any comments on MMC patches?
> > Could you help to merge the mmc patches if there is no changes
> requested?
> 
> I am waiting for Adrian's acks.
> 
> >
> > Regarding to the dts patches, I have some more platforms to support.
> > So I'd like to drop them currently, and send them all to arm mailing
> list for reviewing.
> 
> If it's new bindings/compatibles, the DT doc changes needs to be
> discussed and agreed upon first. Actual changes to the DTS files, should
> preferably go via the arm soc tree.
> 
> Kind regards
> Uffe

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

* [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
@ 2017-04-11  5:24       ` Y.B. Lu
  0 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-11  5:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uffe and Adrian,

Thanks for your quick response.
I dropped the dts patches and would send the new version mmc patchset which addressed Adrian's comments.
The dts patches would be sent separately to arm soc and will not have new bindings/compatibles to discuss.

Thanks.


Best regards,
Yangbo Lu

> -----Original Message-----
> From: Ulf Hansson [mailto:ulf.hansson at linaro.org]
> Sent: Monday, April 10, 2017 6:49 PM
> To: Y.B. Lu
> Cc: linux-mmc at vger.kernel.org; devicetree at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; Adrian Hunter; Rob Herring; Mark Rutland;
> Catalin Marinas; Will Deacon; Xiaobo Xie
> Subject: Re: [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC
> 
> On 10 April 2017 at 10:20, Y.B. Lu <yangbo.lu@nxp.com> wrote:
> > Hi Andrian and Uffe,
> >
> > Do you have any comments on MMC patches?
> > Could you help to merge the mmc patches if there is no changes
> requested?
> 
> I am waiting for Adrian's acks.
> 
> >
> > Regarding to the dts patches, I have some more platforms to support.
> > So I'd like to drop them currently, and send them all to arm mailing
> list for reviewing.
> 
> If it's new bindings/compatibles, the DT doc changes needs to be
> discussed and agreed upon first. Actual changes to the DTS files, should
> preferably go via the arm soc tree.
> 
> Kind regards
> Uffe

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

* RE: [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
  2017-04-11  5:14       ` Y.B. Lu
  (?)
@ 2017-04-26  3:09       ` Y.B. Lu
  -1 siblings, 0 replies; 37+ messages in thread
From: Y.B. Lu @ 2017-04-26  3:09 UTC (permalink / raw)
  To: Adrian Hunter, linux-mmc, ulf.hansson; +Cc: Xiaobo Xie

Hi Adrian,


> -----Original Message-----
> From: linux-mmc-owner@vger.kernel.org [mailto:linux-mmc-
> owner@vger.kernel.org] On Behalf Of Y.B. Lu
> Sent: Tuesday, April 11, 2017 1:15 PM
> To: Adrian Hunter; linux-mmc@vger.kernel.org; devicetree@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; ulf.hansson@linaro.org; Rob Herring;
> Mark Rutland; Catalin Marinas; Will Deacon
> Cc: Xiaobo Xie
> Subject: RE: [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support
> 
> Hi Adrian,
> 
> 
> > -----Original Message-----
> > From: Adrian Hunter [mailto:adrian.hunter@intel.com]
> > Sent: Monday, April 10, 2017 8:36 PM
> > To: Y.B. Lu; linux-mmc@vger.kernel.org; devicetree@vger.kernel.org;
> > linux-arm-kernel@lists.infradead.org; ulf.hansson@linaro.org; Rob
> > Herring; Mark Rutland; Catalin Marinas; Will Deacon
> > Cc: Xiaobo Xie
> > Subject: Re: [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock
> > support
> >
> > On 27/03/17 10:49, Yangbo Lu wrote:
> > > eSDHC could select peripheral clock or platform clock as clock
> > > source by the PCS bit of eSDHC Control Register, and this bit
> > > couldn't be reset by software reset for all. In default, the
> > > platform clock is used. But we have to use peripheral clock since it
> > > has a higher frequency to support eMMC
> > > HS200 mode and SD UHS-I mode. This patch is to add peripheral clock
> > > support and use it instead of platform clock if it's declared in
> > > eSDHC
> > dts node.
> > >
> > > Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> >
> > Apart from minor comments:
> >
> > Acked-by: Adrian Hunter <adrian.hunter@intel.com>
> >
> > > ---
> > > Changes for v2:
> > > 	- None
> > > Changes for v3:
> > > 	- None
> > > ---
> > >  drivers/mmc/host/sdhci-esdhc.h    |  1 +
> > >  drivers/mmc/host/sdhci-of-esdhc.c | 70
> > > +++++++++++++++++++++++++++++++++++++--
> > >  2 files changed, 69 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/mmc/host/sdhci-esdhc.h
> > > b/drivers/mmc/host/sdhci-esdhc.h index ece8b37..5343fc0 100644
> > > --- a/drivers/mmc/host/sdhci-esdhc.h
> > > +++ b/drivers/mmc/host/sdhci-esdhc.h
> > > @@ -54,6 +54,7 @@
> > >
> > >  /* Control Register for DMA transfer */
> > >  #define ESDHC_DMA_SYSCTL		0x40c
> > > +#define ESDHC_PERIPHERAL_CLK_SEL	0x00080000
> > >  #define ESDHC_DMA_SNOOP			0x00000040
> > >
> > >  #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */ diff --git
> > > a/drivers/mmc/host/sdhci-of-esdhc.c
> > > b/drivers/mmc/host/sdhci-of-esdhc.c
> > > index ff37e74..7ce1caf 100644
> > > --- a/drivers/mmc/host/sdhci-of-esdhc.c
> > > +++ b/drivers/mmc/host/sdhci-of-esdhc.c
> > > @@ -19,6 +19,7 @@
> > >  #include <linux/delay.h>
> > >  #include <linux/module.h>
> > >  #include <linux/sys_soc.h>
> > > +#include <linux/clk.h>
> > >  #include <linux/mmc/host.h>
> > >  #include "sdhci-pltfm.h"
> > >  #include "sdhci-esdhc.h"
> > > @@ -30,6 +31,7 @@ struct sdhci_esdhc {
> > >  	u8 vendor_ver;
> > >  	u8 spec_ver;
> > >  	bool quirk_incorrect_hostver;
> > > +	unsigned int peripheral_clock;
> > >  };
> > >
> > >  /**
> > > @@ -414,15 +416,25 @@ static int esdhc_of_enable_dma(struct
> > > sdhci_host
> > > *host)  static unsigned int esdhc_of_get_max_clock(struct sdhci_host
> > > *host)  {
> > >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > > +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> > >
> > > -	return pltfm_host->clock;
> > > +	if (esdhc->peripheral_clock)
> > > +		return esdhc->peripheral_clock;
> > > +	else
> > > +		return pltfm_host->clock;
> > >  }
> > >
> > >  static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
> > > {
> > >  	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> > > +	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
> > > +	unsigned int clock;
> > >
> > > -	return pltfm_host->clock / 256 / 16;
> > > +	if (esdhc->peripheral_clock)
> > > +		clock = esdhc->peripheral_clock;
> > > +	else
> > > +		clock = pltfm_host->clock;
> > > +	return clock / 256 / 16;
> > >  }
> > >
> > >  static void esdhc_of_set_clock(struct sdhci_host *host, unsigned
> > > int
> > > clock) @@ -512,6 +524,33 @@ static void
> > esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
> > >  	sdhci_writel(host, ctrl, ESDHC_PROCTL);  }
> > >
> > > +static void esdhc_clock_enable(struct sdhci_host *host, bool
> > > +enable) {
> > > +	u32 val;
> > > +	u32 timeout;
> > > +
> > > +	val = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
> > > +
> > > +	if (enable)
> > > +		val |= ESDHC_CLOCK_SDCLKEN;
> > > +	else
> > > +		val &= ~ESDHC_CLOCK_SDCLKEN;
> > > +
> > > +	sdhci_writel(host, val, ESDHC_SYSTEM_CONTROL);
> > > +
> > > +	timeout = 20;
> > > +	val = ESDHC_CLOCK_STABLE;
> > > +	while (!(sdhci_readl(host, ESDHC_PRSSTAT) & val)) {
> > > +		if (timeout == 0) {
> > > +			pr_err("%s: Internal clock never stabilised.\n",
> > > +				mmc_hostname(host->mmc));
> > > +			break;
> > > +		}
> > > +		timeout--;
> > > +		mdelay(1);
> >
> > If the time to stabilize is much less that 1 ms then this loop can
> > waste time.  Have a look at the change in sdhci.c.
> >
> 
> [Lu Yangbo-B47093] Thanks a lot. The method in sdhci.c is really better.
> I will send next version to use it soon.
> 
> Currently another place in esdhc driver could also change to use this
> method. I will send a separate patch for that later.
> 

[Lu Yangbo-B47093] I just sent another patch to fix the mdelay problem.
https://patchwork.kernel.org/patch/9700193/

Thank you very much.

> 
> > > +	}
> > > +}
> > > +
> > >  static void esdhc_reset(struct sdhci_host *host, u8 mask)  {
> > >  	sdhci_reset(host, mask);
> > > @@ -613,6 +652,9 @@ static void esdhc_init(struct platform_device
> > > *pdev, struct sdhci_host *host)  {
> > >  	struct sdhci_pltfm_host *pltfm_host;
> > >  	struct sdhci_esdhc *esdhc;
> > > +	struct device_node *np;
> > > +	struct clk *clk;
> > > +	u32 val;
> > >  	u16 host_ver;
> > >
> > >  	pltfm_host = sdhci_priv(host);
> > > @@ -626,6 +668,30 @@ static void esdhc_init(struct platform_device
> > *pdev, struct sdhci_host *host)
> > >  		esdhc->quirk_incorrect_hostver = true;
> > >  	else
> > >  		esdhc->quirk_incorrect_hostver = false;
> > > +
> > > +	np = pdev->dev.of_node;
> > > +	clk = of_clk_get(np, 0);
> >
> > Should there be a clk_put somewhere?
> 
> [Lu Yangbo-B47093] Will add it after driver gets the clock value.
> 
> >
> > > +	if (!IS_ERR(clk)) {
> > > +		/*
> > > +		 * esdhc->peripheral_clock would be assigned with a value
> > > +		 * which is eSDHC base clock when use periperal clock.
> > > +		 * For ls1046a, the clock value got by common clk API is
> > > +		 * peripheral clock while the eSDHC base clock is 1/2
> > > +		 * peripheral clock.
> > > +		 */
> > > +		if (of_device_is_compatible(np, "fsl,ls1046a-esdhc"))
> > > +			esdhc->peripheral_clock = clk_get_rate(clk) / 2;
> > > +		else
> > > +			esdhc->peripheral_clock = clk_get_rate(clk);
> > > +	}
> > > +
> > > +	if (esdhc->peripheral_clock) {
> > > +		esdhc_clock_enable(host, false);
> > > +		val = sdhci_readl(host, ESDHC_DMA_SYSCTL);
> > > +		val |= ESDHC_PERIPHERAL_CLK_SEL;
> > > +		sdhci_writel(host, val, ESDHC_DMA_SYSCTL);
> > > +		esdhc_clock_enable(host, true);
> > > +	}
> > >  }
> > >
> > >  static int sdhci_esdhc_probe(struct platform_device *pdev)
> > >
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2017-04-26  3:09 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-27  7:49 [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC Yangbo Lu
2017-03-27  7:49 ` Yangbo Lu
2017-03-27  7:49 ` [v3, 1/7] mmc: sdhci-of-esdhc: add peripheral clock support Yangbo Lu
2017-03-27  7:49   ` Yangbo Lu
2017-04-10 12:36   ` Adrian Hunter
2017-04-10 12:36     ` Adrian Hunter
2017-04-11  5:14     ` Y.B. Lu
2017-04-11  5:14       ` Y.B. Lu
2017-04-26  3:09       ` Y.B. Lu
2017-03-27  7:49 ` [v3, 2/7] mmc: sdhci-of-esdhc: add support for signal voltage switch Yangbo Lu
2017-03-27  7:49   ` Yangbo Lu
2017-04-10 12:37   ` Adrian Hunter
2017-04-10 12:37     ` Adrian Hunter
     [not found]     ` <e7e08c87-ecd6-ab24-636c-7707a5172b08-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-04-11  5:20       ` Y.B. Lu
2017-04-11  5:20         ` Y.B. Lu
2017-03-27  7:49 ` [v3, 3/7] mmc: sdhci-of-esdhc: add tuning support Yangbo Lu
2017-03-27  7:49   ` Yangbo Lu
     [not found]   ` <1490600982-5410-4-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
2017-04-10 12:38     ` Adrian Hunter
2017-04-10 12:38       ` Adrian Hunter
2017-03-27  7:49 ` [v3, 4/7] mmc: sdhci: Control the delay between tuning commands Yangbo Lu
2017-03-27  7:49   ` Yangbo Lu
2017-03-27  7:49 ` [v3, 5/7] mmc: sdhci-of-esdhc: add delay between tuning cycles Yangbo Lu
2017-03-27  7:49   ` Yangbo Lu
2017-04-10 12:39   ` Adrian Hunter
2017-04-10 12:39     ` Adrian Hunter
     [not found] ` <1490600982-5410-1-git-send-email-yangbo.lu-3arQi8VN3Tc@public.gmane.org>
2017-03-27  7:49   ` [v3, 6/7] arm64: dts: ls1046a: add clocks property and compatible for eSDHC node Yangbo Lu
2017-03-27  7:49     ` Yangbo Lu
2017-03-27  7:49 ` [v3, 7/7] arm64: dts: ls1046ardb: add MMC HS200/UHS-1 modes support Yangbo Lu
2017-03-27  7:49   ` Yangbo Lu
2017-04-06  8:02 ` [v3, 0/7] Add SD UHS-I and eMMC HS200 support for eSDHC Y.B. Lu
2017-04-06  8:02   ` Y.B. Lu
2017-04-10  8:20 ` Y.B. Lu
2017-04-10  8:20   ` Y.B. Lu
2017-04-10 10:48   ` Ulf Hansson
2017-04-10 10:48     ` Ulf Hansson
2017-04-11  5:24     ` Y.B. Lu
2017-04-11  5:24       ` Y.B. Lu

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.