All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support
@ 2015-01-14 10:30 ` Alim Akhtar
  0 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw)
  To: linux-mmc
  Cc: chris, ulf.hansson, jh80.chung, tgih.jun, dianders, alim.akhtar,
	kgene, linux-arm-kernel, devicetree, linux-samsung-soc,
	a.kesavan

This adds HS400 mode support for exynos dw_mmc host controller.

Currently tested on Exynos5800-peach-pi platform for HS400 mode.
Tested HS200 mode with this series applied, HS200 still works.

Appreciate testing on other exynos5/7 platform which supports emmc5.0

Changes in V4:
	* drop the idea of changing existing binding for ciu_div as per [1]
        * addressed comments from Jaehoon Chung [2]

[1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html
[2] http://www.spinics.net/lists/devicetree/msg64373.html

Changes in V3:
	rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static)

Seungwon Jeon (2):
  mmc: dw_mmc: exynos: Support eMMC's HS400 mode
  ARM: dts: Add HS400 support for exynos5420 and exynos5800

 .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
 arch/arm/boot/dts/exynos5420-peach-pit.dts         |    4 +-
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi          |    7 +
 arch/arm/boot/dts/exynos5420-smdk5420.dts          |    4 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts          |    4 +-
 drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
 drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
 drivers/mmc/host/dw_mmc.c                          |   16 +-
 drivers/mmc/host/dw_mmc.h                          |    2 +
 9 files changed, 212 insertions(+), 38 deletions(-)

-- 
1.7.9.5


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

* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support
@ 2015-01-14 10:30 ` Alim Akhtar
  0 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

This adds HS400 mode support for exynos dw_mmc host controller.

Currently tested on Exynos5800-peach-pi platform for HS400 mode.
Tested HS200 mode with this series applied, HS200 still works.

Appreciate testing on other exynos5/7 platform which supports emmc5.0

Changes in V4:
	* drop the idea of changing existing binding for ciu_div as per [1]
        * addressed comments from Jaehoon Chung [2]

[1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html
[2] http://www.spinics.net/lists/devicetree/msg64373.html

Changes in V3:
	rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static)

Seungwon Jeon (2):
  mmc: dw_mmc: exynos: Support eMMC's HS400 mode
  ARM: dts: Add HS400 support for exynos5420 and exynos5800

 .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
 arch/arm/boot/dts/exynos5420-peach-pit.dts         |    4 +-
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi          |    7 +
 arch/arm/boot/dts/exynos5420-smdk5420.dts          |    4 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts          |    4 +-
 drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
 drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
 drivers/mmc/host/dw_mmc.c                          |   16 +-
 drivers/mmc/host/dw_mmc.h                          |    2 +
 9 files changed, 212 insertions(+), 38 deletions(-)

-- 
1.7.9.5

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

* [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode
  2015-01-14 10:30 ` Alim Akhtar
@ 2015-01-14 10:30   ` Alim Akhtar
  -1 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw)
  To: linux-mmc
  Cc: chris, ulf.hansson, jh80.chung, tgih.jun, dianders, alim.akhtar,
	kgene, linux-arm-kernel, devicetree, linux-samsung-soc,
	a.kesavan

From: Seungwon Jeon <tgih.jun@samsung.com>

Implements HS400 mode support for exynos host driver.
This also include some updates as new mode is added.

Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
[Alim: addressed review comments]
---
 .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
 drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
 drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
 drivers/mmc/host/dw_mmc.c                          |   16 +-
 drivers/mmc/host/dw_mmc.h                          |    2 +
 5 files changed, 196 insertions(+), 35 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
index ee4fc05..dcab52c 100644
--- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
@@ -36,6 +36,8 @@ Required Properties:
   in transmit mode and CIU clock phase shift value in receive mode for double
   data rate mode operation. Refer notes below for the order of the cells and the
   valid values.
+* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase
+  shift value for hs400 mode operation.
 
   Notes for the sdr-timing and ddr-timing values:
 
@@ -50,6 +52,9 @@ Required Properties:
       - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
         phase shift clocks should be 0.
 
+* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode
+  (Latency value for delay line in Read path)
+
 Required properties for a slot (Deprecated - Recommend to use one slot per host):
 
 * gpios: specifies a list of gpios used for command, clock and data bus. The
@@ -82,5 +87,7 @@ Example:
 		samsung,dw-mshc-ciu-div = <3>;
 		samsung,dw-mshc-sdr-timing = <2 3>;
 		samsung,dw-mshc-ddr-timing = <1 2>;
+		samsung,dw-mshc-hs400-timing = <0 2>;
+		read-strobe-delay = <90>;
 		bus-width = <8>;
 	};
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 12a5eaa..172a2a8 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data {
 	u8				ciu_div;
 	u32				sdr_timing;
 	u32				ddr_timing;
+	u32				hs400_timing;
+	u32				tuned_sample;
 	u32				cur_speed;
+	u32				dqs_delay;
+	u32				saved_dqs_en;
+	u32				saved_strobe_ctrl;
 };
 
 static struct dw_mci_exynos_compatible {
@@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible {
 	},
 };
 
+static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+
+	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
+		return EXYNOS4412_FIXED_CIU_CLK_DIV;
+	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
+		return EXYNOS4210_FIXED_CIU_CLK_DIV;
+	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
+			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
+		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1;
+	else
+		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1;
+}
+
 static int dw_mci_exynos_priv_init(struct dw_mci *host)
 {
 	struct dw_mci_exynos_priv_data *priv = host->priv;
@@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
 			   SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT);
 	}
 
+	if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) {
+		priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL);
+		priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN);
+		priv->saved_dqs_en |= AXI_NON_BLOCKING_WR;
+		mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en);
+		if (!priv->dqs_delay)
+			priv->dqs_delay =
+				DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl);
+	}
+
 	return 0;
 }
 
@@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host)
 {
 	struct dw_mci_exynos_priv_data *priv = host->priv;
 
-	host->bus_hz /= (priv->ciu_div + 1);
+	host->bus_hz /= priv->ciu_div;
 
 	return 0;
 }
 
+static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+	u32 clksel;
+
+	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
+		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
+		clksel = mci_readl(host, CLKSEL64);
+	else
+		clksel = mci_readl(host, CLKSEL);
+
+	clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing;
+
+	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
+		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
+		mci_writel(host, CLKSEL64, clksel);
+	else
+		mci_writel(host, CLKSEL, clksel);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int dw_mci_exynos_suspend(struct device *dev)
 {
@@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
 	}
 }
 
-static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing)
 {
 	struct dw_mci_exynos_priv_data *priv = host->priv;
-	unsigned int wanted = ios->clock;
-	unsigned long actual;
-	u8 div = priv->ciu_div + 1;
+	u32 dqs, strobe;
 
-	if (ios->timing == MMC_TIMING_MMC_DDR52) {
-		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
-			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
-			mci_writel(host, CLKSEL64, priv->ddr_timing);
-		else
-			mci_writel(host, CLKSEL, priv->ddr_timing);
-		/* Should be double rate for DDR mode */
-		if (ios->bus_width == MMC_BUS_WIDTH_8)
-			wanted <<= 1;
+	/*
+	 * Not suppported to configure register
+	 * related to HS400
+	 */
+	if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420)
+		return;
+
+	dqs = priv->saved_dqs_en;
+	strobe = priv->saved_strobe_ctrl;
+
+	if (timing == MMC_TIMING_MMC_HS400) {
+		dqs |= DATA_STROBE_EN;
+		strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay);
 	} else {
-		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
-			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
-			mci_writel(host, CLKSEL64, priv->sdr_timing);
-		else
-			mci_writel(host, CLKSEL, priv->sdr_timing);
+		dqs &= ~DATA_STROBE_EN;
 	}
 
+	mci_writel(host, HS400_DQS_EN, dqs);
+	mci_writel(host, HS400_DLINE_CTRL, strobe);
+}
+
+static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+	unsigned long actual;
+	u8 div;
+	int ret;
 	/*
 	 * Don't care if wanted clock is zero or
 	 * ciu clock is unavailable
@@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
 	if (wanted < EXYNOS_CCLKIN_MIN)
 		wanted = EXYNOS_CCLKIN_MIN;
 
-	if (wanted != priv->cur_speed) {
-		int ret = clk_set_rate(host->ciu_clk, wanted * div);
-		if (ret)
-			dev_warn(host->dev,
-				"failed to set clk-rate %u error: %d\n",
-				 wanted * div, ret);
-		actual = clk_get_rate(host->ciu_clk);
-		host->bus_hz = actual / div;
-		priv->cur_speed = wanted;
-		host->current_speed = 0;
+	if (wanted == priv->cur_speed)
+		return;
+
+	div = dw_mci_exynos_get_ciu_div(host);
+	ret = clk_set_rate(host->ciu_clk, wanted * div);
+	if (ret)
+		dev_warn(host->dev,
+			"failed to set clk-rate %u error: %d\n",
+			wanted * div, ret);
+	actual = clk_get_rate(host->ciu_clk);
+	host->bus_hz = actual / div;
+	priv->cur_speed = wanted;
+	host->current_speed = 0;
+}
+
+static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+	unsigned int wanted = ios->clock;
+	u32 timing = ios->timing, clksel;
+
+	switch (timing) {
+	case MMC_TIMING_MMC_HS400:
+		/* Update tuned sample timing */
+		clksel = SDMMC_CLKSEL_UP_SAMPLE(
+				priv->hs400_timing, priv->tuned_sample);
+		wanted <<= 1;
+		break;
+	case MMC_TIMING_MMC_DDR52:
+		clksel = priv->ddr_timing;
+		/* Should be double rate for DDR mode */
+		if (ios->bus_width == MMC_BUS_WIDTH_8)
+			wanted <<= 1;
+		break;
+	default:
+		clksel = priv->sdr_timing;
 	}
+
+	/* Set clock timing for the requested speed mode*/
+	dw_mci_exynos_set_clksel_timing(host, clksel);
+
+	/* Configure setting for HS400 */
+	dw_mci_exynos_config_hs400(host, timing);
+
+	/* Configure clock rate */
+	dw_mci_exynos_adjust_clock(host, wanted);
 }
 
 static int dw_mci_exynos_parse_dt(struct dw_mci *host)
@@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host)
 		return ret;
 
 	priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+
+	ret = of_property_read_u32_array(np,
+			"samsung,dw-mshc-hs400-timing", timing, 2);
+	if (!ret && of_property_read_u32(np,
+				"read-strobe-delay", &priv->dqs_delay))
+		dev_info(host->dev,
+			"read-strobe-delay is not found, assuming usage of default value\n");
+
+	priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1],
+						HS400_FIXED_CIU_CLK_DIV);
 	host->priv = priv;
 	return 0;
 }
@@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample)
 		clksel = mci_readl(host, CLKSEL64);
 	else
 		clksel = mci_readl(host, CLKSEL);
-	clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample);
+	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
 	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
 		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
 		mci_writel(host, CLKSEL64, clksel);
@@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host)
 		clksel = mci_readl(host, CLKSEL64);
 	else
 		clksel = mci_readl(host, CLKSEL);
+
 	sample = (clksel + 1) & 0x7;
-	clksel = (clksel & ~0x7) | sample;
+	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
+
 	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
 		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
 		mci_writel(host, CLKSEL64, clksel);
 	else
 		mci_writel(host, CLKSEL, clksel);
+
 	return sample;
 }
 
@@ -343,6 +449,7 @@ out:
 static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
 {
 	struct dw_mci *host = slot->host;
+	struct dw_mci_exynos_priv_data *priv = host->priv;
 	struct mmc_host *mmc = slot->mmc;
 	u8 start_smpl, smpl, candiates = 0;
 	s8 found = -1;
@@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
 	} while (start_smpl != smpl);
 
 	found = dw_mci_exynos_get_best_clksmpl(candiates);
-	if (found >= 0)
+	if (found >= 0) {
 		dw_mci_exynos_set_clksmpl(host, found);
-	else
+		priv->tuned_sample = found;
+	} else {
 		ret = -EIO;
+	}
 
 	return ret;
 }
 
+int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host,
+					struct mmc_ios *ios)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+
+	dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing);
+	dw_mci_exynos_adjust_clock(host, (ios->clock) << 1);
+
+	return 0;
+}
+
 /* Common capabilities of Exynos4/Exynos5 SoC */
 static unsigned long exynos_dwmmc_caps[4] = {
 	MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
@@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = {
 	.set_ios		= dw_mci_exynos_set_ios,
 	.parse_dt		= dw_mci_exynos_parse_dt,
 	.execute_tuning		= dw_mci_exynos_execute_tuning,
+	.prepare_hs400_tuning	= dw_mci_exynos_prepare_hs400_tuning,
 };
 
 static const struct of_device_id dw_mci_exynos_match[] = {
diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h
index 7872ce5..595c934 100644
--- a/drivers/mmc/host/dw_mmc-exynos.h
+++ b/drivers/mmc/host/dw_mmc-exynos.h
@@ -12,20 +12,36 @@
 #ifndef _DW_MMC_EXYNOS_H_
 #define _DW_MMC_EXYNOS_H_
 
-/* Extended Register's Offset */
 #define SDMMC_CLKSEL			0x09C
 #define SDMMC_CLKSEL64			0x0A8
 
+/* Extended Register's Offset */
+#define SDMMC_HS400_DQS_EN		0x180
+#define SDMMC_HS400_ASYNC_FIFO_CTRL	0x184
+#define SDMMC_HS400_DLINE_CTRL		0x188
+
 /* CLKSEL register defines */
 #define SDMMC_CLKSEL_CCLK_SAMPLE(x)	(((x) & 7) << 0)
 #define SDMMC_CLKSEL_CCLK_DRIVE(x)	(((x) & 7) << 16)
 #define SDMMC_CLKSEL_CCLK_DIVIDER(x)	(((x) & 7) << 24)
 #define SDMMC_CLKSEL_GET_DRV_WD3(x)	(((x) >> 16) & 0x7)
+#define SDMMC_CLKSEL_GET_DIV(x)		(((x) >> 24) & 0x7)
+#define SDMMC_CLKSEL_UP_SAMPLE(x, y)	(((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\
+					 SDMMC_CLKSEL_CCLK_SAMPLE(y))
 #define SDMMC_CLKSEL_TIMING(x, y, z)	(SDMMC_CLKSEL_CCLK_SAMPLE(x) |	\
 					 SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
 					 SDMMC_CLKSEL_CCLK_DIVIDER(z))
+#define SDMMC_CLKSEL_TIMING_MASK	SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7)
 #define SDMMC_CLKSEL_WAKEUP_INT		BIT(11)
 
+/* RCLK_EN register defines */
+#define DATA_STROBE_EN			BIT(0)
+#define AXI_NON_BLOCKING_WR	BIT(7)
+
+/* DLINE_CTRL register defines */
+#define DQS_CTRL_RD_DELAY(x, y)		(((x) & ~0x3FF) | ((y) & 0x3FF))
+#define DQS_CTRL_GET_RD_DELAY(x)	((x) & 0x3FF)
+
 /* Protector Register */
 #define SDMMC_EMMCP_BASE	0x1000
 #define SDMMC_MPSECURITY	(SDMMC_EMMCP_BASE + 0x0010)
@@ -49,6 +65,7 @@
 /* Fixed clock divider */
 #define EXYNOS4210_FIXED_CIU_CLK_DIV	2
 #define EXYNOS4412_FIXED_CIU_CLK_DIV	4
+#define HS400_FIXED_CIU_CLK_DIV		1
 
 /* Minimal required clock frequency for cclkin, unit: HZ */
 #define EXYNOS_CCLKIN_MIN	50000000
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 2e8abc8..43a3a5b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	regs = mci_readl(slot->host, UHS_REG);
 
 	/* DDR mode set */
-	if (ios->timing == MMC_TIMING_MMC_DDR52)
+	if (ios->timing == MMC_TIMING_MMC_DDR52 ||
+	    ios->timing == MMC_TIMING_MMC_HS400)
 		regs |= ((0x1 << slot->id) << 16);
 	else
 		regs &= ~((0x1 << slot->id) << 16);
@@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	return err;
 }
 
+int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct dw_mci *host = slot->host;
+	const struct dw_mci_drv_data *drv_data = host->drv_data;
+
+	if (drv_data && drv_data->prepare_hs400_tuning)
+		return drv_data->prepare_hs400_tuning(host, ios);
+
+	return 0;
+}
+
 static const struct mmc_host_ops dw_mci_ops = {
 	.request		= dw_mci_request,
 	.pre_req		= dw_mci_pre_req,
@@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = {
 	.card_busy		= dw_mci_card_busy,
 	.start_signal_voltage_switch = dw_mci_switch_voltage,
 	.init_card		= dw_mci_init_card,
+	.prepare_hs400_tuning	= dw_mci_prepare_hs400_tuning,
 };
 
 static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 18c4afe..d239867 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -271,5 +271,7 @@ struct dw_mci_drv_data {
 	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
 	int		(*parse_dt)(struct dw_mci *host);
 	int		(*execute_tuning)(struct dw_mci_slot *slot);
+	int		(*prepare_hs400_tuning)(struct dw_mci *host,
+						struct mmc_ios *ios);
 };
 #endif /* _DW_MMC_H_ */
-- 
1.7.9.5

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

* [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode
@ 2015-01-14 10:30   ` Alim Akhtar
  0 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

From: Seungwon Jeon <tgih.jun@samsung.com>

Implements HS400 mode support for exynos host driver.
This also include some updates as new mode is added.

Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
[Alim: addressed review comments]
---
 .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
 drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
 drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
 drivers/mmc/host/dw_mmc.c                          |   16 +-
 drivers/mmc/host/dw_mmc.h                          |    2 +
 5 files changed, 196 insertions(+), 35 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
index ee4fc05..dcab52c 100644
--- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
@@ -36,6 +36,8 @@ Required Properties:
   in transmit mode and CIU clock phase shift value in receive mode for double
   data rate mode operation. Refer notes below for the order of the cells and the
   valid values.
+* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase
+  shift value for hs400 mode operation.
 
   Notes for the sdr-timing and ddr-timing values:
 
@@ -50,6 +52,9 @@ Required Properties:
       - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
         phase shift clocks should be 0.
 
+* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode
+  (Latency value for delay line in Read path)
+
 Required properties for a slot (Deprecated - Recommend to use one slot per host):
 
 * gpios: specifies a list of gpios used for command, clock and data bus. The
@@ -82,5 +87,7 @@ Example:
 		samsung,dw-mshc-ciu-div = <3>;
 		samsung,dw-mshc-sdr-timing = <2 3>;
 		samsung,dw-mshc-ddr-timing = <1 2>;
+		samsung,dw-mshc-hs400-timing = <0 2>;
+		read-strobe-delay = <90>;
 		bus-width = <8>;
 	};
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
index 12a5eaa..172a2a8 100644
--- a/drivers/mmc/host/dw_mmc-exynos.c
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data {
 	u8				ciu_div;
 	u32				sdr_timing;
 	u32				ddr_timing;
+	u32				hs400_timing;
+	u32				tuned_sample;
 	u32				cur_speed;
+	u32				dqs_delay;
+	u32				saved_dqs_en;
+	u32				saved_strobe_ctrl;
 };
 
 static struct dw_mci_exynos_compatible {
@@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible {
 	},
 };
 
+static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+
+	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
+		return EXYNOS4412_FIXED_CIU_CLK_DIV;
+	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
+		return EXYNOS4210_FIXED_CIU_CLK_DIV;
+	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
+			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
+		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1;
+	else
+		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1;
+}
+
 static int dw_mci_exynos_priv_init(struct dw_mci *host)
 {
 	struct dw_mci_exynos_priv_data *priv = host->priv;
@@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
 			   SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT);
 	}
 
+	if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) {
+		priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL);
+		priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN);
+		priv->saved_dqs_en |= AXI_NON_BLOCKING_WR;
+		mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en);
+		if (!priv->dqs_delay)
+			priv->dqs_delay =
+				DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl);
+	}
+
 	return 0;
 }
 
@@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host)
 {
 	struct dw_mci_exynos_priv_data *priv = host->priv;
 
-	host->bus_hz /= (priv->ciu_div + 1);
+	host->bus_hz /= priv->ciu_div;
 
 	return 0;
 }
 
+static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+	u32 clksel;
+
+	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
+		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
+		clksel = mci_readl(host, CLKSEL64);
+	else
+		clksel = mci_readl(host, CLKSEL);
+
+	clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing;
+
+	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
+		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
+		mci_writel(host, CLKSEL64, clksel);
+	else
+		mci_writel(host, CLKSEL, clksel);
+}
+
 #ifdef CONFIG_PM_SLEEP
 static int dw_mci_exynos_suspend(struct device *dev)
 {
@@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
 	}
 }
 
-static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing)
 {
 	struct dw_mci_exynos_priv_data *priv = host->priv;
-	unsigned int wanted = ios->clock;
-	unsigned long actual;
-	u8 div = priv->ciu_div + 1;
+	u32 dqs, strobe;
 
-	if (ios->timing == MMC_TIMING_MMC_DDR52) {
-		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
-			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
-			mci_writel(host, CLKSEL64, priv->ddr_timing);
-		else
-			mci_writel(host, CLKSEL, priv->ddr_timing);
-		/* Should be double rate for DDR mode */
-		if (ios->bus_width == MMC_BUS_WIDTH_8)
-			wanted <<= 1;
+	/*
+	 * Not suppported to configure register
+	 * related to HS400
+	 */
+	if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420)
+		return;
+
+	dqs = priv->saved_dqs_en;
+	strobe = priv->saved_strobe_ctrl;
+
+	if (timing == MMC_TIMING_MMC_HS400) {
+		dqs |= DATA_STROBE_EN;
+		strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay);
 	} else {
-		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
-			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
-			mci_writel(host, CLKSEL64, priv->sdr_timing);
-		else
-			mci_writel(host, CLKSEL, priv->sdr_timing);
+		dqs &= ~DATA_STROBE_EN;
 	}
 
+	mci_writel(host, HS400_DQS_EN, dqs);
+	mci_writel(host, HS400_DLINE_CTRL, strobe);
+}
+
+static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+	unsigned long actual;
+	u8 div;
+	int ret;
 	/*
 	 * Don't care if wanted clock is zero or
 	 * ciu clock is unavailable
@@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
 	if (wanted < EXYNOS_CCLKIN_MIN)
 		wanted = EXYNOS_CCLKIN_MIN;
 
-	if (wanted != priv->cur_speed) {
-		int ret = clk_set_rate(host->ciu_clk, wanted * div);
-		if (ret)
-			dev_warn(host->dev,
-				"failed to set clk-rate %u error: %d\n",
-				 wanted * div, ret);
-		actual = clk_get_rate(host->ciu_clk);
-		host->bus_hz = actual / div;
-		priv->cur_speed = wanted;
-		host->current_speed = 0;
+	if (wanted == priv->cur_speed)
+		return;
+
+	div = dw_mci_exynos_get_ciu_div(host);
+	ret = clk_set_rate(host->ciu_clk, wanted * div);
+	if (ret)
+		dev_warn(host->dev,
+			"failed to set clk-rate %u error: %d\n",
+			wanted * div, ret);
+	actual = clk_get_rate(host->ciu_clk);
+	host->bus_hz = actual / div;
+	priv->cur_speed = wanted;
+	host->current_speed = 0;
+}
+
+static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+	unsigned int wanted = ios->clock;
+	u32 timing = ios->timing, clksel;
+
+	switch (timing) {
+	case MMC_TIMING_MMC_HS400:
+		/* Update tuned sample timing */
+		clksel = SDMMC_CLKSEL_UP_SAMPLE(
+				priv->hs400_timing, priv->tuned_sample);
+		wanted <<= 1;
+		break;
+	case MMC_TIMING_MMC_DDR52:
+		clksel = priv->ddr_timing;
+		/* Should be double rate for DDR mode */
+		if (ios->bus_width == MMC_BUS_WIDTH_8)
+			wanted <<= 1;
+		break;
+	default:
+		clksel = priv->sdr_timing;
 	}
+
+	/* Set clock timing for the requested speed mode*/
+	dw_mci_exynos_set_clksel_timing(host, clksel);
+
+	/* Configure setting for HS400 */
+	dw_mci_exynos_config_hs400(host, timing);
+
+	/* Configure clock rate */
+	dw_mci_exynos_adjust_clock(host, wanted);
 }
 
 static int dw_mci_exynos_parse_dt(struct dw_mci *host)
@@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host)
 		return ret;
 
 	priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+
+	ret = of_property_read_u32_array(np,
+			"samsung,dw-mshc-hs400-timing", timing, 2);
+	if (!ret && of_property_read_u32(np,
+				"read-strobe-delay", &priv->dqs_delay))
+		dev_info(host->dev,
+			"read-strobe-delay is not found, assuming usage of default value\n");
+
+	priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1],
+						HS400_FIXED_CIU_CLK_DIV);
 	host->priv = priv;
 	return 0;
 }
@@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample)
 		clksel = mci_readl(host, CLKSEL64);
 	else
 		clksel = mci_readl(host, CLKSEL);
-	clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample);
+	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
 	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
 		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
 		mci_writel(host, CLKSEL64, clksel);
@@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host)
 		clksel = mci_readl(host, CLKSEL64);
 	else
 		clksel = mci_readl(host, CLKSEL);
+
 	sample = (clksel + 1) & 0x7;
-	clksel = (clksel & ~0x7) | sample;
+	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
+
 	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
 		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
 		mci_writel(host, CLKSEL64, clksel);
 	else
 		mci_writel(host, CLKSEL, clksel);
+
 	return sample;
 }
 
@@ -343,6 +449,7 @@ out:
 static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
 {
 	struct dw_mci *host = slot->host;
+	struct dw_mci_exynos_priv_data *priv = host->priv;
 	struct mmc_host *mmc = slot->mmc;
 	u8 start_smpl, smpl, candiates = 0;
 	s8 found = -1;
@@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
 	} while (start_smpl != smpl);
 
 	found = dw_mci_exynos_get_best_clksmpl(candiates);
-	if (found >= 0)
+	if (found >= 0) {
 		dw_mci_exynos_set_clksmpl(host, found);
-	else
+		priv->tuned_sample = found;
+	} else {
 		ret = -EIO;
+	}
 
 	return ret;
 }
 
+int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host,
+					struct mmc_ios *ios)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+
+	dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing);
+	dw_mci_exynos_adjust_clock(host, (ios->clock) << 1);
+
+	return 0;
+}
+
 /* Common capabilities of Exynos4/Exynos5 SoC */
 static unsigned long exynos_dwmmc_caps[4] = {
 	MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
@@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = {
 	.set_ios		= dw_mci_exynos_set_ios,
 	.parse_dt		= dw_mci_exynos_parse_dt,
 	.execute_tuning		= dw_mci_exynos_execute_tuning,
+	.prepare_hs400_tuning	= dw_mci_exynos_prepare_hs400_tuning,
 };
 
 static const struct of_device_id dw_mci_exynos_match[] = {
diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h
index 7872ce5..595c934 100644
--- a/drivers/mmc/host/dw_mmc-exynos.h
+++ b/drivers/mmc/host/dw_mmc-exynos.h
@@ -12,20 +12,36 @@
 #ifndef _DW_MMC_EXYNOS_H_
 #define _DW_MMC_EXYNOS_H_
 
-/* Extended Register's Offset */
 #define SDMMC_CLKSEL			0x09C
 #define SDMMC_CLKSEL64			0x0A8
 
+/* Extended Register's Offset */
+#define SDMMC_HS400_DQS_EN		0x180
+#define SDMMC_HS400_ASYNC_FIFO_CTRL	0x184
+#define SDMMC_HS400_DLINE_CTRL		0x188
+
 /* CLKSEL register defines */
 #define SDMMC_CLKSEL_CCLK_SAMPLE(x)	(((x) & 7) << 0)
 #define SDMMC_CLKSEL_CCLK_DRIVE(x)	(((x) & 7) << 16)
 #define SDMMC_CLKSEL_CCLK_DIVIDER(x)	(((x) & 7) << 24)
 #define SDMMC_CLKSEL_GET_DRV_WD3(x)	(((x) >> 16) & 0x7)
+#define SDMMC_CLKSEL_GET_DIV(x)		(((x) >> 24) & 0x7)
+#define SDMMC_CLKSEL_UP_SAMPLE(x, y)	(((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\
+					 SDMMC_CLKSEL_CCLK_SAMPLE(y))
 #define SDMMC_CLKSEL_TIMING(x, y, z)	(SDMMC_CLKSEL_CCLK_SAMPLE(x) |	\
 					 SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
 					 SDMMC_CLKSEL_CCLK_DIVIDER(z))
+#define SDMMC_CLKSEL_TIMING_MASK	SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7)
 #define SDMMC_CLKSEL_WAKEUP_INT		BIT(11)
 
+/* RCLK_EN register defines */
+#define DATA_STROBE_EN			BIT(0)
+#define AXI_NON_BLOCKING_WR	BIT(7)
+
+/* DLINE_CTRL register defines */
+#define DQS_CTRL_RD_DELAY(x, y)		(((x) & ~0x3FF) | ((y) & 0x3FF))
+#define DQS_CTRL_GET_RD_DELAY(x)	((x) & 0x3FF)
+
 /* Protector Register */
 #define SDMMC_EMMCP_BASE	0x1000
 #define SDMMC_MPSECURITY	(SDMMC_EMMCP_BASE + 0x0010)
@@ -49,6 +65,7 @@
 /* Fixed clock divider */
 #define EXYNOS4210_FIXED_CIU_CLK_DIV	2
 #define EXYNOS4412_FIXED_CIU_CLK_DIV	4
+#define HS400_FIXED_CIU_CLK_DIV		1
 
 /* Minimal required clock frequency for cclkin, unit: HZ */
 #define EXYNOS_CCLKIN_MIN	50000000
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 2e8abc8..43a3a5b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 	regs = mci_readl(slot->host, UHS_REG);
 
 	/* DDR mode set */
-	if (ios->timing == MMC_TIMING_MMC_DDR52)
+	if (ios->timing == MMC_TIMING_MMC_DDR52 ||
+	    ios->timing == MMC_TIMING_MMC_HS400)
 		regs |= ((0x1 << slot->id) << 16);
 	else
 		regs &= ~((0x1 << slot->id) << 16);
@@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
 	return err;
 }
 
+int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct dw_mci_slot *slot = mmc_priv(mmc);
+	struct dw_mci *host = slot->host;
+	const struct dw_mci_drv_data *drv_data = host->drv_data;
+
+	if (drv_data && drv_data->prepare_hs400_tuning)
+		return drv_data->prepare_hs400_tuning(host, ios);
+
+	return 0;
+}
+
 static const struct mmc_host_ops dw_mci_ops = {
 	.request		= dw_mci_request,
 	.pre_req		= dw_mci_pre_req,
@@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = {
 	.card_busy		= dw_mci_card_busy,
 	.start_signal_voltage_switch = dw_mci_switch_voltage,
 	.init_card		= dw_mci_init_card,
+	.prepare_hs400_tuning	= dw_mci_prepare_hs400_tuning,
 };
 
 static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 18c4afe..d239867 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -271,5 +271,7 @@ struct dw_mci_drv_data {
 	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
 	int		(*parse_dt)(struct dw_mci *host);
 	int		(*execute_tuning)(struct dw_mci_slot *slot);
+	int		(*prepare_hs400_tuning)(struct dw_mci *host,
+						struct mmc_ios *ios);
 };
 #endif /* _DW_MMC_H_ */
-- 
1.7.9.5

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

* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
  2015-01-14 10:30 ` Alim Akhtar
@ 2015-01-14 10:30   ` Alim Akhtar
  -1 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw)
  To: linux-mmc
  Cc: chris, ulf.hansson, jh80.chung, tgih.jun, dianders, alim.akhtar,
	kgene, linux-arm-kernel, devicetree, linux-samsung-soc,
	a.kesavan

From: Seungwon Jeon <tgih.jun@samsung.com>

HS400 timing values are added for SMDK5420, exynos5420-peach-pit
and exynos5800-peach-pi boards.
This also adds RCLK GPIO line, this gpio should be in pull-down
state.

Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
[Alim: addressed review comments]
---
 arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
 arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 9a050e1..7ffaba8 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -569,8 +569,10 @@
 	samsung,dw-mshc-ciu-div = <3>;
 	samsung,dw-mshc-sdr-timing = <0 4>;
 	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-hs400-timing = <0 2>;
+	read-strobe-delay = <90>;
 	pinctrl-names = "default";
-	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
 	bus-width = <8>;
 };
 
diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
index ba686e4..8b15316 100644
--- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
@@ -201,6 +201,13 @@
 			samsung,pin-drv = <3>;
 		};
 
+		sd0_rclk: sd0-rclk {
+			samsung,pins = "gpc0-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <1>;
+			samsung,pin-drv = <3>;
+		};
+
 		sd1_cmd: sd1-cmd {
 			samsung,pins = "gpc1-1";
 			samsung,pin-function = <2>;
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index 8be3d7b..5290e79 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -80,8 +80,10 @@
 		samsung,dw-mshc-ciu-div = <3>;
 		samsung,dw-mshc-sdr-timing = <0 4>;
 		samsung,dw-mshc-ddr-timing = <0 2>;
+		samsung,dw-mshc-hs400-timing = <0 2>;
+		read-strobe-delay = <90>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
 		bus-width = <8>;
 		cap-mmc-highspeed;
 	};
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index e8fdda8..fa1c858 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -557,8 +557,10 @@
 	samsung,dw-mshc-ciu-div = <3>;
 	samsung,dw-mshc-sdr-timing = <0 4>;
 	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-hs400-timing = <0 2>;
+	read-strobe-delay = <90>;
 	pinctrl-names = "default";
-	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
 	bus-width = <8>;
 };
 
-- 
1.7.9.5

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

* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
@ 2015-01-14 10:30   ` Alim Akhtar
  0 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-14 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

From: Seungwon Jeon <tgih.jun@samsung.com>

HS400 timing values are added for SMDK5420, exynos5420-peach-pit
and exynos5800-peach-pi boards.
This also adds RCLK GPIO line, this gpio should be in pull-down
state.

Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
[Alim: addressed review comments]
---
 arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
 arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 9a050e1..7ffaba8 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -569,8 +569,10 @@
 	samsung,dw-mshc-ciu-div = <3>;
 	samsung,dw-mshc-sdr-timing = <0 4>;
 	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-hs400-timing = <0 2>;
+	read-strobe-delay = <90>;
 	pinctrl-names = "default";
-	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
 	bus-width = <8>;
 };
 
diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
index ba686e4..8b15316 100644
--- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
@@ -201,6 +201,13 @@
 			samsung,pin-drv = <3>;
 		};
 
+		sd0_rclk: sd0-rclk {
+			samsung,pins = "gpc0-7";
+			samsung,pin-function = <2>;
+			samsung,pin-pud = <1>;
+			samsung,pin-drv = <3>;
+		};
+
 		sd1_cmd: sd1-cmd {
 			samsung,pins = "gpc1-1";
 			samsung,pin-function = <2>;
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index 8be3d7b..5290e79 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -80,8 +80,10 @@
 		samsung,dw-mshc-ciu-div = <3>;
 		samsung,dw-mshc-sdr-timing = <0 4>;
 		samsung,dw-mshc-ddr-timing = <0 2>;
+		samsung,dw-mshc-hs400-timing = <0 2>;
+		read-strobe-delay = <90>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
 		bus-width = <8>;
 		cap-mmc-highspeed;
 	};
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index e8fdda8..fa1c858 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -557,8 +557,10 @@
 	samsung,dw-mshc-ciu-div = <3>;
 	samsung,dw-mshc-sdr-timing = <0 4>;
 	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-hs400-timing = <0 2>;
+	read-strobe-delay = <90>;
 	pinctrl-names = "default";
-	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
 	bus-width = <8>;
 };
 
-- 
1.7.9.5

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

* Re: [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support
  2015-01-14 10:30 ` Alim Akhtar
@ 2015-01-14 13:32   ` Jaehoon Chung
  -1 siblings, 0 replies; 24+ messages in thread
From: Jaehoon Chung @ 2015-01-14 13:32 UTC (permalink / raw)
  To: Alim Akhtar, linux-mmc
  Cc: devicetree, ulf.hansson, linux-samsung-soc, tgih.jun, chris,
	dianders, jh80.chung, kgene, a.kesavan, alim.akhtar,
	linux-arm-kernel

Hi, Alim.

On 01/14/2015 07:30 PM, Alim Akhtar wrote:
> This adds HS400 mode support for exynos dw_mmc host controller.
> 
> Currently tested on Exynos5800-peach-pi platform for HS400 mode.
> Tested HS200 mode with this series applied, HS200 still works.
> 
> Appreciate testing on other exynos5/7 platform which supports emmc5.0

I will test this patch on exynos5/7 board.

Best Regards,
Jaehoon Chung
> 
> Changes in V4:
> 	* drop the idea of changing existing binding for ciu_div as per [1]
>         * addressed comments from Jaehoon Chung [2]
> 
> [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html
> [2] http://www.spinics.net/lists/devicetree/msg64373.html
> 
> Changes in V3:
> 	rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static)
> 
> Seungwon Jeon (2):
>   mmc: dw_mmc: exynos: Support eMMC's HS400 mode
>   ARM: dts: Add HS400 support for exynos5420 and exynos5800
> 
>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
>  arch/arm/boot/dts/exynos5420-peach-pit.dts         |    4 +-
>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi          |    7 +
>  arch/arm/boot/dts/exynos5420-smdk5420.dts          |    4 +-
>  arch/arm/boot/dts/exynos5800-peach-pi.dts          |    4 +-
>  drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
>  drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
>  drivers/mmc/host/dw_mmc.c                          |   16 +-
>  drivers/mmc/host/dw_mmc.h                          |    2 +
>  9 files changed, 212 insertions(+), 38 deletions(-)
> 

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

* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support
@ 2015-01-14 13:32   ` Jaehoon Chung
  0 siblings, 0 replies; 24+ messages in thread
From: Jaehoon Chung @ 2015-01-14 13:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, Alim.

On 01/14/2015 07:30 PM, Alim Akhtar wrote:
> This adds HS400 mode support for exynos dw_mmc host controller.
> 
> Currently tested on Exynos5800-peach-pi platform for HS400 mode.
> Tested HS200 mode with this series applied, HS200 still works.
> 
> Appreciate testing on other exynos5/7 platform which supports emmc5.0

I will test this patch on exynos5/7 board.

Best Regards,
Jaehoon Chung
> 
> Changes in V4:
> 	* drop the idea of changing existing binding for ciu_div as per [1]
>         * addressed comments from Jaehoon Chung [2]
> 
> [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html
> [2] http://www.spinics.net/lists/devicetree/msg64373.html
> 
> Changes in V3:
> 	rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static)
> 
> Seungwon Jeon (2):
>   mmc: dw_mmc: exynos: Support eMMC's HS400 mode
>   ARM: dts: Add HS400 support for exynos5420 and exynos5800
> 
>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
>  arch/arm/boot/dts/exynos5420-peach-pit.dts         |    4 +-
>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi          |    7 +
>  arch/arm/boot/dts/exynos5420-smdk5420.dts          |    4 +-
>  arch/arm/boot/dts/exynos5800-peach-pi.dts          |    4 +-
>  drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
>  drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
>  drivers/mmc/host/dw_mmc.c                          |   16 +-
>  drivers/mmc/host/dw_mmc.h                          |    2 +
>  9 files changed, 212 insertions(+), 38 deletions(-)
> 

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

* Re: [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support
  2015-01-14 13:32   ` Jaehoon Chung
@ 2015-01-14 15:35     ` Kukjin Kim
  -1 siblings, 0 replies; 24+ messages in thread
From: Kukjin Kim @ 2015-01-14 15:35 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: Alim Akhtar, linux-mmc, devicetree, ulf.hansson,
	linux-samsung-soc, tgih.jun, chris, dianders, kgene, a.kesavan,
	alim.akhtar, linux-arm-kernel

On 01/14/15 22:32, Jaehoon Chung wrote:
> Hi, Alim.
> 
> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>> This adds HS400 mode support for exynos dw_mmc host controller.
>>
>> Currently tested on Exynos5800-peach-pi platform for HS400 mode.
>> Tested HS200 mode with this series applied, HS200 still works.
>>
>> Appreciate testing on other exynos5/7 platform which supports emmc5.0
> 
> I will test this patch on exynos5/7 board.
> 

What's the result? :-) If it's OK, I'll take DT changes for exynos
stuff, I'm not sure about the driver changes though...

Thanks,
Kukjin

> Best Regards,
> Jaehoon Chung
>>
>> Changes in V4:
>> 	* drop the idea of changing existing binding for ciu_div as per [1]
>>         * addressed comments from Jaehoon Chung [2]
>>
>> [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html
>> [2] http://www.spinics.net/lists/devicetree/msg64373.html
>>
>> Changes in V3:
>> 	rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static)
>>
>> Seungwon Jeon (2):
>>   mmc: dw_mmc: exynos: Support eMMC's HS400 mode
>>   ARM: dts: Add HS400 support for exynos5420 and exynos5800
>>
>>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
>>  arch/arm/boot/dts/exynos5420-peach-pit.dts         |    4 +-
>>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi          |    7 +
>>  arch/arm/boot/dts/exynos5420-smdk5420.dts          |    4 +-
>>  arch/arm/boot/dts/exynos5800-peach-pi.dts          |    4 +-
>>  drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
>>  drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
>>  drivers/mmc/host/dw_mmc.c                          |   16 +-
>>  drivers/mmc/host/dw_mmc.h                          |    2 +
>>  9 files changed, 212 insertions(+), 38 deletions(-)

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

* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support
@ 2015-01-14 15:35     ` Kukjin Kim
  0 siblings, 0 replies; 24+ messages in thread
From: Kukjin Kim @ 2015-01-14 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 01/14/15 22:32, Jaehoon Chung wrote:
> Hi, Alim.
> 
> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>> This adds HS400 mode support for exynos dw_mmc host controller.
>>
>> Currently tested on Exynos5800-peach-pi platform for HS400 mode.
>> Tested HS200 mode with this series applied, HS200 still works.
>>
>> Appreciate testing on other exynos5/7 platform which supports emmc5.0
> 
> I will test this patch on exynos5/7 board.
> 

What's the result? :-) If it's OK, I'll take DT changes for exynos
stuff, I'm not sure about the driver changes though...

Thanks,
Kukjin

> Best Regards,
> Jaehoon Chung
>>
>> Changes in V4:
>> 	* drop the idea of changing existing binding for ciu_div as per [1]
>>         * addressed comments from Jaehoon Chung [2]
>>
>> [1] http://www.spinics.net/lists/linux-samsung-soc/msg40923.html
>> [2] http://www.spinics.net/lists/devicetree/msg64373.html
>>
>> Changes in V3:
>> 	rebased on ulf's next (commit: 607b448 mmc: core: Make tuning block patterns static)
>>
>> Seungwon Jeon (2):
>>   mmc: dw_mmc: exynos: Support eMMC's HS400 mode
>>   ARM: dts: Add HS400 support for exynos5420 and exynos5800
>>
>>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
>>  arch/arm/boot/dts/exynos5420-peach-pit.dts         |    4 +-
>>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi          |    7 +
>>  arch/arm/boot/dts/exynos5420-smdk5420.dts          |    4 +-
>>  arch/arm/boot/dts/exynos5800-peach-pi.dts          |    4 +-
>>  drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
>>  drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
>>  drivers/mmc/host/dw_mmc.c                          |   16 +-
>>  drivers/mmc/host/dw_mmc.h                          |    2 +
>>  9 files changed, 212 insertions(+), 38 deletions(-)

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

* Re: [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support
  2015-01-14 15:35     ` Kukjin Kim
@ 2015-01-14 15:56       ` Ulf Hansson
  -1 siblings, 0 replies; 24+ messages in thread
From: Ulf Hansson @ 2015-01-14 15:56 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: Jaehoon Chung, Alim Akhtar, linux-mmc, devicetree,
	linux-samsung-soc, tgih.jun, Chris Ball, Doug Anderson,
	ABHILASH KESAVAN, Alim Akhtar, linux-arm-kernel

On 14 January 2015 at 16:35, Kukjin Kim <kgene@kernel.org> wrote:
> On 01/14/15 22:32, Jaehoon Chung wrote:
>> Hi, Alim.
>>
>> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>>> This adds HS400 mode support for exynos dw_mmc host controller.
>>>
>>> Currently tested on Exynos5800-peach-pi platform for HS400 mode.
>>> Tested HS200 mode with this series applied, HS200 still works.
>>>
>>> Appreciate testing on other exynos5/7 platform which supports emmc5.0
>>
>> I will test this patch on exynos5/7 board.
>>
>
> What's the result? :-) If it's OK, I'll take DT changes for exynos
> stuff, I'm not sure about the driver changes though...

Kukjin,

As I understand it, there is a dependency between the patches, since
driver adds supports for new DT bindings.

So, unless I am mistaken I think it would be best to take this
complete patchset through my mmc tree. With your ack of course.

Kind regards
Uffe

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

* [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support
@ 2015-01-14 15:56       ` Ulf Hansson
  0 siblings, 0 replies; 24+ messages in thread
From: Ulf Hansson @ 2015-01-14 15:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 14 January 2015 at 16:35, Kukjin Kim <kgene@kernel.org> wrote:
> On 01/14/15 22:32, Jaehoon Chung wrote:
>> Hi, Alim.
>>
>> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>>> This adds HS400 mode support for exynos dw_mmc host controller.
>>>
>>> Currently tested on Exynos5800-peach-pi platform for HS400 mode.
>>> Tested HS200 mode with this series applied, HS200 still works.
>>>
>>> Appreciate testing on other exynos5/7 platform which supports emmc5.0
>>
>> I will test this patch on exynos5/7 board.
>>
>
> What's the result? :-) If it's OK, I'll take DT changes for exynos
> stuff, I'm not sure about the driver changes though...

Kukjin,

As I understand it, there is a dependency between the patches, since
driver adds supports for new DT bindings.

So, unless I am mistaken I think it would be best to take this
complete patchset through my mmc tree. With your ack of course.

Kind regards
Uffe

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

* Re: [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode
  2015-01-14 10:30   ` Alim Akhtar
@ 2015-01-20 23:02     ` Jaehoon Chung
  -1 siblings, 0 replies; 24+ messages in thread
From: Jaehoon Chung @ 2015-01-20 23:02 UTC (permalink / raw)
  To: Alim Akhtar, linux-mmc
  Cc: chris, ulf.hansson, tgih.jun, dianders, alim.akhtar, kgene,
	linux-arm-kernel, devicetree, linux-samsung-soc, a.kesavan

Hi,

This patch can be separated.
When i tested on my board, it's not working fine.
I think it depends on my timing, so i will check after change the timing.

On 01/14/2015 07:30 PM, Alim Akhtar wrote:
> From: Seungwon Jeon <tgih.jun@samsung.com>
> 
> Implements HS400 mode support for exynos host driver.
> This also include some updates as new mode is added.
> 
> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> [Alim: addressed review comments]
> ---
>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
>  drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
>  drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
>  drivers/mmc/host/dw_mmc.c                          |   16 +-
>  drivers/mmc/host/dw_mmc.h                          |    2 +
>  5 files changed, 196 insertions(+), 35 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> index ee4fc05..dcab52c 100644
> --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> @@ -36,6 +36,8 @@ Required Properties:
>    in transmit mode and CIU clock phase shift value in receive mode for double
>    data rate mode operation. Refer notes below for the order of the cells and the
>    valid values.
> +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase
> +  shift value for hs400 mode operation.
>  
>    Notes for the sdr-timing and ddr-timing values:
>  
> @@ -50,6 +52,9 @@ Required Properties:
>        - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
>          phase shift clocks should be 0.
>  
> +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode
> +  (Latency value for delay line in Read path)
> +
>  Required properties for a slot (Deprecated - Recommend to use one slot per host):
>  
>  * gpios: specifies a list of gpios used for command, clock and data bus. The
> @@ -82,5 +87,7 @@ Example:
>  		samsung,dw-mshc-ciu-div = <3>;
>  		samsung,dw-mshc-sdr-timing = <2 3>;
>  		samsung,dw-mshc-ddr-timing = <1 2>;
> +		samsung,dw-mshc-hs400-timing = <0 2>;
> +		read-strobe-delay = <90>;

read-strobe-delay is exynos specific, isn't? 
read-strobe-delay -> samsung.read-strobe-delay.

>  		bus-width = <8>;
>  	};
> diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
> index 12a5eaa..172a2a8 100644
> --- a/drivers/mmc/host/dw_mmc-exynos.c
> +++ b/drivers/mmc/host/dw_mmc-exynos.c
> @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data {
>  	u8				ciu_div;
>  	u32				sdr_timing;
>  	u32				ddr_timing;
> +	u32				hs400_timing;
> +	u32				tuned_sample;
>  	u32				cur_speed;
> +	u32				dqs_delay;
> +	u32				saved_dqs_en;
> +	u32				saved_strobe_ctrl;
>  };
>  
>  static struct dw_mci_exynos_compatible {
> @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible {
>  	},
>  };
>  
> +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +
> +	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
> +		return EXYNOS4412_FIXED_CIU_CLK_DIV;
> +	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
> +		return EXYNOS4210_FIXED_CIU_CLK_DIV;
> +	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> +			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> +		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1;
> +	else
> +		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1;
> +}
> +
>  static int dw_mci_exynos_priv_init(struct dw_mci *host)
>  {
>  	struct dw_mci_exynos_priv_data *priv = host->priv;
> @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
>  			   SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT);
>  	}
>  
> +	if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) {
> +		priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL);
> +		priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN);
> +		priv->saved_dqs_en |= AXI_NON_BLOCKING_WR;
> +		mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en);
> +		if (!priv->dqs_delay)
> +			priv->dqs_delay =
> +				DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host)
>  {
>  	struct dw_mci_exynos_priv_data *priv = host->priv;
>  
> -	host->bus_hz /= (priv->ciu_div + 1);
> +	host->bus_hz /= priv->ciu_div;

Don't need to consider the case that priv->ciu_div set to 0?

>  
>  	return 0;
>  }
>  
> +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +	u32 clksel;
> +
> +	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> +		clksel = mci_readl(host, CLKSEL64);
> +	else
> +		clksel = mci_readl(host, CLKSEL);
> +
> +	clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing;
> +
> +	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> +		mci_writel(host, CLKSEL64, clksel);
> +	else
> +		mci_writel(host, CLKSEL, clksel);
> +}
> +
>  #ifdef CONFIG_PM_SLEEP
>  static int dw_mci_exynos_suspend(struct device *dev)
>  {
> @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
>  	}
>  }
>  
> -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing)
>  {
>  	struct dw_mci_exynos_priv_data *priv = host->priv;
> -	unsigned int wanted = ios->clock;
> -	unsigned long actual;
> -	u8 div = priv->ciu_div + 1;
> +	u32 dqs, strobe;
>  
> -	if (ios->timing == MMC_TIMING_MMC_DDR52) {
> -		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> -			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> -			mci_writel(host, CLKSEL64, priv->ddr_timing);
> -		else
> -			mci_writel(host, CLKSEL, priv->ddr_timing);
> -		/* Should be double rate for DDR mode */
> -		if (ios->bus_width == MMC_BUS_WIDTH_8)
> -			wanted <<= 1;
> +	/*
> +	 * Not suppported to configure register

Typo..supported

> +	 * related to HS400
> +	 */
> +	if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420)
> +		return;
> +
> +	dqs = priv->saved_dqs_en;
> +	strobe = priv->saved_strobe_ctrl;

priv->saved_dqs_en is set at init-time.
And you read the RDDQS_EN and HS400_DLINE_CTRL register at that time.
Doesn't it need to consider the changed value at those register?

priv->saved_xxx is reset value?

> +
> +	if (timing == MMC_TIMING_MMC_HS400) {
> +		dqs |= DATA_STROBE_EN;
> +		strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay);
>  	} else {
> -		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> -			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> -			mci_writel(host, CLKSEL64, priv->sdr_timing);
> -		else
> -			mci_writel(host, CLKSEL, priv->sdr_timing);
> +		dqs &= ~DATA_STROBE_EN;
>  	}
>  
> +	mci_writel(host, HS400_DQS_EN, dqs);
> +	mci_writel(host, HS400_DLINE_CTRL, strobe);
> +}
> +
> +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +	unsigned long actual;
> +	u8 div;
> +	int ret;
>  	/*
>  	 * Don't care if wanted clock is zero or
>  	 * ciu clock is unavailable
> @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>  	if (wanted < EXYNOS_CCLKIN_MIN)
>  		wanted = EXYNOS_CCLKIN_MIN;
>  
> -	if (wanted != priv->cur_speed) {
> -		int ret = clk_set_rate(host->ciu_clk, wanted * div);
> -		if (ret)
> -			dev_warn(host->dev,
> -				"failed to set clk-rate %u error: %d\n",
> -				 wanted * div, ret);
> -		actual = clk_get_rate(host->ciu_clk);
> -		host->bus_hz = actual / div;
> -		priv->cur_speed = wanted;
> -		host->current_speed = 0;
> +	if (wanted == priv->cur_speed)
> +		return;
> +
> +	div = dw_mci_exynos_get_ciu_div(host);
> +	ret = clk_set_rate(host->ciu_clk, wanted * div);
> +	if (ret)
> +		dev_warn(host->dev,
> +			"failed to set clk-rate %u error: %d\n",
> +			wanted * div, ret);
> +	actual = clk_get_rate(host->ciu_clk);
> +	host->bus_hz = actual / div;
> +	priv->cur_speed = wanted;
> +	host->current_speed = 0;
> +}
> +
> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +	unsigned int wanted = ios->clock;
> +	u32 timing = ios->timing, clksel;
> +
> +	switch (timing) {
> +	case MMC_TIMING_MMC_HS400:
> +		/* Update tuned sample timing */
> +		clksel = SDMMC_CLKSEL_UP_SAMPLE(
> +				priv->hs400_timing, priv->tuned_sample);
> +		wanted <<= 1;
> +		break;
> +	case MMC_TIMING_MMC_DDR52:
> +		clksel = priv->ddr_timing;
> +		/* Should be double rate for DDR mode */
> +		if (ios->bus_width == MMC_BUS_WIDTH_8)
> +			wanted <<= 1;
> +		break;
> +	default:
> +		clksel = priv->sdr_timing;
>  	}
> +
> +	/* Set clock timing for the requested speed mode*/
> +	dw_mci_exynos_set_clksel_timing(host, clksel);
> +
> +	/* Configure setting for HS400 */
> +	dw_mci_exynos_config_hs400(host, timing);
> +
> +	/* Configure clock rate */
> +	dw_mci_exynos_adjust_clock(host, wanted);
>  }
>  
>  static int dw_mci_exynos_parse_dt(struct dw_mci *host)
> @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host)
>  		return ret;
>  
>  	priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
> +
> +	ret = of_property_read_u32_array(np,
> +			"samsung,dw-mshc-hs400-timing", timing, 2);
> +	if (!ret && of_property_read_u32(np,
> +				"read-strobe-delay", &priv->dqs_delay))
> +		dev_info(host->dev,
> +			"read-strobe-delay is not found, assuming usage of default value\n");

Need the message?

> +
> +	priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1],
> +						HS400_FIXED_CIU_CLK_DIV);

Why useed the HS400_FIXED_CIU_CLK_DIV? always set to 1?

Best Regards,
Jaehoon Chung

>  	host->priv = priv;
>  	return 0;
>  }
> @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample)
>  		clksel = mci_readl(host, CLKSEL64);
>  	else
>  		clksel = mci_readl(host, CLKSEL);
> -	clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample);
> +	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
>  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>  		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>  		mci_writel(host, CLKSEL64, clksel);
> @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host)
>  		clksel = mci_readl(host, CLKSEL64);
>  	else
>  		clksel = mci_readl(host, CLKSEL);
> +
>  	sample = (clksel + 1) & 0x7;
> -	clksel = (clksel & ~0x7) | sample;
> +	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
> +
>  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>  		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>  		mci_writel(host, CLKSEL64, clksel);
>  	else
>  		mci_writel(host, CLKSEL, clksel);
> +
>  	return sample;
>  }
>  
> @@ -343,6 +449,7 @@ out:
>  static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
>  {
>  	struct dw_mci *host = slot->host;
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
>  	struct mmc_host *mmc = slot->mmc;
>  	u8 start_smpl, smpl, candiates = 0;
>  	s8 found = -1;
> @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
>  	} while (start_smpl != smpl);
>  
>  	found = dw_mci_exynos_get_best_clksmpl(candiates);
> -	if (found >= 0)
> +	if (found >= 0) {
>  		dw_mci_exynos_set_clksmpl(host, found);
> -	else
> +		priv->tuned_sample = found;
> +	} else {
>  		ret = -EIO;
> +	}
>  
>  	return ret;
>  }
>  
> +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host,
> +					struct mmc_ios *ios)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +
> +	dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing);
> +	dw_mci_exynos_adjust_clock(host, (ios->clock) << 1);
> +
> +	return 0;
> +}
> +
>  /* Common capabilities of Exynos4/Exynos5 SoC */
>  static unsigned long exynos_dwmmc_caps[4] = {
>  	MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
> @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = {
>  	.set_ios		= dw_mci_exynos_set_ios,
>  	.parse_dt		= dw_mci_exynos_parse_dt,
>  	.execute_tuning		= dw_mci_exynos_execute_tuning,
> +	.prepare_hs400_tuning	= dw_mci_exynos_prepare_hs400_tuning,
>  };
>  
>  static const struct of_device_id dw_mci_exynos_match[] = {
> diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h
> index 7872ce5..595c934 100644
> --- a/drivers/mmc/host/dw_mmc-exynos.h
> +++ b/drivers/mmc/host/dw_mmc-exynos.h
> @@ -12,20 +12,36 @@
>  #ifndef _DW_MMC_EXYNOS_H_
>  #define _DW_MMC_EXYNOS_H_
>  
> -/* Extended Register's Offset */
>  #define SDMMC_CLKSEL			0x09C
>  #define SDMMC_CLKSEL64			0x0A8
>  
> +/* Extended Register's Offset */
> +#define SDMMC_HS400_DQS_EN		0x180
> +#define SDMMC_HS400_ASYNC_FIFO_CTRL	0x184
> +#define SDMMC_HS400_DLINE_CTRL		0x188
> +
>  /* CLKSEL register defines */
>  #define SDMMC_CLKSEL_CCLK_SAMPLE(x)	(((x) & 7) << 0)
>  #define SDMMC_CLKSEL_CCLK_DRIVE(x)	(((x) & 7) << 16)
>  #define SDMMC_CLKSEL_CCLK_DIVIDER(x)	(((x) & 7) << 24)
>  #define SDMMC_CLKSEL_GET_DRV_WD3(x)	(((x) >> 16) & 0x7)
> +#define SDMMC_CLKSEL_GET_DIV(x)		(((x) >> 24) & 0x7)
> +#define SDMMC_CLKSEL_UP_SAMPLE(x, y)	(((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\
> +					 SDMMC_CLKSEL_CCLK_SAMPLE(y))
>  #define SDMMC_CLKSEL_TIMING(x, y, z)	(SDMMC_CLKSEL_CCLK_SAMPLE(x) |	\
>  					 SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
>  					 SDMMC_CLKSEL_CCLK_DIVIDER(z))
> +#define SDMMC_CLKSEL_TIMING_MASK	SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7)
>  #define SDMMC_CLKSEL_WAKEUP_INT		BIT(11)
>  
> +/* RCLK_EN register defines */
> +#define DATA_STROBE_EN			BIT(0)
> +#define AXI_NON_BLOCKING_WR	BIT(7)
> +
> +/* DLINE_CTRL register defines */
> +#define DQS_CTRL_RD_DELAY(x, y)		(((x) & ~0x3FF) | ((y) & 0x3FF))
> +#define DQS_CTRL_GET_RD_DELAY(x)	((x) & 0x3FF)
> +
>  /* Protector Register */
>  #define SDMMC_EMMCP_BASE	0x1000
>  #define SDMMC_MPSECURITY	(SDMMC_EMMCP_BASE + 0x0010)
> @@ -49,6 +65,7 @@
>  /* Fixed clock divider */
>  #define EXYNOS4210_FIXED_CIU_CLK_DIV	2
>  #define EXYNOS4412_FIXED_CIU_CLK_DIV	4
> +#define HS400_FIXED_CIU_CLK_DIV		1
>  
>  /* Minimal required clock frequency for cclkin, unit: HZ */
>  #define EXYNOS_CCLKIN_MIN	50000000
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 2e8abc8..43a3a5b 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  	regs = mci_readl(slot->host, UHS_REG);
>  
>  	/* DDR mode set */
> -	if (ios->timing == MMC_TIMING_MMC_DDR52)
> +	if (ios->timing == MMC_TIMING_MMC_DDR52 ||
> +	    ios->timing == MMC_TIMING_MMC_HS400)
>  		regs |= ((0x1 << slot->id) << 16);
>  	else
>  		regs &= ~((0x1 << slot->id) << 16);
> @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>  	return err;
>  }
>  
> +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> +	struct dw_mci_slot *slot = mmc_priv(mmc);
> +	struct dw_mci *host = slot->host;
> +	const struct dw_mci_drv_data *drv_data = host->drv_data;
> +
> +	if (drv_data && drv_data->prepare_hs400_tuning)
> +		return drv_data->prepare_hs400_tuning(host, ios);
> +
> +	return 0;
> +}
> +
>  static const struct mmc_host_ops dw_mci_ops = {
>  	.request		= dw_mci_request,
>  	.pre_req		= dw_mci_pre_req,
> @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = {
>  	.card_busy		= dw_mci_card_busy,
>  	.start_signal_voltage_switch = dw_mci_switch_voltage,
>  	.init_card		= dw_mci_init_card,
> +	.prepare_hs400_tuning	= dw_mci_prepare_hs400_tuning,
>  };
>  
>  static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 18c4afe..d239867 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -271,5 +271,7 @@ struct dw_mci_drv_data {
>  	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
>  	int		(*parse_dt)(struct dw_mci *host);
>  	int		(*execute_tuning)(struct dw_mci_slot *slot);
> +	int		(*prepare_hs400_tuning)(struct dw_mci *host,
> +						struct mmc_ios *ios);
>  };
>  #endif /* _DW_MMC_H_ */
> 

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

* [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode
@ 2015-01-20 23:02     ` Jaehoon Chung
  0 siblings, 0 replies; 24+ messages in thread
From: Jaehoon Chung @ 2015-01-20 23:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This patch can be separated.
When i tested on my board, it's not working fine.
I think it depends on my timing, so i will check after change the timing.

On 01/14/2015 07:30 PM, Alim Akhtar wrote:
> From: Seungwon Jeon <tgih.jun@samsung.com>
> 
> Implements HS400 mode support for exynos host driver.
> This also include some updates as new mode is added.
> 
> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> [Alim: addressed review comments]
> ---
>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
>  drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
>  drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
>  drivers/mmc/host/dw_mmc.c                          |   16 +-
>  drivers/mmc/host/dw_mmc.h                          |    2 +
>  5 files changed, 196 insertions(+), 35 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> index ee4fc05..dcab52c 100644
> --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
> @@ -36,6 +36,8 @@ Required Properties:
>    in transmit mode and CIU clock phase shift value in receive mode for double
>    data rate mode operation. Refer notes below for the order of the cells and the
>    valid values.
> +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase
> +  shift value for hs400 mode operation.
>  
>    Notes for the sdr-timing and ddr-timing values:
>  
> @@ -50,6 +52,9 @@ Required Properties:
>        - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
>          phase shift clocks should be 0.
>  
> +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode
> +  (Latency value for delay line in Read path)
> +
>  Required properties for a slot (Deprecated - Recommend to use one slot per host):
>  
>  * gpios: specifies a list of gpios used for command, clock and data bus. The
> @@ -82,5 +87,7 @@ Example:
>  		samsung,dw-mshc-ciu-div = <3>;
>  		samsung,dw-mshc-sdr-timing = <2 3>;
>  		samsung,dw-mshc-ddr-timing = <1 2>;
> +		samsung,dw-mshc-hs400-timing = <0 2>;
> +		read-strobe-delay = <90>;

read-strobe-delay is exynos specific, isn't? 
read-strobe-delay -> samsung.read-strobe-delay.

>  		bus-width = <8>;
>  	};
> diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
> index 12a5eaa..172a2a8 100644
> --- a/drivers/mmc/host/dw_mmc-exynos.c
> +++ b/drivers/mmc/host/dw_mmc-exynos.c
> @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data {
>  	u8				ciu_div;
>  	u32				sdr_timing;
>  	u32				ddr_timing;
> +	u32				hs400_timing;
> +	u32				tuned_sample;
>  	u32				cur_speed;
> +	u32				dqs_delay;
> +	u32				saved_dqs_en;
> +	u32				saved_strobe_ctrl;
>  };
>  
>  static struct dw_mci_exynos_compatible {
> @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible {
>  	},
>  };
>  
> +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +
> +	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
> +		return EXYNOS4412_FIXED_CIU_CLK_DIV;
> +	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
> +		return EXYNOS4210_FIXED_CIU_CLK_DIV;
> +	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> +			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> +		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1;
> +	else
> +		return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1;
> +}
> +
>  static int dw_mci_exynos_priv_init(struct dw_mci *host)
>  {
>  	struct dw_mci_exynos_priv_data *priv = host->priv;
> @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
>  			   SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT);
>  	}
>  
> +	if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) {
> +		priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL);
> +		priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN);
> +		priv->saved_dqs_en |= AXI_NON_BLOCKING_WR;
> +		mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en);
> +		if (!priv->dqs_delay)
> +			priv->dqs_delay =
> +				DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl);
> +	}
> +
>  	return 0;
>  }
>  
> @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host)
>  {
>  	struct dw_mci_exynos_priv_data *priv = host->priv;
>  
> -	host->bus_hz /= (priv->ciu_div + 1);
> +	host->bus_hz /= priv->ciu_div;

Don't need to consider the case that priv->ciu_div set to 0?

>  
>  	return 0;
>  }
>  
> +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +	u32 clksel;
> +
> +	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> +		clksel = mci_readl(host, CLKSEL64);
> +	else
> +		clksel = mci_readl(host, CLKSEL);
> +
> +	clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing;
> +
> +	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> +		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> +		mci_writel(host, CLKSEL64, clksel);
> +	else
> +		mci_writel(host, CLKSEL, clksel);
> +}
> +
>  #ifdef CONFIG_PM_SLEEP
>  static int dw_mci_exynos_suspend(struct device *dev)
>  {
> @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
>  	}
>  }
>  
> -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing)
>  {
>  	struct dw_mci_exynos_priv_data *priv = host->priv;
> -	unsigned int wanted = ios->clock;
> -	unsigned long actual;
> -	u8 div = priv->ciu_div + 1;
> +	u32 dqs, strobe;
>  
> -	if (ios->timing == MMC_TIMING_MMC_DDR52) {
> -		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> -			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> -			mci_writel(host, CLKSEL64, priv->ddr_timing);
> -		else
> -			mci_writel(host, CLKSEL, priv->ddr_timing);
> -		/* Should be double rate for DDR mode */
> -		if (ios->bus_width == MMC_BUS_WIDTH_8)
> -			wanted <<= 1;
> +	/*
> +	 * Not suppported to configure register

Typo..supported

> +	 * related to HS400
> +	 */
> +	if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420)
> +		return;
> +
> +	dqs = priv->saved_dqs_en;
> +	strobe = priv->saved_strobe_ctrl;

priv->saved_dqs_en is set at init-time.
And you read the RDDQS_EN and HS400_DLINE_CTRL register at that time.
Doesn't it need to consider the changed value at those register?

priv->saved_xxx is reset value?

> +
> +	if (timing == MMC_TIMING_MMC_HS400) {
> +		dqs |= DATA_STROBE_EN;
> +		strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay);
>  	} else {
> -		if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
> -			priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
> -			mci_writel(host, CLKSEL64, priv->sdr_timing);
> -		else
> -			mci_writel(host, CLKSEL, priv->sdr_timing);
> +		dqs &= ~DATA_STROBE_EN;
>  	}
>  
> +	mci_writel(host, HS400_DQS_EN, dqs);
> +	mci_writel(host, HS400_DLINE_CTRL, strobe);
> +}
> +
> +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +	unsigned long actual;
> +	u8 div;
> +	int ret;
>  	/*
>  	 * Don't care if wanted clock is zero or
>  	 * ciu clock is unavailable
> @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>  	if (wanted < EXYNOS_CCLKIN_MIN)
>  		wanted = EXYNOS_CCLKIN_MIN;
>  
> -	if (wanted != priv->cur_speed) {
> -		int ret = clk_set_rate(host->ciu_clk, wanted * div);
> -		if (ret)
> -			dev_warn(host->dev,
> -				"failed to set clk-rate %u error: %d\n",
> -				 wanted * div, ret);
> -		actual = clk_get_rate(host->ciu_clk);
> -		host->bus_hz = actual / div;
> -		priv->cur_speed = wanted;
> -		host->current_speed = 0;
> +	if (wanted == priv->cur_speed)
> +		return;
> +
> +	div = dw_mci_exynos_get_ciu_div(host);
> +	ret = clk_set_rate(host->ciu_clk, wanted * div);
> +	if (ret)
> +		dev_warn(host->dev,
> +			"failed to set clk-rate %u error: %d\n",
> +			wanted * div, ret);
> +	actual = clk_get_rate(host->ciu_clk);
> +	host->bus_hz = actual / div;
> +	priv->cur_speed = wanted;
> +	host->current_speed = 0;
> +}
> +
> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +	unsigned int wanted = ios->clock;
> +	u32 timing = ios->timing, clksel;
> +
> +	switch (timing) {
> +	case MMC_TIMING_MMC_HS400:
> +		/* Update tuned sample timing */
> +		clksel = SDMMC_CLKSEL_UP_SAMPLE(
> +				priv->hs400_timing, priv->tuned_sample);
> +		wanted <<= 1;
> +		break;
> +	case MMC_TIMING_MMC_DDR52:
> +		clksel = priv->ddr_timing;
> +		/* Should be double rate for DDR mode */
> +		if (ios->bus_width == MMC_BUS_WIDTH_8)
> +			wanted <<= 1;
> +		break;
> +	default:
> +		clksel = priv->sdr_timing;
>  	}
> +
> +	/* Set clock timing for the requested speed mode*/
> +	dw_mci_exynos_set_clksel_timing(host, clksel);
> +
> +	/* Configure setting for HS400 */
> +	dw_mci_exynos_config_hs400(host, timing);
> +
> +	/* Configure clock rate */
> +	dw_mci_exynos_adjust_clock(host, wanted);
>  }
>  
>  static int dw_mci_exynos_parse_dt(struct dw_mci *host)
> @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host)
>  		return ret;
>  
>  	priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
> +
> +	ret = of_property_read_u32_array(np,
> +			"samsung,dw-mshc-hs400-timing", timing, 2);
> +	if (!ret && of_property_read_u32(np,
> +				"read-strobe-delay", &priv->dqs_delay))
> +		dev_info(host->dev,
> +			"read-strobe-delay is not found, assuming usage of default value\n");

Need the message?

> +
> +	priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1],
> +						HS400_FIXED_CIU_CLK_DIV);

Why useed the HS400_FIXED_CIU_CLK_DIV? always set to 1?

Best Regards,
Jaehoon Chung

>  	host->priv = priv;
>  	return 0;
>  }
> @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample)
>  		clksel = mci_readl(host, CLKSEL64);
>  	else
>  		clksel = mci_readl(host, CLKSEL);
> -	clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample);
> +	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
>  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>  		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>  		mci_writel(host, CLKSEL64, clksel);
> @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host)
>  		clksel = mci_readl(host, CLKSEL64);
>  	else
>  		clksel = mci_readl(host, CLKSEL);
> +
>  	sample = (clksel + 1) & 0x7;
> -	clksel = (clksel & ~0x7) | sample;
> +	clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
> +
>  	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>  		priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>  		mci_writel(host, CLKSEL64, clksel);
>  	else
>  		mci_writel(host, CLKSEL, clksel);
> +
>  	return sample;
>  }
>  
> @@ -343,6 +449,7 @@ out:
>  static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
>  {
>  	struct dw_mci *host = slot->host;
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
>  	struct mmc_host *mmc = slot->mmc;
>  	u8 start_smpl, smpl, candiates = 0;
>  	s8 found = -1;
> @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
>  	} while (start_smpl != smpl);
>  
>  	found = dw_mci_exynos_get_best_clksmpl(candiates);
> -	if (found >= 0)
> +	if (found >= 0) {
>  		dw_mci_exynos_set_clksmpl(host, found);
> -	else
> +		priv->tuned_sample = found;
> +	} else {
>  		ret = -EIO;
> +	}
>  
>  	return ret;
>  }
>  
> +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host,
> +					struct mmc_ios *ios)
> +{
> +	struct dw_mci_exynos_priv_data *priv = host->priv;
> +
> +	dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing);
> +	dw_mci_exynos_adjust_clock(host, (ios->clock) << 1);
> +
> +	return 0;
> +}
> +
>  /* Common capabilities of Exynos4/Exynos5 SoC */
>  static unsigned long exynos_dwmmc_caps[4] = {
>  	MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
> @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = {
>  	.set_ios		= dw_mci_exynos_set_ios,
>  	.parse_dt		= dw_mci_exynos_parse_dt,
>  	.execute_tuning		= dw_mci_exynos_execute_tuning,
> +	.prepare_hs400_tuning	= dw_mci_exynos_prepare_hs400_tuning,
>  };
>  
>  static const struct of_device_id dw_mci_exynos_match[] = {
> diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h
> index 7872ce5..595c934 100644
> --- a/drivers/mmc/host/dw_mmc-exynos.h
> +++ b/drivers/mmc/host/dw_mmc-exynos.h
> @@ -12,20 +12,36 @@
>  #ifndef _DW_MMC_EXYNOS_H_
>  #define _DW_MMC_EXYNOS_H_
>  
> -/* Extended Register's Offset */
>  #define SDMMC_CLKSEL			0x09C
>  #define SDMMC_CLKSEL64			0x0A8
>  
> +/* Extended Register's Offset */
> +#define SDMMC_HS400_DQS_EN		0x180
> +#define SDMMC_HS400_ASYNC_FIFO_CTRL	0x184
> +#define SDMMC_HS400_DLINE_CTRL		0x188
> +
>  /* CLKSEL register defines */
>  #define SDMMC_CLKSEL_CCLK_SAMPLE(x)	(((x) & 7) << 0)
>  #define SDMMC_CLKSEL_CCLK_DRIVE(x)	(((x) & 7) << 16)
>  #define SDMMC_CLKSEL_CCLK_DIVIDER(x)	(((x) & 7) << 24)
>  #define SDMMC_CLKSEL_GET_DRV_WD3(x)	(((x) >> 16) & 0x7)
> +#define SDMMC_CLKSEL_GET_DIV(x)		(((x) >> 24) & 0x7)
> +#define SDMMC_CLKSEL_UP_SAMPLE(x, y)	(((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\
> +					 SDMMC_CLKSEL_CCLK_SAMPLE(y))
>  #define SDMMC_CLKSEL_TIMING(x, y, z)	(SDMMC_CLKSEL_CCLK_SAMPLE(x) |	\
>  					 SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
>  					 SDMMC_CLKSEL_CCLK_DIVIDER(z))
> +#define SDMMC_CLKSEL_TIMING_MASK	SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7)
>  #define SDMMC_CLKSEL_WAKEUP_INT		BIT(11)
>  
> +/* RCLK_EN register defines */
> +#define DATA_STROBE_EN			BIT(0)
> +#define AXI_NON_BLOCKING_WR	BIT(7)
> +
> +/* DLINE_CTRL register defines */
> +#define DQS_CTRL_RD_DELAY(x, y)		(((x) & ~0x3FF) | ((y) & 0x3FF))
> +#define DQS_CTRL_GET_RD_DELAY(x)	((x) & 0x3FF)
> +
>  /* Protector Register */
>  #define SDMMC_EMMCP_BASE	0x1000
>  #define SDMMC_MPSECURITY	(SDMMC_EMMCP_BASE + 0x0010)
> @@ -49,6 +65,7 @@
>  /* Fixed clock divider */
>  #define EXYNOS4210_FIXED_CIU_CLK_DIV	2
>  #define EXYNOS4412_FIXED_CIU_CLK_DIV	4
> +#define HS400_FIXED_CIU_CLK_DIV		1
>  
>  /* Minimal required clock frequency for cclkin, unit: HZ */
>  #define EXYNOS_CCLKIN_MIN	50000000
> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
> index 2e8abc8..43a3a5b 100644
> --- a/drivers/mmc/host/dw_mmc.c
> +++ b/drivers/mmc/host/dw_mmc.c
> @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>  	regs = mci_readl(slot->host, UHS_REG);
>  
>  	/* DDR mode set */
> -	if (ios->timing == MMC_TIMING_MMC_DDR52)
> +	if (ios->timing == MMC_TIMING_MMC_DDR52 ||
> +	    ios->timing == MMC_TIMING_MMC_HS400)
>  		regs |= ((0x1 << slot->id) << 16);
>  	else
>  		regs &= ~((0x1 << slot->id) << 16);
> @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>  	return err;
>  }
>  
> +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> +	struct dw_mci_slot *slot = mmc_priv(mmc);
> +	struct dw_mci *host = slot->host;
> +	const struct dw_mci_drv_data *drv_data = host->drv_data;
> +
> +	if (drv_data && drv_data->prepare_hs400_tuning)
> +		return drv_data->prepare_hs400_tuning(host, ios);
> +
> +	return 0;
> +}
> +
>  static const struct mmc_host_ops dw_mci_ops = {
>  	.request		= dw_mci_request,
>  	.pre_req		= dw_mci_pre_req,
> @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = {
>  	.card_busy		= dw_mci_card_busy,
>  	.start_signal_voltage_switch = dw_mci_switch_voltage,
>  	.init_card		= dw_mci_init_card,
> +	.prepare_hs400_tuning	= dw_mci_prepare_hs400_tuning,
>  };
>  
>  static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
> index 18c4afe..d239867 100644
> --- a/drivers/mmc/host/dw_mmc.h
> +++ b/drivers/mmc/host/dw_mmc.h
> @@ -271,5 +271,7 @@ struct dw_mci_drv_data {
>  	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
>  	int		(*parse_dt)(struct dw_mci *host);
>  	int		(*execute_tuning)(struct dw_mci_slot *slot);
> +	int		(*prepare_hs400_tuning)(struct dw_mci *host,
> +						struct mmc_ios *ios);
>  };
>  #endif /* _DW_MMC_H_ */
> 

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

* Re: [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
  2015-01-14 10:30   ` Alim Akhtar
@ 2015-01-20 23:02       ` Jaehoon Chung
  -1 siblings, 0 replies; 24+ messages in thread
From: Jaehoon Chung @ 2015-01-20 23:02 UTC (permalink / raw)
  To: Alim Akhtar, linux-mmc-u79uwXL29TY76Z2rM5mHXA
  Cc: chris-OsFVWbfNK3isTnJN9+BGXg, ulf.hansson-QSEj5FYQhm4dnm+yROfE0A,
	tgih.jun-Sze3O3UU22JBDgjK7y7TUQ, dianders-F7+t8E8rja9g9hUCZPvPmw,
	alim.akhtar-Re5JQEeQqe8AvxtiuMwx3w, kgene-DgEjT+Ai2ygdnm+yROfE0A,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
	a.kesavan-Sze3O3UU22JBDgjK7y7TUQ

Hi,

If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v".
But this patch didn't add them. do you have any other plan?

On 01/14/2015 07:30 PM, Alim Akhtar wrote:
> From: Seungwon Jeon <tgih.jun-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> 
> HS400 timing values are added for SMDK5420, exynos5420-peach-pit
> and exynos5800-peach-pi boards.
> This also adds RCLK GPIO line, this gpio should be in pull-down
> state.
> 
> Signed-off-by: Seungwon Jeon <tgih.jun-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Alim Akhtar <alim.akhtar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> [Alim: addressed review comments]
> ---
>  arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
>  arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
>  arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
>  4 files changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> index 9a050e1..7ffaba8 100644
> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> @@ -569,8 +569,10 @@
>  	samsung,dw-mshc-ciu-div = <3>;
>  	samsung,dw-mshc-sdr-timing = <0 4>;
>  	samsung,dw-mshc-ddr-timing = <0 2>;
> +	samsung,dw-mshc-hs400-timing = <0 2>;
> +	read-strobe-delay = <90>;
>  	pinctrl-names = "default";
> -	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
> +	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>  	bus-width = <8>;
>  };
>  
> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
> index ba686e4..8b15316 100644
> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
> @@ -201,6 +201,13 @@
>  			samsung,pin-drv = <3>;
>  		};
>  
> +		sd0_rclk: sd0-rclk {

I know it used to "sd0_rdqs", not "sd0_rclk".
Change name.

Best Regards,
Jaehoon Chung
> +			samsung,pins = "gpc0-7";
> +			samsung,pin-function = <2>;
> +			samsung,pin-pud = <1>;
> +			samsung,pin-drv = <3>;
> +		};
> +
>  		sd1_cmd: sd1-cmd {
>  			samsung,pins = "gpc1-1";
>  			samsung,pin-function = <2>;
> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
> index 8be3d7b..5290e79 100644
> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
> @@ -80,8 +80,10 @@
>  		samsung,dw-mshc-ciu-div = <3>;
>  		samsung,dw-mshc-sdr-timing = <0 4>;
>  		samsung,dw-mshc-ddr-timing = <0 2>;
> +		samsung,dw-mshc-hs400-timing = <0 2>;
> +		read-strobe-delay = <90>;
>  		pinctrl-names = "default";
> -		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
> +		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>  		bus-width = <8>;
>  		cap-mmc-highspeed;
>  	};
> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> index e8fdda8..fa1c858 100644
> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> @@ -557,8 +557,10 @@
>  	samsung,dw-mshc-ciu-div = <3>;
>  	samsung,dw-mshc-sdr-timing = <0 4>;
>  	samsung,dw-mshc-ddr-timing = <0 2>;
> +	samsung,dw-mshc-hs400-timing = <0 2>;
> +	read-strobe-delay = <90>;
>  	pinctrl-names = "default";
> -	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
> +	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>  	bus-width = <8>;
>  };
>  
> 

--
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] 24+ messages in thread

* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
@ 2015-01-20 23:02       ` Jaehoon Chung
  0 siblings, 0 replies; 24+ messages in thread
From: Jaehoon Chung @ 2015-01-20 23:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v".
But this patch didn't add them. do you have any other plan?

On 01/14/2015 07:30 PM, Alim Akhtar wrote:
> From: Seungwon Jeon <tgih.jun@samsung.com>
> 
> HS400 timing values are added for SMDK5420, exynos5420-peach-pit
> and exynos5800-peach-pi boards.
> This also adds RCLK GPIO line, this gpio should be in pull-down
> state.
> 
> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
> [Alim: addressed review comments]
> ---
>  arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
>  arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
>  arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
>  4 files changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> index 9a050e1..7ffaba8 100644
> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> @@ -569,8 +569,10 @@
>  	samsung,dw-mshc-ciu-div = <3>;
>  	samsung,dw-mshc-sdr-timing = <0 4>;
>  	samsung,dw-mshc-ddr-timing = <0 2>;
> +	samsung,dw-mshc-hs400-timing = <0 2>;
> +	read-strobe-delay = <90>;
>  	pinctrl-names = "default";
> -	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
> +	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>  	bus-width = <8>;
>  };
>  
> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
> index ba686e4..8b15316 100644
> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
> @@ -201,6 +201,13 @@
>  			samsung,pin-drv = <3>;
>  		};
>  
> +		sd0_rclk: sd0-rclk {

I know it used to "sd0_rdqs", not "sd0_rclk".
Change name.

Best Regards,
Jaehoon Chung
> +			samsung,pins = "gpc0-7";
> +			samsung,pin-function = <2>;
> +			samsung,pin-pud = <1>;
> +			samsung,pin-drv = <3>;
> +		};
> +
>  		sd1_cmd: sd1-cmd {
>  			samsung,pins = "gpc1-1";
>  			samsung,pin-function = <2>;
> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
> index 8be3d7b..5290e79 100644
> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
> @@ -80,8 +80,10 @@
>  		samsung,dw-mshc-ciu-div = <3>;
>  		samsung,dw-mshc-sdr-timing = <0 4>;
>  		samsung,dw-mshc-ddr-timing = <0 2>;
> +		samsung,dw-mshc-hs400-timing = <0 2>;
> +		read-strobe-delay = <90>;
>  		pinctrl-names = "default";
> -		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
> +		pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>  		bus-width = <8>;
>  		cap-mmc-highspeed;
>  	};
> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> index e8fdda8..fa1c858 100644
> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> @@ -557,8 +557,10 @@
>  	samsung,dw-mshc-ciu-div = <3>;
>  	samsung,dw-mshc-sdr-timing = <0 4>;
>  	samsung,dw-mshc-ddr-timing = <0 2>;
> +	samsung,dw-mshc-hs400-timing = <0 2>;
> +	read-strobe-delay = <90>;
>  	pinctrl-names = "default";
> -	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
> +	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>  	bus-width = <8>;
>  };
>  
> 

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

* Re: [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
  2015-01-20 23:02       ` Jaehoon Chung
@ 2015-01-21 14:12         ` Alim Akhtar
  -1 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-21 14:12 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: Alim Akhtar, linux-mmc, Chris Ball, Ulf Hansson, Seungwon Jeon,
	Douglas Anderson, kgene, linux-arm-kernel, devicetree,
	linux-samsung-soc, Abhilash Kesavan

Hi Jaehoon

On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi,
>
> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v".
> But this patch didn't add them. do you have any other plan?
>
Yes, right, plan is to send separate patch to enable hs400, as of now
I am not sure if all the 5800-peach-pi boards are populated with
emmc5.0 device or not. So I will enable HS400 after confirming this
point.
> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>> From: Seungwon Jeon <tgih.jun@samsung.com>
>>
>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit
>> and exynos5800-peach-pi boards.
>> This also adds RCLK GPIO line, this gpio should be in pull-down
>> state.
>>
>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>> [Alim: addressed review comments]
>> ---
>>  arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
>>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
>>  arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
>>  arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
>>  4 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> index 9a050e1..7ffaba8 100644
>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> @@ -569,8 +569,10 @@
>>       samsung,dw-mshc-ciu-div = <3>;
>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>       samsung,dw-mshc-ddr-timing = <0 2>;
>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>> +     read-strobe-delay = <90>;
>>       pinctrl-names = "default";
>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>       bus-width = <8>;
>>  };
>>
>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>> index ba686e4..8b15316 100644
>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>> @@ -201,6 +201,13 @@
>>                       samsung,pin-drv = <3>;
>>               };
>>
>> +             sd0_rclk: sd0-rclk {
>
> I know it used to "sd0_rdqs", not "sd0_rclk".
> Change name.
>
Ok, I will change as per UM of 5800/5420,

> Best Regards,
> Jaehoon Chung
>> +                     samsung,pins = "gpc0-7";
>> +                     samsung,pin-function = <2>;
>> +                     samsung,pin-pud = <1>;
>> +                     samsung,pin-drv = <3>;
>> +             };
>> +
>>               sd1_cmd: sd1-cmd {
>>                       samsung,pins = "gpc1-1";
>>                       samsung,pin-function = <2>;
>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> index 8be3d7b..5290e79 100644
>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> @@ -80,8 +80,10 @@
>>               samsung,dw-mshc-ciu-div = <3>;
>>               samsung,dw-mshc-sdr-timing = <0 4>;
>>               samsung,dw-mshc-ddr-timing = <0 2>;
>> +             samsung,dw-mshc-hs400-timing = <0 2>;
>> +             read-strobe-delay = <90>;
>>               pinctrl-names = "default";
>> -             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>> +             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>               bus-width = <8>;
>>               cap-mmc-highspeed;
>>       };
>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> index e8fdda8..fa1c858 100644
>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> @@ -557,8 +557,10 @@
>>       samsung,dw-mshc-ciu-div = <3>;
>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>       samsung,dw-mshc-ddr-timing = <0 2>;
>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>> +     read-strobe-delay = <90>;
>>       pinctrl-names = "default";
>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>       bus-width = <8>;
>>  };
>>
>>
>



-- 
Regards,
Alim

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

* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
@ 2015-01-21 14:12         ` Alim Akhtar
  0 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-21 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jaehoon

On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi,
>
> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v".
> But this patch didn't add them. do you have any other plan?
>
Yes, right, plan is to send separate patch to enable hs400, as of now
I am not sure if all the 5800-peach-pi boards are populated with
emmc5.0 device or not. So I will enable HS400 after confirming this
point.
> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>> From: Seungwon Jeon <tgih.jun@samsung.com>
>>
>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit
>> and exynos5800-peach-pi boards.
>> This also adds RCLK GPIO line, this gpio should be in pull-down
>> state.
>>
>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>> [Alim: addressed review comments]
>> ---
>>  arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
>>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
>>  arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
>>  arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
>>  4 files changed, 16 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> index 9a050e1..7ffaba8 100644
>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>> @@ -569,8 +569,10 @@
>>       samsung,dw-mshc-ciu-div = <3>;
>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>       samsung,dw-mshc-ddr-timing = <0 2>;
>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>> +     read-strobe-delay = <90>;
>>       pinctrl-names = "default";
>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>       bus-width = <8>;
>>  };
>>
>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>> index ba686e4..8b15316 100644
>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>> @@ -201,6 +201,13 @@
>>                       samsung,pin-drv = <3>;
>>               };
>>
>> +             sd0_rclk: sd0-rclk {
>
> I know it used to "sd0_rdqs", not "sd0_rclk".
> Change name.
>
Ok, I will change as per UM of 5800/5420,

> Best Regards,
> Jaehoon Chung
>> +                     samsung,pins = "gpc0-7";
>> +                     samsung,pin-function = <2>;
>> +                     samsung,pin-pud = <1>;
>> +                     samsung,pin-drv = <3>;
>> +             };
>> +
>>               sd1_cmd: sd1-cmd {
>>                       samsung,pins = "gpc1-1";
>>                       samsung,pin-function = <2>;
>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> index 8be3d7b..5290e79 100644
>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>> @@ -80,8 +80,10 @@
>>               samsung,dw-mshc-ciu-div = <3>;
>>               samsung,dw-mshc-sdr-timing = <0 4>;
>>               samsung,dw-mshc-ddr-timing = <0 2>;
>> +             samsung,dw-mshc-hs400-timing = <0 2>;
>> +             read-strobe-delay = <90>;
>>               pinctrl-names = "default";
>> -             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>> +             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>               bus-width = <8>;
>>               cap-mmc-highspeed;
>>       };
>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> index e8fdda8..fa1c858 100644
>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> @@ -557,8 +557,10 @@
>>       samsung,dw-mshc-ciu-div = <3>;
>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>       samsung,dw-mshc-ddr-timing = <0 2>;
>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>> +     read-strobe-delay = <90>;
>>       pinctrl-names = "default";
>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>       bus-width = <8>;
>>  };
>>
>>
>



-- 
Regards,
Alim

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

* Re: [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode
  2015-01-20 23:02     ` Jaehoon Chung
@ 2015-01-21 23:42       ` Alim Akhtar
  -1 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-21 23:42 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: Alim Akhtar, linux-mmc, Chris Ball, Ulf Hansson, Seungwon Jeon,
	Douglas Anderson, kgene, linux-arm-kernel, devicetree,
	linux-samsung-soc, Abhilash Kesavan

Hi Jaehoon

On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi,
>
> This patch can be separated.
> When i tested on my board, it's not working fine.
> I think it depends on my timing, so i will check after change the timing.
>
> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>> From: Seungwon Jeon <tgih.jun@samsung.com>
>>
>> Implements HS400 mode support for exynos host driver.
>> This also include some updates as new mode is added.
>>
>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>> [Alim: addressed review comments]
>> ---
>>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
>>  drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
>>  drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
>>  drivers/mmc/host/dw_mmc.c                          |   16 +-
>>  drivers/mmc/host/dw_mmc.h                          |    2 +
>>  5 files changed, 196 insertions(+), 35 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
>> index ee4fc05..dcab52c 100644
>> --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
>> +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
>> @@ -36,6 +36,8 @@ Required Properties:
>>    in transmit mode and CIU clock phase shift value in receive mode for double
>>    data rate mode operation. Refer notes below for the order of the cells and the
>>    valid values.
>> +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase
>> +  shift value for hs400 mode operation.
>>
>>    Notes for the sdr-timing and ddr-timing values:
>>
>> @@ -50,6 +52,9 @@ Required Properties:
>>        - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
>>          phase shift clocks should be 0.
>>
>> +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode
>> +  (Latency value for delay line in Read path)
>> +
>>  Required properties for a slot (Deprecated - Recommend to use one slot per host):
>>
>>  * gpios: specifies a list of gpios used for command, clock and data bus. The
>> @@ -82,5 +87,7 @@ Example:
>>               samsung,dw-mshc-ciu-div = <3>;
>>               samsung,dw-mshc-sdr-timing = <2 3>;
>>               samsung,dw-mshc-ddr-timing = <1 2>;
>> +             samsung,dw-mshc-hs400-timing = <0 2>;
>> +             read-strobe-delay = <90>;
>
> read-strobe-delay is exynos specific, isn't?
> read-strobe-delay -> samsung.read-strobe-delay.
>
read-strobe are as per hs400 spec, ok I will change this to match the
naming with other properties.
>>               bus-width = <8>;
>>       };
>> diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
>> index 12a5eaa..172a2a8 100644
>> --- a/drivers/mmc/host/dw_mmc-exynos.c
>> +++ b/drivers/mmc/host/dw_mmc-exynos.c
>> @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data {
>>       u8                              ciu_div;
>>       u32                             sdr_timing;
>>       u32                             ddr_timing;
>> +     u32                             hs400_timing;
>> +     u32                             tuned_sample;
>>       u32                             cur_speed;
>> +     u32                             dqs_delay;
>> +     u32                             saved_dqs_en;
>> +     u32                             saved_strobe_ctrl;
>>  };
>>
>>  static struct dw_mci_exynos_compatible {
>> @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible {
>>       },
>>  };
>>
>> +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +
>> +     if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
>> +             return EXYNOS4412_FIXED_CIU_CLK_DIV;
>> +     else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
>> +             return EXYNOS4210_FIXED_CIU_CLK_DIV;
>> +     else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> +                     priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> +             return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1;
>> +     else
>> +             return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1;
>> +}
>> +
>>  static int dw_mci_exynos_priv_init(struct dw_mci *host)
>>  {
>>       struct dw_mci_exynos_priv_data *priv = host->priv;
>> @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
>>                          SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT);
>>       }
>>
>> +     if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) {
>> +             priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL);
>> +             priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN);
>> +             priv->saved_dqs_en |= AXI_NON_BLOCKING_WR;
>> +             mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en);
>> +             if (!priv->dqs_delay)
>> +                     priv->dqs_delay =
>> +                             DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl);
>> +     }
>> +
>>       return 0;
>>  }
>>
>> @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host)
>>  {
>>       struct dw_mci_exynos_priv_data *priv = host->priv;
>>
>> -     host->bus_hz /= (priv->ciu_div + 1);
>> +     host->bus_hz /= priv->ciu_div;
>
> Don't need to consider the case that priv->ciu_div set to 0?
>
Ah ok, I know at least one board sets ciu_div as zero, let me remove
this change. thanks
>>
>>       return 0;
>>  }
>>
>> +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +     u32 clksel;
>> +
>> +     if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> +             priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> +             clksel = mci_readl(host, CLKSEL64);
>> +     else
>> +             clksel = mci_readl(host, CLKSEL);
>> +
>> +     clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing;
>> +
>> +     if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> +             priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> +             mci_writel(host, CLKSEL64, clksel);
>> +     else
>> +             mci_writel(host, CLKSEL, clksel);
>> +}
>> +
>>  #ifdef CONFIG_PM_SLEEP
>>  static int dw_mci_exynos_suspend(struct device *dev)
>>  {
>> @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
>>       }
>>  }
>>
>> -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>> +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing)
>>  {
>>       struct dw_mci_exynos_priv_data *priv = host->priv;
>> -     unsigned int wanted = ios->clock;
>> -     unsigned long actual;
>> -     u8 div = priv->ciu_div + 1;
>> +     u32 dqs, strobe;
>>
>> -     if (ios->timing == MMC_TIMING_MMC_DDR52) {
>> -             if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> -                     priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> -                     mci_writel(host, CLKSEL64, priv->ddr_timing);
>> -             else
>> -                     mci_writel(host, CLKSEL, priv->ddr_timing);
>> -             /* Should be double rate for DDR mode */
>> -             if (ios->bus_width == MMC_BUS_WIDTH_8)
>> -                     wanted <<= 1;
>> +     /*
>> +      * Not suppported to configure register
>
> Typo..supported
>
ok will correct.
>> +      * related to HS400
>> +      */
>> +     if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420)
>> +             return;
>> +
>> +     dqs = priv->saved_dqs_en;
>> +     strobe = priv->saved_strobe_ctrl;
>
> priv->saved_dqs_en is set at init-time.
> And you read the RDDQS_EN and HS400_DLINE_CTRL register at that time.
> Doesn't it need to consider the changed value at those register?
>
> priv->saved_xxx is reset value?
>
Default values are read in init and adjusted below, for now only these
bits are touched other bits of these register are kept as their reset
values.
>> +
>> +     if (timing == MMC_TIMING_MMC_HS400) {
>> +             dqs |= DATA_STROBE_EN;
>> +             strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay);
>>       } else {
>> -             if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> -                     priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> -                     mci_writel(host, CLKSEL64, priv->sdr_timing);
>> -             else
>> -                     mci_writel(host, CLKSEL, priv->sdr_timing);
>> +             dqs &= ~DATA_STROBE_EN;
>>       }
>>
>> +     mci_writel(host, HS400_DQS_EN, dqs);
>> +     mci_writel(host, HS400_DLINE_CTRL, strobe);
>> +}
>> +
>> +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +     unsigned long actual;
>> +     u8 div;
>> +     int ret;
>>       /*
>>        * Don't care if wanted clock is zero or
>>        * ciu clock is unavailable
>> @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>>       if (wanted < EXYNOS_CCLKIN_MIN)
>>               wanted = EXYNOS_CCLKIN_MIN;
>>
>> -     if (wanted != priv->cur_speed) {
>> -             int ret = clk_set_rate(host->ciu_clk, wanted * div);
>> -             if (ret)
>> -                     dev_warn(host->dev,
>> -                             "failed to set clk-rate %u error: %d\n",
>> -                              wanted * div, ret);
>> -             actual = clk_get_rate(host->ciu_clk);
>> -             host->bus_hz = actual / div;
>> -             priv->cur_speed = wanted;
>> -             host->current_speed = 0;
>> +     if (wanted == priv->cur_speed)
>> +             return;
>> +
>> +     div = dw_mci_exynos_get_ciu_div(host);
>> +     ret = clk_set_rate(host->ciu_clk, wanted * div);
>> +     if (ret)
>> +             dev_warn(host->dev,
>> +                     "failed to set clk-rate %u error: %d\n",
>> +                     wanted * div, ret);
>> +     actual = clk_get_rate(host->ciu_clk);
>> +     host->bus_hz = actual / div;
>> +     priv->cur_speed = wanted;
>> +     host->current_speed = 0;
>> +}
>> +
>> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +     unsigned int wanted = ios->clock;
>> +     u32 timing = ios->timing, clksel;
>> +
>> +     switch (timing) {
>> +     case MMC_TIMING_MMC_HS400:
>> +             /* Update tuned sample timing */
>> +             clksel = SDMMC_CLKSEL_UP_SAMPLE(
>> +                             priv->hs400_timing, priv->tuned_sample);
>> +             wanted <<= 1;
>> +             break;
>> +     case MMC_TIMING_MMC_DDR52:
>> +             clksel = priv->ddr_timing;
>> +             /* Should be double rate for DDR mode */
>> +             if (ios->bus_width == MMC_BUS_WIDTH_8)
>> +                     wanted <<= 1;
>> +             break;
>> +     default:
>> +             clksel = priv->sdr_timing;
>>       }
>> +
>> +     /* Set clock timing for the requested speed mode*/
>> +     dw_mci_exynos_set_clksel_timing(host, clksel);
>> +
>> +     /* Configure setting for HS400 */
>> +     dw_mci_exynos_config_hs400(host, timing);
>> +
>> +     /* Configure clock rate */
>> +     dw_mci_exynos_adjust_clock(host, wanted);
>>  }
>>
>>  static int dw_mci_exynos_parse_dt(struct dw_mci *host)
>> @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host)
>>               return ret;
>>
>>       priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
>> +
>> +     ret = of_property_read_u32_array(np,
>> +                     "samsung,dw-mshc-hs400-timing", timing, 2);
>> +     if (!ret && of_property_read_u32(np,
>> +                             "read-strobe-delay", &priv->dqs_delay))
>> +             dev_info(host->dev,
>> +                     "read-strobe-delay is not found, assuming usage of default value\n");
>
> Need the message?
>
Just in case the default values does not work, then user will know
this is something they need to change as per their boards.
>> +
>> +     priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1],
>> +                                             HS400_FIXED_CIU_CLK_DIV);
>
> Why useed the HS400_FIXED_CIU_CLK_DIV? always set to 1?
>
I thought about this, but I didn't find a case where it is anytime set
to more then div by 2 to support HS400 clock input value requirement.
So instead of getting this via DT, I kept fixed value,
Let me know your opinion on this, in case you wants me to change this.
> Best Regards,
> Jaehoon Chung
>
>>       host->priv = priv;
>>       return 0;
>>  }
>> @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample)
>>               clksel = mci_readl(host, CLKSEL64);
>>       else
>>               clksel = mci_readl(host, CLKSEL);
>> -     clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample);
>> +     clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
>>       if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>>               priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>>               mci_writel(host, CLKSEL64, clksel);
>> @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host)
>>               clksel = mci_readl(host, CLKSEL64);
>>       else
>>               clksel = mci_readl(host, CLKSEL);
>> +
>>       sample = (clksel + 1) & 0x7;
>> -     clksel = (clksel & ~0x7) | sample;
>> +     clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
>> +
>>       if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>>               priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>>               mci_writel(host, CLKSEL64, clksel);
>>       else
>>               mci_writel(host, CLKSEL, clksel);
>> +
>>       return sample;
>>  }
>>
>> @@ -343,6 +449,7 @@ out:
>>  static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
>>  {
>>       struct dw_mci *host = slot->host;
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>>       struct mmc_host *mmc = slot->mmc;
>>       u8 start_smpl, smpl, candiates = 0;
>>       s8 found = -1;
>> @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
>>       } while (start_smpl != smpl);
>>
>>       found = dw_mci_exynos_get_best_clksmpl(candiates);
>> -     if (found >= 0)
>> +     if (found >= 0) {
>>               dw_mci_exynos_set_clksmpl(host, found);
>> -     else
>> +             priv->tuned_sample = found;
>> +     } else {
>>               ret = -EIO;
>> +     }
>>
>>       return ret;
>>  }
>>
>> +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host,
>> +                                     struct mmc_ios *ios)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +
>> +     dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing);
>> +     dw_mci_exynos_adjust_clock(host, (ios->clock) << 1);
>> +
>> +     return 0;
>> +}
>> +
>>  /* Common capabilities of Exynos4/Exynos5 SoC */
>>  static unsigned long exynos_dwmmc_caps[4] = {
>>       MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
>> @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = {
>>       .set_ios                = dw_mci_exynos_set_ios,
>>       .parse_dt               = dw_mci_exynos_parse_dt,
>>       .execute_tuning         = dw_mci_exynos_execute_tuning,
>> +     .prepare_hs400_tuning   = dw_mci_exynos_prepare_hs400_tuning,
>>  };
>>
>>  static const struct of_device_id dw_mci_exynos_match[] = {
>> diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h
>> index 7872ce5..595c934 100644
>> --- a/drivers/mmc/host/dw_mmc-exynos.h
>> +++ b/drivers/mmc/host/dw_mmc-exynos.h
>> @@ -12,20 +12,36 @@
>>  #ifndef _DW_MMC_EXYNOS_H_
>>  #define _DW_MMC_EXYNOS_H_
>>
>> -/* Extended Register's Offset */
>>  #define SDMMC_CLKSEL                 0x09C
>>  #define SDMMC_CLKSEL64                       0x0A8
>>
>> +/* Extended Register's Offset */
>> +#define SDMMC_HS400_DQS_EN           0x180
>> +#define SDMMC_HS400_ASYNC_FIFO_CTRL  0x184
>> +#define SDMMC_HS400_DLINE_CTRL               0x188
>> +
>>  /* CLKSEL register defines */
>>  #define SDMMC_CLKSEL_CCLK_SAMPLE(x)  (((x) & 7) << 0)
>>  #define SDMMC_CLKSEL_CCLK_DRIVE(x)   (((x) & 7) << 16)
>>  #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24)
>>  #define SDMMC_CLKSEL_GET_DRV_WD3(x)  (((x) >> 16) & 0x7)
>> +#define SDMMC_CLKSEL_GET_DIV(x)              (((x) >> 24) & 0x7)
>> +#define SDMMC_CLKSEL_UP_SAMPLE(x, y) (((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\
>> +                                      SDMMC_CLKSEL_CCLK_SAMPLE(y))
>>  #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) |  \
>>                                        SDMMC_CLKSEL_CCLK_DRIVE(y) |   \
>>                                        SDMMC_CLKSEL_CCLK_DIVIDER(z))
>> +#define SDMMC_CLKSEL_TIMING_MASK     SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7)
>>  #define SDMMC_CLKSEL_WAKEUP_INT              BIT(11)
>>
>> +/* RCLK_EN register defines */
>> +#define DATA_STROBE_EN                       BIT(0)
>> +#define AXI_NON_BLOCKING_WR  BIT(7)
>> +
>> +/* DLINE_CTRL register defines */
>> +#define DQS_CTRL_RD_DELAY(x, y)              (((x) & ~0x3FF) | ((y) & 0x3FF))
>> +#define DQS_CTRL_GET_RD_DELAY(x)     ((x) & 0x3FF)
>> +
>>  /* Protector Register */
>>  #define SDMMC_EMMCP_BASE     0x1000
>>  #define SDMMC_MPSECURITY     (SDMMC_EMMCP_BASE + 0x0010)
>> @@ -49,6 +65,7 @@
>>  /* Fixed clock divider */
>>  #define EXYNOS4210_FIXED_CIU_CLK_DIV 2
>>  #define EXYNOS4412_FIXED_CIU_CLK_DIV 4
>> +#define HS400_FIXED_CIU_CLK_DIV              1
>>
>>  /* Minimal required clock frequency for cclkin, unit: HZ */
>>  #define EXYNOS_CCLKIN_MIN    50000000
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 2e8abc8..43a3a5b 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>       regs = mci_readl(slot->host, UHS_REG);
>>
>>       /* DDR mode set */
>> -     if (ios->timing == MMC_TIMING_MMC_DDR52)
>> +     if (ios->timing == MMC_TIMING_MMC_DDR52 ||
>> +         ios->timing == MMC_TIMING_MMC_HS400)
>>               regs |= ((0x1 << slot->id) << 16);
>>       else
>>               regs &= ~((0x1 << slot->id) << 16);
>> @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>>       return err;
>>  }
>>
>> +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
>> +{
>> +     struct dw_mci_slot *slot = mmc_priv(mmc);
>> +     struct dw_mci *host = slot->host;
>> +     const struct dw_mci_drv_data *drv_data = host->drv_data;
>> +
>> +     if (drv_data && drv_data->prepare_hs400_tuning)
>> +             return drv_data->prepare_hs400_tuning(host, ios);
>> +
>> +     return 0;
>> +}
>> +
>>  static const struct mmc_host_ops dw_mci_ops = {
>>       .request                = dw_mci_request,
>>       .pre_req                = dw_mci_pre_req,
>> @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = {
>>       .card_busy              = dw_mci_card_busy,
>>       .start_signal_voltage_switch = dw_mci_switch_voltage,
>>       .init_card              = dw_mci_init_card,
>> +     .prepare_hs400_tuning   = dw_mci_prepare_hs400_tuning,
>>  };
>>
>>  static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>> index 18c4afe..d239867 100644
>> --- a/drivers/mmc/host/dw_mmc.h
>> +++ b/drivers/mmc/host/dw_mmc.h
>> @@ -271,5 +271,7 @@ struct dw_mci_drv_data {
>>       void            (*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
>>       int             (*parse_dt)(struct dw_mci *host);
>>       int             (*execute_tuning)(struct dw_mci_slot *slot);
>> +     int             (*prepare_hs400_tuning)(struct dw_mci *host,
>> +                                             struct mmc_ios *ios);
>>  };
>>  #endif /* _DW_MMC_H_ */
>>
>



-- 
Regards,
Alim

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

* [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode
@ 2015-01-21 23:42       ` Alim Akhtar
  0 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-21 23:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jaehoon

On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi,
>
> This patch can be separated.
> When i tested on my board, it's not working fine.
> I think it depends on my timing, so i will check after change the timing.
>
> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>> From: Seungwon Jeon <tgih.jun@samsung.com>
>>
>> Implements HS400 mode support for exynos host driver.
>> This also include some updates as new mode is added.
>>
>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>> [Alim: addressed review comments]
>> ---
>>  .../devicetree/bindings/mmc/exynos-dw-mshc.txt     |    7 +
>>  drivers/mmc/host/dw_mmc-exynos.c                   |  187 ++++++++++++++++----
>>  drivers/mmc/host/dw_mmc-exynos.h                   |   19 +-
>>  drivers/mmc/host/dw_mmc.c                          |   16 +-
>>  drivers/mmc/host/dw_mmc.h                          |    2 +
>>  5 files changed, 196 insertions(+), 35 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
>> index ee4fc05..dcab52c 100644
>> --- a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
>> +++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
>> @@ -36,6 +36,8 @@ Required Properties:
>>    in transmit mode and CIU clock phase shift value in receive mode for double
>>    data rate mode operation. Refer notes below for the order of the cells and the
>>    valid values.
>> +* samsung,dw-mshc-hs400-timing: Specifies the value of CIU TX and RX clock phase
>> +  shift value for hs400 mode operation.
>>
>>    Notes for the sdr-timing and ddr-timing values:
>>
>> @@ -50,6 +52,9 @@ Required Properties:
>>        - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
>>          phase shift clocks should be 0.
>>
>> +* read-strobe-delay: RCLK (Data strobe) delay to control HS400 mode
>> +  (Latency value for delay line in Read path)
>> +
>>  Required properties for a slot (Deprecated - Recommend to use one slot per host):
>>
>>  * gpios: specifies a list of gpios used for command, clock and data bus. The
>> @@ -82,5 +87,7 @@ Example:
>>               samsung,dw-mshc-ciu-div = <3>;
>>               samsung,dw-mshc-sdr-timing = <2 3>;
>>               samsung,dw-mshc-ddr-timing = <1 2>;
>> +             samsung,dw-mshc-hs400-timing = <0 2>;
>> +             read-strobe-delay = <90>;
>
> read-strobe-delay is exynos specific, isn't?
> read-strobe-delay -> samsung.read-strobe-delay.
>
read-strobe are as per hs400 spec, ok I will change this to match the
naming with other properties.
>>               bus-width = <8>;
>>       };
>> diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
>> index 12a5eaa..172a2a8 100644
>> --- a/drivers/mmc/host/dw_mmc-exynos.c
>> +++ b/drivers/mmc/host/dw_mmc-exynos.c
>> @@ -40,7 +40,12 @@ struct dw_mci_exynos_priv_data {
>>       u8                              ciu_div;
>>       u32                             sdr_timing;
>>       u32                             ddr_timing;
>> +     u32                             hs400_timing;
>> +     u32                             tuned_sample;
>>       u32                             cur_speed;
>> +     u32                             dqs_delay;
>> +     u32                             saved_dqs_en;
>> +     u32                             saved_strobe_ctrl;
>>  };
>>
>>  static struct dw_mci_exynos_compatible {
>> @@ -71,6 +76,21 @@ static struct dw_mci_exynos_compatible {
>>       },
>>  };
>>
>> +static inline u8 dw_mci_exynos_get_ciu_div(struct dw_mci *host)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +
>> +     if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
>> +             return EXYNOS4412_FIXED_CIU_CLK_DIV;
>> +     else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
>> +             return EXYNOS4210_FIXED_CIU_CLK_DIV;
>> +     else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> +                     priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> +             return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL64)) + 1;
>> +     else
>> +             return SDMMC_CLKSEL_GET_DIV(mci_readl(host, CLKSEL)) + 1;
>> +}
>> +
>>  static int dw_mci_exynos_priv_init(struct dw_mci *host)
>>  {
>>       struct dw_mci_exynos_priv_data *priv = host->priv;
>> @@ -85,6 +105,16 @@ static int dw_mci_exynos_priv_init(struct dw_mci *host)
>>                          SDMMC_MPSCTRL_NON_SECURE_WRITE_BIT);
>>       }
>>
>> +     if (priv->ctrl_type >= DW_MCI_TYPE_EXYNOS5420) {
>> +             priv->saved_strobe_ctrl = mci_readl(host, HS400_DLINE_CTRL);
>> +             priv->saved_dqs_en = mci_readl(host, HS400_DQS_EN);
>> +             priv->saved_dqs_en |= AXI_NON_BLOCKING_WR;
>> +             mci_writel(host, HS400_DQS_EN, priv->saved_dqs_en);
>> +             if (!priv->dqs_delay)
>> +                     priv->dqs_delay =
>> +                             DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl);
>> +     }
>> +
>>       return 0;
>>  }
>>
>> @@ -92,11 +122,31 @@ static int dw_mci_exynos_setup_clock(struct dw_mci *host)
>>  {
>>       struct dw_mci_exynos_priv_data *priv = host->priv;
>>
>> -     host->bus_hz /= (priv->ciu_div + 1);
>> +     host->bus_hz /= priv->ciu_div;
>
> Don't need to consider the case that priv->ciu_div set to 0?
>
Ah ok, I know at least one board sets ciu_div as zero, let me remove
this change. thanks
>>
>>       return 0;
>>  }
>>
>> +static void dw_mci_exynos_set_clksel_timing(struct dw_mci *host, u32 timing)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +     u32 clksel;
>> +
>> +     if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> +             priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> +             clksel = mci_readl(host, CLKSEL64);
>> +     else
>> +             clksel = mci_readl(host, CLKSEL);
>> +
>> +     clksel = (clksel & ~SDMMC_CLKSEL_TIMING_MASK) | timing;
>> +
>> +     if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> +             priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> +             mci_writel(host, CLKSEL64, clksel);
>> +     else
>> +             mci_writel(host, CLKSEL, clksel);
>> +}
>> +
>>  #ifdef CONFIG_PM_SLEEP
>>  static int dw_mci_exynos_suspend(struct device *dev)
>>  {
>> @@ -172,30 +222,38 @@ static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
>>       }
>>  }
>>
>> -static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>> +static void dw_mci_exynos_config_hs400(struct dw_mci *host, u32 timing)
>>  {
>>       struct dw_mci_exynos_priv_data *priv = host->priv;
>> -     unsigned int wanted = ios->clock;
>> -     unsigned long actual;
>> -     u8 div = priv->ciu_div + 1;
>> +     u32 dqs, strobe;
>>
>> -     if (ios->timing == MMC_TIMING_MMC_DDR52) {
>> -             if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> -                     priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> -                     mci_writel(host, CLKSEL64, priv->ddr_timing);
>> -             else
>> -                     mci_writel(host, CLKSEL, priv->ddr_timing);
>> -             /* Should be double rate for DDR mode */
>> -             if (ios->bus_width == MMC_BUS_WIDTH_8)
>> -                     wanted <<= 1;
>> +     /*
>> +      * Not suppported to configure register
>
> Typo..supported
>
ok will correct.
>> +      * related to HS400
>> +      */
>> +     if (priv->ctrl_type < DW_MCI_TYPE_EXYNOS5420)
>> +             return;
>> +
>> +     dqs = priv->saved_dqs_en;
>> +     strobe = priv->saved_strobe_ctrl;
>
> priv->saved_dqs_en is set at init-time.
> And you read the RDDQS_EN and HS400_DLINE_CTRL register at that time.
> Doesn't it need to consider the changed value at those register?
>
> priv->saved_xxx is reset value?
>
Default values are read in init and adjusted below, for now only these
bits are touched other bits of these register are kept as their reset
values.
>> +
>> +     if (timing == MMC_TIMING_MMC_HS400) {
>> +             dqs |= DATA_STROBE_EN;
>> +             strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay);
>>       } else {
>> -             if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>> -                     priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>> -                     mci_writel(host, CLKSEL64, priv->sdr_timing);
>> -             else
>> -                     mci_writel(host, CLKSEL, priv->sdr_timing);
>> +             dqs &= ~DATA_STROBE_EN;
>>       }
>>
>> +     mci_writel(host, HS400_DQS_EN, dqs);
>> +     mci_writel(host, HS400_DLINE_CTRL, strobe);
>> +}
>> +
>> +static void dw_mci_exynos_adjust_clock(struct dw_mci *host, unsigned int wanted)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +     unsigned long actual;
>> +     u8 div;
>> +     int ret;
>>       /*
>>        * Don't care if wanted clock is zero or
>>        * ciu clock is unavailable
>> @@ -207,17 +265,52 @@ static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>>       if (wanted < EXYNOS_CCLKIN_MIN)
>>               wanted = EXYNOS_CCLKIN_MIN;
>>
>> -     if (wanted != priv->cur_speed) {
>> -             int ret = clk_set_rate(host->ciu_clk, wanted * div);
>> -             if (ret)
>> -                     dev_warn(host->dev,
>> -                             "failed to set clk-rate %u error: %d\n",
>> -                              wanted * div, ret);
>> -             actual = clk_get_rate(host->ciu_clk);
>> -             host->bus_hz = actual / div;
>> -             priv->cur_speed = wanted;
>> -             host->current_speed = 0;
>> +     if (wanted == priv->cur_speed)
>> +             return;
>> +
>> +     div = dw_mci_exynos_get_ciu_div(host);
>> +     ret = clk_set_rate(host->ciu_clk, wanted * div);
>> +     if (ret)
>> +             dev_warn(host->dev,
>> +                     "failed to set clk-rate %u error: %d\n",
>> +                     wanted * div, ret);
>> +     actual = clk_get_rate(host->ciu_clk);
>> +     host->bus_hz = actual / div;
>> +     priv->cur_speed = wanted;
>> +     host->current_speed = 0;
>> +}
>> +
>> +static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +     unsigned int wanted = ios->clock;
>> +     u32 timing = ios->timing, clksel;
>> +
>> +     switch (timing) {
>> +     case MMC_TIMING_MMC_HS400:
>> +             /* Update tuned sample timing */
>> +             clksel = SDMMC_CLKSEL_UP_SAMPLE(
>> +                             priv->hs400_timing, priv->tuned_sample);
>> +             wanted <<= 1;
>> +             break;
>> +     case MMC_TIMING_MMC_DDR52:
>> +             clksel = priv->ddr_timing;
>> +             /* Should be double rate for DDR mode */
>> +             if (ios->bus_width == MMC_BUS_WIDTH_8)
>> +                     wanted <<= 1;
>> +             break;
>> +     default:
>> +             clksel = priv->sdr_timing;
>>       }
>> +
>> +     /* Set clock timing for the requested speed mode*/
>> +     dw_mci_exynos_set_clksel_timing(host, clksel);
>> +
>> +     /* Configure setting for HS400 */
>> +     dw_mci_exynos_config_hs400(host, timing);
>> +
>> +     /* Configure clock rate */
>> +     dw_mci_exynos_adjust_clock(host, wanted);
>>  }
>>
>>  static int dw_mci_exynos_parse_dt(struct dw_mci *host)
>> @@ -260,6 +353,16 @@ static int dw_mci_exynos_parse_dt(struct dw_mci *host)
>>               return ret;
>>
>>       priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
>> +
>> +     ret = of_property_read_u32_array(np,
>> +                     "samsung,dw-mshc-hs400-timing", timing, 2);
>> +     if (!ret && of_property_read_u32(np,
>> +                             "read-strobe-delay", &priv->dqs_delay))
>> +             dev_info(host->dev,
>> +                     "read-strobe-delay is not found, assuming usage of default value\n");
>
> Need the message?
>
Just in case the default values does not work, then user will know
this is something they need to change as per their boards.
>> +
>> +     priv->hs400_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1],
>> +                                             HS400_FIXED_CIU_CLK_DIV);
>
> Why useed the HS400_FIXED_CIU_CLK_DIV? always set to 1?
>
I thought about this, but I didn't find a case where it is anytime set
to more then div by 2 to support HS400 clock input value requirement.
So instead of getting this via DT, I kept fixed value,
Let me know your opinion on this, in case you wants me to change this.
> Best Regards,
> Jaehoon Chung
>
>>       host->priv = priv;
>>       return 0;
>>  }
>> @@ -285,7 +388,7 @@ static inline void dw_mci_exynos_set_clksmpl(struct dw_mci *host, u8 sample)
>>               clksel = mci_readl(host, CLKSEL64);
>>       else
>>               clksel = mci_readl(host, CLKSEL);
>> -     clksel = (clksel & ~0x7) | SDMMC_CLKSEL_CCLK_SAMPLE(sample);
>> +     clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
>>       if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>>               priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>>               mci_writel(host, CLKSEL64, clksel);
>> @@ -304,13 +407,16 @@ static inline u8 dw_mci_exynos_move_next_clksmpl(struct dw_mci *host)
>>               clksel = mci_readl(host, CLKSEL64);
>>       else
>>               clksel = mci_readl(host, CLKSEL);
>> +
>>       sample = (clksel + 1) & 0x7;
>> -     clksel = (clksel & ~0x7) | sample;
>> +     clksel = SDMMC_CLKSEL_UP_SAMPLE(clksel, sample);
>> +
>>       if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS7 ||
>>               priv->ctrl_type == DW_MCI_TYPE_EXYNOS7_SMU)
>>               mci_writel(host, CLKSEL64, clksel);
>>       else
>>               mci_writel(host, CLKSEL, clksel);
>> +
>>       return sample;
>>  }
>>
>> @@ -343,6 +449,7 @@ out:
>>  static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
>>  {
>>       struct dw_mci *host = slot->host;
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>>       struct mmc_host *mmc = slot->mmc;
>>       u8 start_smpl, smpl, candiates = 0;
>>       s8 found = -1;
>> @@ -360,14 +467,27 @@ static int dw_mci_exynos_execute_tuning(struct dw_mci_slot *slot)
>>       } while (start_smpl != smpl);
>>
>>       found = dw_mci_exynos_get_best_clksmpl(candiates);
>> -     if (found >= 0)
>> +     if (found >= 0) {
>>               dw_mci_exynos_set_clksmpl(host, found);
>> -     else
>> +             priv->tuned_sample = found;
>> +     } else {
>>               ret = -EIO;
>> +     }
>>
>>       return ret;
>>  }
>>
>> +int dw_mci_exynos_prepare_hs400_tuning(struct dw_mci *host,
>> +                                     struct mmc_ios *ios)
>> +{
>> +     struct dw_mci_exynos_priv_data *priv = host->priv;
>> +
>> +     dw_mci_exynos_set_clksel_timing(host, priv->hs400_timing);
>> +     dw_mci_exynos_adjust_clock(host, (ios->clock) << 1);
>> +
>> +     return 0;
>> +}
>> +
>>  /* Common capabilities of Exynos4/Exynos5 SoC */
>>  static unsigned long exynos_dwmmc_caps[4] = {
>>       MMC_CAP_1_8V_DDR | MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
>> @@ -384,6 +504,7 @@ static const struct dw_mci_drv_data exynos_drv_data = {
>>       .set_ios                = dw_mci_exynos_set_ios,
>>       .parse_dt               = dw_mci_exynos_parse_dt,
>>       .execute_tuning         = dw_mci_exynos_execute_tuning,
>> +     .prepare_hs400_tuning   = dw_mci_exynos_prepare_hs400_tuning,
>>  };
>>
>>  static const struct of_device_id dw_mci_exynos_match[] = {
>> diff --git a/drivers/mmc/host/dw_mmc-exynos.h b/drivers/mmc/host/dw_mmc-exynos.h
>> index 7872ce5..595c934 100644
>> --- a/drivers/mmc/host/dw_mmc-exynos.h
>> +++ b/drivers/mmc/host/dw_mmc-exynos.h
>> @@ -12,20 +12,36 @@
>>  #ifndef _DW_MMC_EXYNOS_H_
>>  #define _DW_MMC_EXYNOS_H_
>>
>> -/* Extended Register's Offset */
>>  #define SDMMC_CLKSEL                 0x09C
>>  #define SDMMC_CLKSEL64                       0x0A8
>>
>> +/* Extended Register's Offset */
>> +#define SDMMC_HS400_DQS_EN           0x180
>> +#define SDMMC_HS400_ASYNC_FIFO_CTRL  0x184
>> +#define SDMMC_HS400_DLINE_CTRL               0x188
>> +
>>  /* CLKSEL register defines */
>>  #define SDMMC_CLKSEL_CCLK_SAMPLE(x)  (((x) & 7) << 0)
>>  #define SDMMC_CLKSEL_CCLK_DRIVE(x)   (((x) & 7) << 16)
>>  #define SDMMC_CLKSEL_CCLK_DIVIDER(x) (((x) & 7) << 24)
>>  #define SDMMC_CLKSEL_GET_DRV_WD3(x)  (((x) >> 16) & 0x7)
>> +#define SDMMC_CLKSEL_GET_DIV(x)              (((x) >> 24) & 0x7)
>> +#define SDMMC_CLKSEL_UP_SAMPLE(x, y) (((x) & ~SDMMC_CLKSEL_CCLK_SAMPLE(7)) |\
>> +                                      SDMMC_CLKSEL_CCLK_SAMPLE(y))
>>  #define SDMMC_CLKSEL_TIMING(x, y, z) (SDMMC_CLKSEL_CCLK_SAMPLE(x) |  \
>>                                        SDMMC_CLKSEL_CCLK_DRIVE(y) |   \
>>                                        SDMMC_CLKSEL_CCLK_DIVIDER(z))
>> +#define SDMMC_CLKSEL_TIMING_MASK     SDMMC_CLKSEL_TIMING(0x7, 0x7, 0x7)
>>  #define SDMMC_CLKSEL_WAKEUP_INT              BIT(11)
>>
>> +/* RCLK_EN register defines */
>> +#define DATA_STROBE_EN                       BIT(0)
>> +#define AXI_NON_BLOCKING_WR  BIT(7)
>> +
>> +/* DLINE_CTRL register defines */
>> +#define DQS_CTRL_RD_DELAY(x, y)              (((x) & ~0x3FF) | ((y) & 0x3FF))
>> +#define DQS_CTRL_GET_RD_DELAY(x)     ((x) & 0x3FF)
>> +
>>  /* Protector Register */
>>  #define SDMMC_EMMCP_BASE     0x1000
>>  #define SDMMC_MPSECURITY     (SDMMC_EMMCP_BASE + 0x0010)
>> @@ -49,6 +65,7 @@
>>  /* Fixed clock divider */
>>  #define EXYNOS4210_FIXED_CIU_CLK_DIV 2
>>  #define EXYNOS4412_FIXED_CIU_CLK_DIV 4
>> +#define HS400_FIXED_CIU_CLK_DIV              1
>>
>>  /* Minimal required clock frequency for cclkin, unit: HZ */
>>  #define EXYNOS_CCLKIN_MIN    50000000
>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
>> index 2e8abc8..43a3a5b 100644
>> --- a/drivers/mmc/host/dw_mmc.c
>> +++ b/drivers/mmc/host/dw_mmc.c
>> @@ -1084,7 +1084,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>>       regs = mci_readl(slot->host, UHS_REG);
>>
>>       /* DDR mode set */
>> -     if (ios->timing == MMC_TIMING_MMC_DDR52)
>> +     if (ios->timing == MMC_TIMING_MMC_DDR52 ||
>> +         ios->timing == MMC_TIMING_MMC_HS400)
>>               regs |= ((0x1 << slot->id) << 16);
>>       else
>>               regs &= ~((0x1 << slot->id) << 16);
>> @@ -1321,6 +1322,18 @@ static int dw_mci_execute_tuning(struct mmc_host *mmc, u32 opcode)
>>       return err;
>>  }
>>
>> +int dw_mci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
>> +{
>> +     struct dw_mci_slot *slot = mmc_priv(mmc);
>> +     struct dw_mci *host = slot->host;
>> +     const struct dw_mci_drv_data *drv_data = host->drv_data;
>> +
>> +     if (drv_data && drv_data->prepare_hs400_tuning)
>> +             return drv_data->prepare_hs400_tuning(host, ios);
>> +
>> +     return 0;
>> +}
>> +
>>  static const struct mmc_host_ops dw_mci_ops = {
>>       .request                = dw_mci_request,
>>       .pre_req                = dw_mci_pre_req,
>> @@ -1333,6 +1346,7 @@ static const struct mmc_host_ops dw_mci_ops = {
>>       .card_busy              = dw_mci_card_busy,
>>       .start_signal_voltage_switch = dw_mci_switch_voltage,
>>       .init_card              = dw_mci_init_card,
>> +     .prepare_hs400_tuning   = dw_mci_prepare_hs400_tuning,
>>  };
>>
>>  static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq)
>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
>> index 18c4afe..d239867 100644
>> --- a/drivers/mmc/host/dw_mmc.h
>> +++ b/drivers/mmc/host/dw_mmc.h
>> @@ -271,5 +271,7 @@ struct dw_mci_drv_data {
>>       void            (*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
>>       int             (*parse_dt)(struct dw_mci *host);
>>       int             (*execute_tuning)(struct dw_mci_slot *slot);
>> +     int             (*prepare_hs400_tuning)(struct dw_mci *host,
>> +                                             struct mmc_ios *ios);
>>  };
>>  #endif /* _DW_MMC_H_ */
>>
>



-- 
Regards,
Alim

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

* Re: [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
  2015-01-21 14:12         ` Alim Akhtar
@ 2015-01-22  2:28           ` Jaehoon Chung
  -1 siblings, 0 replies; 24+ messages in thread
From: Jaehoon Chung @ 2015-01-22  2:28 UTC (permalink / raw)
  To: Alim Akhtar
  Cc: Alim Akhtar, linux-mmc, Chris Ball, Ulf Hansson, Seungwon Jeon,
	Douglas Anderson, kgene, linux-arm-kernel, devicetree,
	linux-samsung-soc, Abhilash Kesavan

Hi.

On 01/21/2015 11:12 PM, Alim Akhtar wrote:
> Hi Jaehoon
> 
> On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>> Hi,
>>
>> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v".
>> But this patch didn't add them. do you have any other plan?
>>
> Yes, right, plan is to send separate patch to enable hs400, as of now
> I am not sure if all the 5800-peach-pi boards are populated with
> emmc5.0 device or not. So I will enable HS400 after confirming this
> point.

I know if card is not support hs400, then it should be enabled to other bus mode.

Best Regards,
Jaehoon Chung

>> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>>> From: Seungwon Jeon <tgih.jun@samsung.com>
>>>
>>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit
>>> and exynos5800-peach-pi boards.
>>> This also adds RCLK GPIO line, this gpio should be in pull-down
>>> state.
>>>
>>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
>>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>>> [Alim: addressed review comments]
>>> ---
>>>  arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
>>>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
>>>  arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
>>>  arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
>>>  4 files changed, 16 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> index 9a050e1..7ffaba8 100644
>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> @@ -569,8 +569,10 @@
>>>       samsung,dw-mshc-ciu-div = <3>;
>>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>>       samsung,dw-mshc-ddr-timing = <0 2>;
>>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>>> +     read-strobe-delay = <90>;
>>>       pinctrl-names = "default";
>>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>       bus-width = <8>;
>>>  };
>>>
>>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>> index ba686e4..8b15316 100644
>>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>> @@ -201,6 +201,13 @@
>>>                       samsung,pin-drv = <3>;
>>>               };
>>>
>>> +             sd0_rclk: sd0-rclk {
>>
>> I know it used to "sd0_rdqs", not "sd0_rclk".
>> Change name.
>>
> Ok, I will change as per UM of 5800/5420,
> 
>> Best Regards,
>> Jaehoon Chung
>>> +                     samsung,pins = "gpc0-7";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <1>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>>               sd1_cmd: sd1-cmd {
>>>                       samsung,pins = "gpc1-1";
>>>                       samsung,pin-function = <2>;
>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> index 8be3d7b..5290e79 100644
>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> @@ -80,8 +80,10 @@
>>>               samsung,dw-mshc-ciu-div = <3>;
>>>               samsung,dw-mshc-sdr-timing = <0 4>;
>>>               samsung,dw-mshc-ddr-timing = <0 2>;
>>> +             samsung,dw-mshc-hs400-timing = <0 2>;
>>> +             read-strobe-delay = <90>;
>>>               pinctrl-names = "default";
>>> -             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>> +             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>               bus-width = <8>;
>>>               cap-mmc-highspeed;
>>>       };
>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> index e8fdda8..fa1c858 100644
>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> @@ -557,8 +557,10 @@
>>>       samsung,dw-mshc-ciu-div = <3>;
>>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>>       samsung,dw-mshc-ddr-timing = <0 2>;
>>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>>> +     read-strobe-delay = <90>;
>>>       pinctrl-names = "default";
>>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>       bus-width = <8>;
>>>  };
>>>
>>>
>>
> 
> 
> 


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

* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
@ 2015-01-22  2:28           ` Jaehoon Chung
  0 siblings, 0 replies; 24+ messages in thread
From: Jaehoon Chung @ 2015-01-22  2:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi.

On 01/21/2015 11:12 PM, Alim Akhtar wrote:
> Hi Jaehoon
> 
> On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>> Hi,
>>
>> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v".
>> But this patch didn't add them. do you have any other plan?
>>
> Yes, right, plan is to send separate patch to enable hs400, as of now
> I am not sure if all the 5800-peach-pi boards are populated with
> emmc5.0 device or not. So I will enable HS400 after confirming this
> point.

I know if card is not support hs400, then it should be enabled to other bus mode.

Best Regards,
Jaehoon Chung

>> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>>> From: Seungwon Jeon <tgih.jun@samsung.com>
>>>
>>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit
>>> and exynos5800-peach-pi boards.
>>> This also adds RCLK GPIO line, this gpio should be in pull-down
>>> state.
>>>
>>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
>>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>>> [Alim: addressed review comments]
>>> ---
>>>  arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
>>>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
>>>  arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
>>>  arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
>>>  4 files changed, 16 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> index 9a050e1..7ffaba8 100644
>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>> @@ -569,8 +569,10 @@
>>>       samsung,dw-mshc-ciu-div = <3>;
>>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>>       samsung,dw-mshc-ddr-timing = <0 2>;
>>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>>> +     read-strobe-delay = <90>;
>>>       pinctrl-names = "default";
>>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>       bus-width = <8>;
>>>  };
>>>
>>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>> index ba686e4..8b15316 100644
>>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>> @@ -201,6 +201,13 @@
>>>                       samsung,pin-drv = <3>;
>>>               };
>>>
>>> +             sd0_rclk: sd0-rclk {
>>
>> I know it used to "sd0_rdqs", not "sd0_rclk".
>> Change name.
>>
> Ok, I will change as per UM of 5800/5420,
> 
>> Best Regards,
>> Jaehoon Chung
>>> +                     samsung,pins = "gpc0-7";
>>> +                     samsung,pin-function = <2>;
>>> +                     samsung,pin-pud = <1>;
>>> +                     samsung,pin-drv = <3>;
>>> +             };
>>> +
>>>               sd1_cmd: sd1-cmd {
>>>                       samsung,pins = "gpc1-1";
>>>                       samsung,pin-function = <2>;
>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> index 8be3d7b..5290e79 100644
>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>> @@ -80,8 +80,10 @@
>>>               samsung,dw-mshc-ciu-div = <3>;
>>>               samsung,dw-mshc-sdr-timing = <0 4>;
>>>               samsung,dw-mshc-ddr-timing = <0 2>;
>>> +             samsung,dw-mshc-hs400-timing = <0 2>;
>>> +             read-strobe-delay = <90>;
>>>               pinctrl-names = "default";
>>> -             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>> +             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>               bus-width = <8>;
>>>               cap-mmc-highspeed;
>>>       };
>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> index e8fdda8..fa1c858 100644
>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>> @@ -557,8 +557,10 @@
>>>       samsung,dw-mshc-ciu-div = <3>;
>>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>>       samsung,dw-mshc-ddr-timing = <0 2>;
>>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>>> +     read-strobe-delay = <90>;
>>>       pinctrl-names = "default";
>>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>       bus-width = <8>;
>>>  };
>>>
>>>
>>
> 
> 
> 

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

* Re: [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
  2015-01-22  2:28           ` Jaehoon Chung
@ 2015-01-29  2:43               ` Alim Akhtar
  -1 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-29  2:43 UTC (permalink / raw)
  To: Jaehoon Chung
  Cc: Alim Akhtar, linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
	Ulf Hansson, Seungwon Jeon, Douglas Anderson, kgene,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA, Abhilash Kesavan

Hi Jaehoon,

Thanks for review.

On Thu, Jan 22, 2015 at 11:28 AM, Jaehoon Chung <jh80.chung-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
> Hi.
>
> On 01/21/2015 11:12 PM, Alim Akhtar wrote:
>> Hi Jaehoon
>>
>> On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org> wrote:
>>> Hi,
>>>
>>> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v".
>>> But this patch didn't add them. do you have any other plan?
>>>
>> Yes, right, plan is to send separate patch to enable hs400, as of now
>> I am not sure if all the 5800-peach-pi boards are populated with
>> emmc5.0 device or not. So I will enable HS400 after confirming this
>> point.
>
> I know if card is not support hs400, then it should be enabled to other bus mode.
>
hmm...mmc-hs{200/400}-1_8v are host capabilities, so host should first
support this, then we can enable it.
ok,  I will enable HS400 for peach-pi in this series.
Also I checked UMs for 5420/5800, in UM, strobe signal is named as
RCLK, so going to keep the same name as UM.
Will resend the patches after modification shortly.

> Best Regards,
> Jaehoon Chung
>
>>> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>>>> From: Seungwon Jeon <tgih.jun-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>>>>
>>>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit
>>>> and exynos5800-peach-pi boards.
>>>> This also adds RCLK GPIO line, this gpio should be in pull-down
>>>> state.
>>>>
>>>> Signed-off-by: Seungwon Jeon <tgih.jun-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>>>> Signed-off-by: Alim Akhtar <alim.akhtar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
>>>> [Alim: addressed review comments]
>>>> ---
>>>>  arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
>>>>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
>>>>  arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
>>>>  arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
>>>>  4 files changed, 16 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> index 9a050e1..7ffaba8 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> @@ -569,8 +569,10 @@
>>>>       samsung,dw-mshc-ciu-div = <3>;
>>>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>>>       samsung,dw-mshc-ddr-timing = <0 2>;
>>>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>>>> +     read-strobe-delay = <90>;
>>>>       pinctrl-names = "default";
>>>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>>       bus-width = <8>;
>>>>  };
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>>> index ba686e4..8b15316 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>>> @@ -201,6 +201,13 @@
>>>>                       samsung,pin-drv = <3>;
>>>>               };
>>>>
>>>> +             sd0_rclk: sd0-rclk {
>>>
>>> I know it used to "sd0_rdqs", not "sd0_rclk".
>>> Change name.
>>>
>> Ok, I will change as per UM of 5800/5420,
>>
>>> Best Regards,
>>> Jaehoon Chung
>>>> +                     samsung,pins = "gpc0-7";
>>>> +                     samsung,pin-function = <2>;
>>>> +                     samsung,pin-pud = <1>;
>>>> +                     samsung,pin-drv = <3>;
>>>> +             };
>>>> +
>>>>               sd1_cmd: sd1-cmd {
>>>>                       samsung,pins = "gpc1-1";
>>>>                       samsung,pin-function = <2>;
>>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> index 8be3d7b..5290e79 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> @@ -80,8 +80,10 @@
>>>>               samsung,dw-mshc-ciu-div = <3>;
>>>>               samsung,dw-mshc-sdr-timing = <0 4>;
>>>>               samsung,dw-mshc-ddr-timing = <0 2>;
>>>> +             samsung,dw-mshc-hs400-timing = <0 2>;
>>>> +             read-strobe-delay = <90>;
>>>>               pinctrl-names = "default";
>>>> -             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>>> +             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>>               bus-width = <8>;
>>>>               cap-mmc-highspeed;
>>>>       };
>>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> index e8fdda8..fa1c858 100644
>>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> @@ -557,8 +557,10 @@
>>>>       samsung,dw-mshc-ciu-div = <3>;
>>>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>>>       samsung,dw-mshc-ddr-timing = <0 2>;
>>>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>>>> +     read-strobe-delay = <90>;
>>>>       pinctrl-names = "default";
>>>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>>       bus-width = <8>;
>>>>  };
>>>>
>>>>
>>>
>>
>>
>>
>



-- 
Regards,
Alim
--
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] 24+ messages in thread

* [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800
@ 2015-01-29  2:43               ` Alim Akhtar
  0 siblings, 0 replies; 24+ messages in thread
From: Alim Akhtar @ 2015-01-29  2:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jaehoon,

Thanks for review.

On Thu, Jan 22, 2015 at 11:28 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
> Hi.
>
> On 01/21/2015 11:12 PM, Alim Akhtar wrote:
>> Hi Jaehoon
>>
>> On Wed, Jan 21, 2015 at 4:32 AM, Jaehoon Chung <jh80.chung@samsung.com> wrote:
>>> Hi,
>>>
>>> If you want to enable the hs400 mode, need to add "mmc-hs400-1_8v" or "mmc-hs400-1_2v".
>>> But this patch didn't add them. do you have any other plan?
>>>
>> Yes, right, plan is to send separate patch to enable hs400, as of now
>> I am not sure if all the 5800-peach-pi boards are populated with
>> emmc5.0 device or not. So I will enable HS400 after confirming this
>> point.
>
> I know if card is not support hs400, then it should be enabled to other bus mode.
>
hmm...mmc-hs{200/400}-1_8v are host capabilities, so host should first
support this, then we can enable it.
ok,  I will enable HS400 for peach-pi in this series.
Also I checked UMs for 5420/5800, in UM, strobe signal is named as
RCLK, so going to keep the same name as UM.
Will resend the patches after modification shortly.

> Best Regards,
> Jaehoon Chung
>
>>> On 01/14/2015 07:30 PM, Alim Akhtar wrote:
>>>> From: Seungwon Jeon <tgih.jun@samsung.com>
>>>>
>>>> HS400 timing values are added for SMDK5420, exynos5420-peach-pit
>>>> and exynos5800-peach-pi boards.
>>>> This also adds RCLK GPIO line, this gpio should be in pull-down
>>>> state.
>>>>
>>>> Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
>>>> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
>>>> [Alim: addressed review comments]
>>>> ---
>>>>  arch/arm/boot/dts/exynos5420-peach-pit.dts |    4 +++-
>>>>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi  |    7 +++++++
>>>>  arch/arm/boot/dts/exynos5420-smdk5420.dts  |    4 +++-
>>>>  arch/arm/boot/dts/exynos5800-peach-pi.dts  |    4 +++-
>>>>  4 files changed, 16 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> index 9a050e1..7ffaba8 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
>>>> @@ -569,8 +569,10 @@
>>>>       samsung,dw-mshc-ciu-div = <3>;
>>>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>>>       samsung,dw-mshc-ddr-timing = <0 2>;
>>>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>>>> +     read-strobe-delay = <90>;
>>>>       pinctrl-names = "default";
>>>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>>       bus-width = <8>;
>>>>  };
>>>>
>>>> diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>>> index ba686e4..8b15316 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>>> +++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
>>>> @@ -201,6 +201,13 @@
>>>>                       samsung,pin-drv = <3>;
>>>>               };
>>>>
>>>> +             sd0_rclk: sd0-rclk {
>>>
>>> I know it used to "sd0_rdqs", not "sd0_rclk".
>>> Change name.
>>>
>> Ok, I will change as per UM of 5800/5420,
>>
>>> Best Regards,
>>> Jaehoon Chung
>>>> +                     samsung,pins = "gpc0-7";
>>>> +                     samsung,pin-function = <2>;
>>>> +                     samsung,pin-pud = <1>;
>>>> +                     samsung,pin-drv = <3>;
>>>> +             };
>>>> +
>>>>               sd1_cmd: sd1-cmd {
>>>>                       samsung,pins = "gpc1-1";
>>>>                       samsung,pin-function = <2>;
>>>> diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> index 8be3d7b..5290e79 100644
>>>> --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
>>>> @@ -80,8 +80,10 @@
>>>>               samsung,dw-mshc-ciu-div = <3>;
>>>>               samsung,dw-mshc-sdr-timing = <0 4>;
>>>>               samsung,dw-mshc-ddr-timing = <0 2>;
>>>> +             samsung,dw-mshc-hs400-timing = <0 2>;
>>>> +             read-strobe-delay = <90>;
>>>>               pinctrl-names = "default";
>>>> -             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>>> +             pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>>               bus-width = <8>;
>>>>               cap-mmc-highspeed;
>>>>       };
>>>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> index e8fdda8..fa1c858 100644
>>>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>>>> @@ -557,8 +557,10 @@
>>>>       samsung,dw-mshc-ciu-div = <3>;
>>>>       samsung,dw-mshc-sdr-timing = <0 4>;
>>>>       samsung,dw-mshc-ddr-timing = <0 2>;
>>>> +     samsung,dw-mshc-hs400-timing = <0 2>;
>>>> +     read-strobe-delay = <90>;
>>>>       pinctrl-names = "default";
>>>> -     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
>>>> +     pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8 &sd0_rclk>;
>>>>       bus-width = <8>;
>>>>  };
>>>>
>>>>
>>>
>>
>>
>>
>



-- 
Regards,
Alim

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

end of thread, other threads:[~2015-01-29  2:43 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-14 10:30 [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support Alim Akhtar
2015-01-14 10:30 ` Alim Akhtar
2015-01-14 10:30 ` [PATCH v4 1/2] mmc: dw_mmc: exynos: Support eMMC's HS400 mode Alim Akhtar
2015-01-14 10:30   ` Alim Akhtar
2015-01-20 23:02   ` Jaehoon Chung
2015-01-20 23:02     ` Jaehoon Chung
2015-01-21 23:42     ` Alim Akhtar
2015-01-21 23:42       ` Alim Akhtar
2015-01-14 10:30 ` [PATCH v4 2/2] ARM: dts: Add HS400 support for exynos5420 and exynos5800 Alim Akhtar
2015-01-14 10:30   ` Alim Akhtar
     [not found]   ` <1421231446-4776-3-git-send-email-alim.akhtar-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-01-20 23:02     ` Jaehoon Chung
2015-01-20 23:02       ` Jaehoon Chung
2015-01-21 14:12       ` Alim Akhtar
2015-01-21 14:12         ` Alim Akhtar
2015-01-22  2:28         ` Jaehoon Chung
2015-01-22  2:28           ` Jaehoon Chung
     [not found]           ` <54C06049.5070106-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-01-29  2:43             ` Alim Akhtar
2015-01-29  2:43               ` Alim Akhtar
2015-01-14 13:32 ` [PATCH v4 0/2] mmc: dw_mmc: exynos: Add HS400 support Jaehoon Chung
2015-01-14 13:32   ` Jaehoon Chung
2015-01-14 15:35   ` Kukjin Kim
2015-01-14 15:35     ` Kukjin Kim
2015-01-14 15:56     ` Ulf Hansson
2015-01-14 15:56       ` Ulf Hansson

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