All of lore.kernel.org
 help / color / mirror / Atom feed
* [0/4] Add eMMC 5.1 support for Versal NET
@ 2023-01-10 11:31 Ashok Reddy Soma
  2023-01-10 11:31 ` [1/4] mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform Ashok Reddy Soma
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ messages in thread
From: Ashok Reddy Soma @ 2023-01-10 11:31 UTC (permalink / raw)
  To: u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek, Ashok Reddy Soma

This patch series,
 - Add support for eMMC5.1 on Versal NET platform by adding new compatible
   string and PHY support.
 - Add support for input and output tap delays for eMMC
 - Add support for enabling HS400 in host capabilities by checking quirk.
 - Add quirk to support HS400 for Versal NET 

Ashok Reddy Soma (4):
  mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform
  mmc: sdhci: Check and call config_dll callback functions
  mmc: sdhci: Enable HS400 support if available in caps
  mmc: zynq_sdhci: Add support and quirk for HS400

 drivers/mmc/sdhci.c      |  20 +++
 drivers/mmc/zynq_sdhci.c | 292 ++++++++++++++++++++++++++++++++++++++-
 include/sdhci.h          |   5 +
 3 files changed, 314 insertions(+), 3 deletions(-)

-- 
2.17.1


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

* [1/4] mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform
  2023-01-10 11:31 [0/4] Add eMMC 5.1 support for Versal NET Ashok Reddy Soma
@ 2023-01-10 11:31 ` Ashok Reddy Soma
  2023-01-31 12:40   ` Jaehoon Chung
  2023-01-10 11:31 ` [2/4] mmc: sdhci: Check and call config_dll callback functions Ashok Reddy Soma
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Ashok Reddy Soma @ 2023-01-10 11:31 UTC (permalink / raw)
  To: u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek, Ashok Reddy Soma

Add support for eMMC 5.1 for Versal NET platform
 - Add new compatible string(xlnx,versal-net-5.1-emmc).
 - Add CONFIG_ARCH_VERSAL_NET condition wherever required.
 - Add DLL and Delay Chain mode support
 - Add input and output tap delays for eMMC.
 - Add Strobe select tap for HS400 mode.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>
---
 drivers/mmc/zynq_sdhci.c | 287 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 284 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 7dcf6ad842..8415da3373 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- * (C) Copyright 2013 - 2015 Xilinx, Inc.
+ * (C) Copyright 2013 - 2022, Xilinx, Inc.
+ * (C) Copyright 2022, Advanced Micro Devices, Inc.
  *
  * Xilinx Zynq SD Host Controller Interface
  */
@@ -16,6 +17,7 @@
 #include <dm/device_compat.h>
 #include <linux/err.h>
 #include <linux/libfdt.h>
+#include <linux/iopoll.h>
 #include <asm/types.h>
 #include <linux/math64.h>
 #include <asm/cache.h>
@@ -48,6 +50,41 @@
 #define SD0_OTAPDLYSEL_MASK		GENMASK(5, 0)
 #define SD1_OTAPDLYSEL_MASK		GENMASK(21, 16)
 
+#define MIN_PHY_CLK_HZ			50000000
+
+#define PHY_CTRL_REG1			0x270
+#define PHY_CTRL_ITAPDLY_ENA_MASK	BIT(0)
+#define PHY_CTRL_ITAPDLY_SEL_MASK	GENMASK(5, 1)
+#define PHY_CTRL_ITAPDLY_SEL_SHIFT	1
+#define PHY_CTRL_ITAP_CHG_WIN_MASK	BIT(6)
+#define PHY_CTRL_OTAPDLY_ENA_MASK	BIT(8)
+#define PHY_CTRL_OTAPDLY_SEL_MASK	GENMASK(15, 12)
+#define PHY_CTRL_OTAPDLY_SEL_SHIFT	12
+#define PHY_CTRL_STRB_SEL_MASK		GENMASK(23, 16)
+#define PHY_CTRL_STRB_SEL_SHIFT		16
+#define PHY_CTRL_TEST_CTRL_MASK		GENMASK(31, 24)
+
+#define PHY_CTRL_REG2			0x274
+#define PHY_CTRL_EN_DLL_MASK		BIT(0)
+#define PHY_CTRL_DLL_RDY_MASK		BIT(1)
+#define PHY_CTRL_FREQ_SEL_MASK		GENMASK(6, 4)
+#define PHY_CTRL_FREQ_SEL_SHIFT		4
+#define PHY_CTRL_SEL_DLY_TX_MASK	BIT(16)
+#define PHY_CTRL_SEL_DLY_RX_MASK	BIT(17)
+#define FREQSEL_200M_170M		0x0
+#define FREQSEL_170M_140M	        0x1
+#define FREQSEL_140M_110M	        0x2
+#define FREQSEL_110M_80M	        0x3
+#define FREQSEL_80M_50M			0x4
+#define FREQSEL_275M_250M		0x5
+#define FREQSEL_250M_225M		0x6
+#define FREQSEL_225M_200M		0x7
+#define PHY_DLL_TIMEOUT_MS		100
+
+#define VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLY_CHAIN	39
+#define VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLL		146
+#define VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL		0X77
+
 struct arasan_sdhci_clk_data {
 	int clk_phase_in[MMC_TIMING_MMC_HS400 + 1];
 	int clk_phase_out[MMC_TIMING_MMC_HS400 + 1];
@@ -64,6 +101,7 @@ struct arasan_sdhci_priv {
 	u32 node_id;
 	u8 bank;
 	u8 no_1p8;
+	bool internal_phy_reg;
 	struct reset_ctl_bulk resets;
 };
 
@@ -84,7 +122,7 @@ __weak int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id)
 	return 1;
 }
 
-#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
+#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET)
 /* Default settings for ZynqMP Clock Phases */
 static const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63,  0,
 					 0, 183, 54,  0, 0};
@@ -97,6 +135,12 @@ static const u32 versal_iclk_phases[] = {0, 132, 132, 0, 132,
 static const u32 versal_oclk_phases[] = {0,  60, 48, 0, 48, 72,
 					 90, 36, 60, 90, 0};
 
+/* Default settings for versal-net eMMC Clock Phases */
+static const u32 versal_net_emmc_iclk_phases[] = {0, 0, 0, 0, 0, 0, 0, 0, 39,
+						  0, 0};
+static const u32 versal_net_emmc_oclk_phases[] = {0, 113, 0, 0, 0, 0, 0, 0,
+						  113, 79, 45};
+
 static const u8 mode2timing[] = {
 	[MMC_LEGACY] = MMC_TIMING_LEGACY,
 	[MMC_HS] = MMC_TIMING_MMC_HS,
@@ -111,6 +155,121 @@ static const u8 mode2timing[] = {
 	[MMC_HS_200] = MMC_TIMING_MMC_HS200,
 };
 
+#if defined(CONFIG_ARCH_VERSAL_NET)
+/**
+ * arasan_phy_set_delaychain - Set eMMC delay chain based Input/Output clock
+ *
+ * @host:	Pointer to the sdhci_host structure
+ * @enable:	Enable or disable Delay chain based Tx and Rx clock
+ * Return:	None
+ *
+ * Enable or disable eMMC delay chain based Input and Output clock in
+ * PHY_CTRL_REG2
+ */
+static void arasan_phy_set_delaychain(struct sdhci_host *host, bool enable)
+{
+	u32 reg;
+
+	reg = sdhci_readw(host, PHY_CTRL_REG2);
+	if (enable)
+		reg |= PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK;
+	else
+		reg &= ~(PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK);
+
+	sdhci_writew(host, reg, PHY_CTRL_REG2);
+}
+
+/**
+ * arasan_phy_set_dll - Set eMMC DLL clock
+ *
+ * @host:	Pointer to the sdhci_host structure
+ * @enable:	Enable or disable DLL clock
+ * Return:	0 if success or timeout error
+ *
+ * Enable or disable eMMC DLL clock in PHY_CTRL_REG2. When DLL enable is
+ * set, wait till DLL is locked
+ */
+static int arasan_phy_set_dll(struct sdhci_host *host, bool enable)
+{
+	u32 reg;
+
+	reg = sdhci_readw(host, PHY_CTRL_REG2);
+	if (enable)
+		reg |= PHY_CTRL_EN_DLL_MASK;
+	else
+		reg &= ~PHY_CTRL_EN_DLL_MASK;
+
+	sdhci_writew(host, reg, PHY_CTRL_REG2);
+
+	/* If DLL is disabled return success */
+	if (!enable)
+		return 0;
+
+	/* If DLL is enabled wait till DLL loop is locked, which is
+	 * indicated by dll_rdy bit(bit1) in PHY_CTRL_REG2
+	 */
+	return readl_relaxed_poll_timeout(host->ioaddr + PHY_CTRL_REG2, reg,
+					  (reg & PHY_CTRL_DLL_RDY_MASK),
+					  1000 * PHY_DLL_TIMEOUT_MS);
+}
+
+/**
+ * arasan_phy_dll_set_freq - Select frequency range of DLL for eMMC
+ *
+ * @host:	Pointer to the sdhci_host structure
+ * @clock:	clock value
+ * Return:	None
+ *
+ * Set frequency range bits based on the selected clock for eMMC
+ */
+static void arasan_phy_dll_set_freq(struct sdhci_host *host, int clock)
+{
+	u32 reg, freq_sel, freq;
+
+	freq = DIV_ROUND_CLOSEST(clock, 1000000);
+	if (freq <= 200 && freq > 170)
+		freq_sel = FREQSEL_200M_170M;
+	else if (freq <= 170 && freq > 140)
+		freq_sel = FREQSEL_170M_140M;
+	else if (freq <= 140 && freq > 110)
+		freq_sel = FREQSEL_140M_110M;
+	else if (freq <= 110 && freq > 80)
+		freq_sel = FREQSEL_110M_80M;
+	else
+		freq_sel = FREQSEL_80M_50M;
+
+	reg = sdhci_readw(host, PHY_CTRL_REG2);
+	reg &= ~PHY_CTRL_FREQ_SEL_MASK;
+	reg |= (freq_sel << PHY_CTRL_FREQ_SEL_SHIFT);
+	sdhci_writew(host, reg, PHY_CTRL_REG2);
+}
+
+static int arasan_sdhci_config_dll(struct sdhci_host *host, unsigned int clock, bool enable)
+{
+	struct mmc *mmc = (struct mmc *)host->mmc;
+	struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
+
+	if (enable) {
+		if (priv->internal_phy_reg && clock >= MIN_PHY_CLK_HZ && enable)
+			arasan_phy_set_dll(host, 1);
+		return 0;
+	}
+
+	if (priv->internal_phy_reg && clock >= MIN_PHY_CLK_HZ) {
+		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+		arasan_phy_set_dll(host, 0);
+		arasan_phy_set_delaychain(host, 0);
+		arasan_phy_dll_set_freq(host, clock);
+		return 0;
+	}
+
+	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+	arasan_phy_set_delaychain(host, 1);
+
+	return 0;
+}
+#endif
+
 static inline int arasan_zynqmp_set_in_tapdelay(u32 node_id, u32 itap_delay)
 {
 	int ret;
@@ -585,6 +744,101 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,
 	return 0;
 }
 
+/**
+ * sdhci_versal_net_emmc_sdcardclk_set_phase - Set eMMC Output Clock Tap Delays
+ *
+ * @host:		Pointer to the sdhci_host structure.
+ * @degrees:		The clock phase shift between 0 - 359.
+ * Return: 0
+ *
+ * Set eMMC Output Clock Tap Delays for Output path
+ */
+static int sdhci_versal_net_emmc_sdcardclk_set_phase(struct sdhci_host *host, int degrees)
+{
+	struct mmc *mmc = (struct mmc *)host->mmc;
+	int timing = mode2timing[mmc->selected_mode];
+	u8 tap_delay, tap_max = 0;
+	u32 regval;
+
+	switch (timing) {
+	case MMC_TIMING_MMC_HS:
+	case MMC_TIMING_MMC_DDR52:
+		tap_max = 16;
+		break;
+	case MMC_TIMING_MMC_HS200:
+	case MMC_TIMING_MMC_HS400:
+		 /* For 200MHz clock, 32 Taps are available */
+		tap_max = 32;
+		break;
+	default:
+		break;
+	}
+
+	tap_delay = (degrees * tap_max) / 360;
+	/* Set the Clock Phase */
+	if (tap_delay) {
+		regval = sdhci_readl(host, PHY_CTRL_REG1);
+		regval |= PHY_CTRL_OTAPDLY_ENA_MASK;
+		sdhci_writel(host, regval, PHY_CTRL_REG1);
+		regval &= ~PHY_CTRL_OTAPDLY_SEL_MASK;
+		regval |= tap_delay << PHY_CTRL_OTAPDLY_SEL_SHIFT;
+		sdhci_writel(host, regval, PHY_CTRL_REG1);
+	}
+
+	return 0;
+}
+
+/**
+ * sdhci_versal_net_emmc_sampleclk_set_phase - Set eMMC Input Clock Tap Delays
+ *
+ * @host:		Pointer to the sdhci_host structure.
+ * @degrees:		The clock phase shift between 0 - 359.
+ * Return: 0
+ *
+ * Set eMMC Input Clock Tap Delays for Input path. If HS400 is selected,
+ * set strobe90 and strobe180 in PHY_CTRL_REG1.
+ */
+static int sdhci_versal_net_emmc_sampleclk_set_phase(struct sdhci_host *host, int degrees)
+{
+	struct mmc *mmc = (struct mmc *)host->mmc;
+	int timing = mode2timing[mmc->selected_mode];
+	u8 tap_delay, tap_max = 0;
+	u32 regval;
+
+	switch (timing) {
+	case MMC_TIMING_MMC_HS:
+	case MMC_TIMING_MMC_DDR52:
+		tap_max = 32;
+		break;
+	case MMC_TIMING_MMC_HS400:
+		/* Strobe select tap point for strb90 and strb180 */
+		regval = sdhci_readl(host, PHY_CTRL_REG1);
+		regval &= ~PHY_CTRL_STRB_SEL_MASK;
+		regval |= VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL << PHY_CTRL_STRB_SEL_SHIFT;
+		sdhci_writel(host, regval, PHY_CTRL_REG1);
+		break;
+	default:
+		break;
+	}
+
+	tap_delay = (degrees * tap_max) / 360;
+	/* Set the Clock Phase */
+	if (tap_delay) {
+		regval = sdhci_readl(host, PHY_CTRL_REG1);
+		regval |= PHY_CTRL_ITAP_CHG_WIN_MASK;
+		sdhci_writel(host, regval, PHY_CTRL_REG1);
+		regval |= PHY_CTRL_ITAPDLY_ENA_MASK;
+		sdhci_writel(host, regval, PHY_CTRL_REG1);
+		regval &= ~PHY_CTRL_ITAPDLY_SEL_MASK;
+		regval |= tap_delay << PHY_CTRL_ITAPDLY_SEL_SHIFT;
+		sdhci_writel(host, regval, PHY_CTRL_REG1);
+		regval &= ~PHY_CTRL_ITAP_CHG_WIN_MASK;
+		sdhci_writel(host, regval, PHY_CTRL_REG1);
+	}
+
+	return 0;
+}
+
 static int arasan_sdhci_set_tapdelay(struct sdhci_host *host)
 {
 	struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
@@ -616,6 +870,19 @@ static int arasan_sdhci_set_tapdelay(struct sdhci_host *host)
 		ret = sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
 		if (ret)
 			return ret;
+	} else if (IS_ENABLED(CONFIG_ARCH_VERSAL_NET) &&
+		   device_is_compatible(dev, "xlnx,versal-net-5.1-emmc")) {
+		if (mmc->clock >= MIN_PHY_CLK_HZ)
+			if (iclk_phase == VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLY_CHAIN)
+				iclk_phase = VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLL;
+
+		ret = sdhci_versal_net_emmc_sampleclk_set_phase(host, iclk_phase);
+		if (ret)
+			return ret;
+
+		ret = sdhci_versal_net_emmc_sdcardclk_set_phase(host, oclk_phase);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -678,6 +945,14 @@ static void arasan_dt_parse_clk_phases(struct udevice *dev)
 		}
 	}
 
+	if (IS_ENABLED(CONFIG_ARCH_VERSAL_NET) &&
+	    device_is_compatible(dev, "xlnx,versal-net-5.1-emmc")) {
+		for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
+			clk_data->clk_phase_in[i] = versal_net_emmc_iclk_phases[i];
+			clk_data->clk_phase_out[i] = versal_net_emmc_oclk_phases[i];
+		}
+	}
+
 	arasan_dt_read_clk_phase(dev, MMC_TIMING_LEGACY,
 				 "clk-phase-legacy");
 	arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS,
@@ -706,6 +981,9 @@ static const struct sdhci_ops arasan_ops = {
 	.platform_execute_tuning	= &arasan_sdhci_execute_tuning,
 	.set_delay = &arasan_sdhci_set_tapdelay,
 	.set_control_reg = &sdhci_set_control_reg,
+#if defined(CONFIG_ARCH_VERSAL_NET)
+	.config_dll = &arasan_sdhci_config_dll,
+#endif
 };
 #endif
 
@@ -822,6 +1100,8 @@ static int arasan_sdhci_probe(struct udevice *dev)
 		}
 	}
 #endif
+	if (device_is_compatible(dev, "xlnx,versal-net-5.1-emmc"))
+		priv->internal_phy_reg = true;
 
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret < 0) {
@@ -905,7 +1185,7 @@ static int arasan_sdhci_of_to_plat(struct udevice *dev)
 
 	priv->host->name = dev->name;
 
-#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
+#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET)
 	priv->host->ops = &arasan_ops;
 	arasan_dt_parse_clk_phases(dev);
 #endif
@@ -933,6 +1213,7 @@ static int arasan_sdhci_bind(struct udevice *dev)
 
 static const struct udevice_id arasan_sdhci_ids[] = {
 	{ .compatible = "arasan,sdhci-8.9a" },
+	{ .compatible = "xlnx,versal-net-5.1-emmc" },
 	{ }
 };
 
-- 
2.17.1


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

* [2/4] mmc: sdhci: Check and call config_dll callback functions
  2023-01-10 11:31 [0/4] Add eMMC 5.1 support for Versal NET Ashok Reddy Soma
  2023-01-10 11:31 ` [1/4] mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform Ashok Reddy Soma
@ 2023-01-10 11:31 ` Ashok Reddy Soma
  2023-01-31 12:40   ` Jaehoon Chung
  2023-01-10 11:31 ` [3/4] mmc: sdhci: Enable HS400 support if available in caps Ashok Reddy Soma
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 13+ messages in thread
From: Ashok Reddy Soma @ 2023-01-10 11:31 UTC (permalink / raw)
  To: u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek, Ashok Reddy Soma

Check if the low level driver supports config_dll callback function and
call it if it does. Call with dll disable before calling set_clock and
with dll enable after it.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>
---
 drivers/mmc/sdhci.c | 16 ++++++++++++++++
 include/sdhci.h     |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index a80ad8329a..181ab9b7cb 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -396,6 +396,14 @@ int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 		}
 	}
 
+	if (host->ops && host->ops->config_dll) {
+		ret = host->ops->config_dll(host, clock, false);
+		if (ret) {
+			printf("%s: Error while configuring dll\n", __func__);
+			return ret;
+		}
+	}
+
 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
 		/*
 		 * Check if the Host Controller supports Programmable Clock
@@ -439,6 +447,14 @@ int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 	if (host->ops && host->ops->set_clock)
 		host->ops->set_clock(host, div);
 
+	if (host->ops && host->ops->config_dll) {
+		ret = host->ops->config_dll(host, clock, true);
+		if (ret) {
+			printf("%s: Error while configuring dll\n", __func__);
+			return ret;
+		}
+	}
+
 	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
 	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
 		<< SDHCI_DIVIDER_HI_SHIFT;
diff --git a/include/sdhci.h b/include/sdhci.h
index 24b4599b85..64a3d309da 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -272,6 +272,8 @@ struct sdhci_ops {
 	void	(*set_clock)(struct sdhci_host *host, u32 div);
 	int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
 	int (*set_delay)(struct sdhci_host *host);
+	/* Callback function to set DLL clock configuration */
+	int (*config_dll)(struct sdhci_host *host, u32 clock, bool enable);
 	int	(*deferred_probe)(struct sdhci_host *host);
 
 	/**
-- 
2.17.1


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

* [3/4] mmc: sdhci: Enable HS400 support if available in caps
  2023-01-10 11:31 [0/4] Add eMMC 5.1 support for Versal NET Ashok Reddy Soma
  2023-01-10 11:31 ` [1/4] mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform Ashok Reddy Soma
  2023-01-10 11:31 ` [2/4] mmc: sdhci: Check and call config_dll callback functions Ashok Reddy Soma
@ 2023-01-10 11:31 ` Ashok Reddy Soma
  2023-01-31 12:40   ` Jaehoon Chung
  2023-01-10 11:31 ` [4/4] mmc: zynq_sdhci: Add support and quirk for HS400 Ashok Reddy Soma
  2023-01-24 13:01 ` [0/4] Add eMMC 5.1 support for Versal NET Michal Simek
  4 siblings, 1 reply; 13+ messages in thread
From: Ashok Reddy Soma @ 2023-01-10 11:31 UTC (permalink / raw)
  To: u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek, Ashok Reddy Soma

HS400 is indicated in bit63 of capability register in few IP's.
Add a quirk to check this and add HS400 to host capabilities.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>
---
 drivers/mmc/sdhci.c | 4 ++++
 include/sdhci.h     | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 181ab9b7cb..c6b250b9a1 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -995,6 +995,10 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 		cfg->host_caps |= MMC_CAP(UHS_SDR50);
 	}
 
+	if ((host->quirks & SDHCI_QUIRK_CAPS_BIT63_FOR_HS400) &&
+	    (caps_1 & SDHCI_SUPPORT_HS400))
+		cfg->host_caps |= MMC_CAP(MMC_HS_400);
+
 	if (caps_1 & SDHCI_SUPPORT_DDR50)
 		cfg->host_caps |= MMC_CAP(UHS_DDR50);
 
diff --git a/include/sdhci.h b/include/sdhci.h
index 64a3d309da..70fefca2a9 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -189,6 +189,7 @@
 #define  SDHCI_SUPPORT_SDR50	0x00000001
 #define  SDHCI_SUPPORT_SDR104	0x00000002
 #define  SDHCI_SUPPORT_DDR50	0x00000004
+#define  SDHCI_SUPPORT_HS400	BIT(31)
 #define  SDHCI_USE_SDR50_TUNING	0x00002000
 
 #define  SDHCI_CLOCK_MUL_MASK	0x00FF0000
@@ -248,6 +249,8 @@
 #define SDHCI_QUIRK_USE_WIDE8		(1 << 8)
 #define SDHCI_QUIRK_NO_1_8_V		(1 << 9)
 #define SDHCI_QUIRK_SUPPORT_SINGLE	(1 << 10)
+/* Capability register bit-63 indicates HS400 support */
+#define SDHCI_QUIRK_CAPS_BIT63_FOR_HS400	BIT(11)
 
 /* to make gcc happy */
 struct sdhci_host;
-- 
2.17.1


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

* [4/4] mmc: zynq_sdhci: Add support and quirk for HS400
  2023-01-10 11:31 [0/4] Add eMMC 5.1 support for Versal NET Ashok Reddy Soma
                   ` (2 preceding siblings ...)
  2023-01-10 11:31 ` [3/4] mmc: sdhci: Enable HS400 support if available in caps Ashok Reddy Soma
@ 2023-01-10 11:31 ` Ashok Reddy Soma
  2023-01-31 12:40   ` Jaehoon Chung
  2023-01-24 13:01 ` [0/4] Add eMMC 5.1 support for Versal NET Michal Simek
  4 siblings, 1 reply; 13+ messages in thread
From: Ashok Reddy Soma @ 2023-01-10 11:31 UTC (permalink / raw)
  To: u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek, Ashok Reddy Soma

Add support for HS400 in mode2timing array.
Add a quirk for Versal NET platform to indicate that HS400 is supported
through bit63 of capability register.

Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>
---
 drivers/mmc/zynq_sdhci.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 8415da3373..72de6c6227 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -153,6 +153,7 @@ static const u8 mode2timing[] = {
 	[UHS_DDR50] = MMC_TIMING_UHS_DDR50,
 	[UHS_SDR104] = MMC_TIMING_UHS_SDR104,
 	[MMC_HS_200] = MMC_TIMING_MMC_HS200,
+	[MMC_HS_400] = MMC_TIMING_MMC_HS400,
 };
 
 #if defined(CONFIG_ARCH_VERSAL_NET)
@@ -1133,6 +1134,10 @@ static int arasan_sdhci_probe(struct udevice *dev)
 	if (priv->no_1p8)
 		host->quirks |= SDHCI_QUIRK_NO_1_8_V;
 
+	if (CONFIG_IS_ENABLED(ARCH_VERSAL_NET) &&
+	    device_is_compatible(dev, "xlnx,versal-net-5.1-emmc"))
+		host->quirks |= SDHCI_QUIRK_CAPS_BIT63_FOR_HS400;
+
 	plat->cfg.f_max = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
 
 	ret = mmc_of_parse(dev, &plat->cfg);
-- 
2.17.1


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

* Re: [0/4] Add eMMC 5.1 support for Versal NET
  2023-01-10 11:31 [0/4] Add eMMC 5.1 support for Versal NET Ashok Reddy Soma
                   ` (3 preceding siblings ...)
  2023-01-10 11:31 ` [4/4] mmc: zynq_sdhci: Add support and quirk for HS400 Ashok Reddy Soma
@ 2023-01-24 13:01 ` Michal Simek
  2023-01-26  2:29   ` Jaehoon Chung
  4 siblings, 1 reply; 13+ messages in thread
From: Michal Simek @ 2023-01-24 13:01 UTC (permalink / raw)
  To: Ashok Reddy Soma, u-boot, Jaehoon Chung
  Cc: peng.fan, kever.yang, hayashi.kunihiko, alpernebiyasak, xypron.glpk, git

Hi Jaehoon,

On 1/10/23 12:31, Ashok Reddy Soma wrote:
> This patch series,
>   - Add support for eMMC5.1 on Versal NET platform by adding new compatible
>     string and PHY support.
>   - Add support for input and output tap delays for eMMC
>   - Add support for enabling HS400 in host capabilities by checking quirk.
>   - Add quirk to support HS400 for Versal NET
> 
> Ashok Reddy Soma (4):
>    mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform
>    mmc: sdhci: Check and call config_dll callback functions
>    mmc: sdhci: Enable HS400 support if available in caps
>    mmc: zynq_sdhci: Add support and quirk for HS400
> 
>   drivers/mmc/sdhci.c      |  20 +++
>   drivers/mmc/zynq_sdhci.c | 292 ++++++++++++++++++++++++++++++++++++++-
>   include/sdhci.h          |   5 +
>   3 files changed, 314 insertions(+), 3 deletions(-)
> 

Can you please review this series?

Thanks,
Michal

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

* RE: [0/4] Add eMMC 5.1 support for Versal NET
  2023-01-24 13:01 ` [0/4] Add eMMC 5.1 support for Versal NET Michal Simek
@ 2023-01-26  2:29   ` Jaehoon Chung
  2023-01-31 13:07     ` Michal Simek
  0 siblings, 1 reply; 13+ messages in thread
From: Jaehoon Chung @ 2023-01-26  2:29 UTC (permalink / raw)
  To: 'Michal Simek', 'Ashok Reddy Soma', u-boot
  Cc: peng.fan, kever.yang, hayashi.kunihiko, alpernebiyasak, xypron.glpk, git

Hi,

> -----Original Message-----
> From: Michal Simek <michal.simek@amd.com>
> Sent: Tuesday, January 24, 2023 10:02 PM
> To: Ashok Reddy Soma <ashok.reddy.soma@amd.com>; u-boot@lists.denx.de; Jaehoon Chung
> <jh80.chung@samsung.com>
> Cc: peng.fan@nxp.com; kever.yang@rock-chips.com; hayashi.kunihiko@socionext.com;
> alpernebiyasak@gmail.com; xypron.glpk@gmx.de; git@amd.com
> Subject: Re: [0/4] Add eMMC 5.1 support for Versal NET
> 
> Hi Jaehoon,
> 
> On 1/10/23 12:31, Ashok Reddy Soma wrote:
> > This patch series,
> >   - Add support for eMMC5.1 on Versal NET platform by adding new compatible
> >     string and PHY support.
> >   - Add support for input and output tap delays for eMMC
> >   - Add support for enabling HS400 in host capabilities by checking quirk.
> >   - Add quirk to support HS400 for Versal NET
> >
> > Ashok Reddy Soma (4):
> >    mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform
> >    mmc: sdhci: Check and call config_dll callback functions
> >    mmc: sdhci: Enable HS400 support if available in caps
> >    mmc: zynq_sdhci: Add support and quirk for HS400
> >
> >   drivers/mmc/sdhci.c      |  20 +++
> >   drivers/mmc/zynq_sdhci.c | 292 ++++++++++++++++++++++++++++++++++++++-
> >   include/sdhci.h          |   5 +
> >   3 files changed, 314 insertions(+), 3 deletions(-)
> >
> 
> Can you please review this series?

Sorry for too late. I will review them. 

Best Regards,
Jaehoon Chung

> 
> Thanks,
> Michal


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

* Re: [1/4] mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform
  2023-01-10 11:31 ` [1/4] mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform Ashok Reddy Soma
@ 2023-01-31 12:40   ` Jaehoon Chung
  0 siblings, 0 replies; 13+ messages in thread
From: Jaehoon Chung @ 2023-01-31 12:40 UTC (permalink / raw)
  To: Ashok Reddy Soma, u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek



On 1/10/23 20:31, Ashok Reddy Soma wrote:
> Add support for eMMC 5.1 for Versal NET platform
>  - Add new compatible string(xlnx,versal-net-5.1-emmc).
>  - Add CONFIG_ARCH_VERSAL_NET condition wherever required.
>  - Add DLL and Delay Chain mode support
>  - Add input and output tap delays for eMMC.
>  - Add Strobe select tap for HS400 mode.
> 
> Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
>  drivers/mmc/zynq_sdhci.c | 287 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 284 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
> index 7dcf6ad842..8415da3373 100644
> --- a/drivers/mmc/zynq_sdhci.c
> +++ b/drivers/mmc/zynq_sdhci.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0+
>  /*
> - * (C) Copyright 2013 - 2015 Xilinx, Inc.
> + * (C) Copyright 2013 - 2022, Xilinx, Inc.
> + * (C) Copyright 2022, Advanced Micro Devices, Inc.
>   *
>   * Xilinx Zynq SD Host Controller Interface
>   */
> @@ -16,6 +17,7 @@
>  #include <dm/device_compat.h>
>  #include <linux/err.h>
>  #include <linux/libfdt.h>
> +#include <linux/iopoll.h>
>  #include <asm/types.h>
>  #include <linux/math64.h>
>  #include <asm/cache.h>
> @@ -48,6 +50,41 @@
>  #define SD0_OTAPDLYSEL_MASK		GENMASK(5, 0)
>  #define SD1_OTAPDLYSEL_MASK		GENMASK(21, 16)
>  
> +#define MIN_PHY_CLK_HZ			50000000
> +
> +#define PHY_CTRL_REG1			0x270
> +#define PHY_CTRL_ITAPDLY_ENA_MASK	BIT(0)
> +#define PHY_CTRL_ITAPDLY_SEL_MASK	GENMASK(5, 1)
> +#define PHY_CTRL_ITAPDLY_SEL_SHIFT	1
> +#define PHY_CTRL_ITAP_CHG_WIN_MASK	BIT(6)
> +#define PHY_CTRL_OTAPDLY_ENA_MASK	BIT(8)
> +#define PHY_CTRL_OTAPDLY_SEL_MASK	GENMASK(15, 12)
> +#define PHY_CTRL_OTAPDLY_SEL_SHIFT	12
> +#define PHY_CTRL_STRB_SEL_MASK		GENMASK(23, 16)
> +#define PHY_CTRL_STRB_SEL_SHIFT		16
> +#define PHY_CTRL_TEST_CTRL_MASK		GENMASK(31, 24)
> +
> +#define PHY_CTRL_REG2			0x274
> +#define PHY_CTRL_EN_DLL_MASK		BIT(0)
> +#define PHY_CTRL_DLL_RDY_MASK		BIT(1)
> +#define PHY_CTRL_FREQ_SEL_MASK		GENMASK(6, 4)
> +#define PHY_CTRL_FREQ_SEL_SHIFT		4
> +#define PHY_CTRL_SEL_DLY_TX_MASK	BIT(16)
> +#define PHY_CTRL_SEL_DLY_RX_MASK	BIT(17)
> +#define FREQSEL_200M_170M		0x0
> +#define FREQSEL_170M_140M	        0x1
> +#define FREQSEL_140M_110M	        0x2
> +#define FREQSEL_110M_80M	        0x3
> +#define FREQSEL_80M_50M			0x4
> +#define FREQSEL_275M_250M		0x5
> +#define FREQSEL_250M_225M		0x6
> +#define FREQSEL_225M_200M		0x7
> +#define PHY_DLL_TIMEOUT_MS		100
> +
> +#define VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLY_CHAIN	39
> +#define VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLL		146
> +#define VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL		0X77
> +
>  struct arasan_sdhci_clk_data {
>  	int clk_phase_in[MMC_TIMING_MMC_HS400 + 1];
>  	int clk_phase_out[MMC_TIMING_MMC_HS400 + 1];
> @@ -64,6 +101,7 @@ struct arasan_sdhci_priv {
>  	u32 node_id;
>  	u8 bank;
>  	u8 no_1p8;
> +	bool internal_phy_reg;
>  	struct reset_ctl_bulk resets;
>  };
>  
> @@ -84,7 +122,7 @@ __weak int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id)
>  	return 1;
>  }
>  
> -#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
> +#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET)
>  /* Default settings for ZynqMP Clock Phases */
>  static const u32 zynqmp_iclk_phases[] = {0, 63, 63, 0, 63,  0,
>  					 0, 183, 54,  0, 0};
> @@ -97,6 +135,12 @@ static const u32 versal_iclk_phases[] = {0, 132, 132, 0, 132,
>  static const u32 versal_oclk_phases[] = {0,  60, 48, 0, 48, 72,
>  					 90, 36, 60, 90, 0};
>  
> +/* Default settings for versal-net eMMC Clock Phases */
> +static const u32 versal_net_emmc_iclk_phases[] = {0, 0, 0, 0, 0, 0, 0, 0, 39,
> +						  0, 0};
> +static const u32 versal_net_emmc_oclk_phases[] = {0, 113, 0, 0, 0, 0, 0, 0,
> +						  113, 79, 45};
> +
>  static const u8 mode2timing[] = {
>  	[MMC_LEGACY] = MMC_TIMING_LEGACY,
>  	[MMC_HS] = MMC_TIMING_MMC_HS,
> @@ -111,6 +155,121 @@ static const u8 mode2timing[] = {
>  	[MMC_HS_200] = MMC_TIMING_MMC_HS200,
>  };
>  
> +#if defined(CONFIG_ARCH_VERSAL_NET)
> +/**
> + * arasan_phy_set_delaychain - Set eMMC delay chain based Input/Output clock
> + *
> + * @host:	Pointer to the sdhci_host structure
> + * @enable:	Enable or disable Delay chain based Tx and Rx clock
> + * Return:	None
> + *
> + * Enable or disable eMMC delay chain based Input and Output clock in
> + * PHY_CTRL_REG2
> + */
> +static void arasan_phy_set_delaychain(struct sdhci_host *host, bool enable)
> +{
> +	u32 reg;
> +
> +	reg = sdhci_readw(host, PHY_CTRL_REG2);
> +	if (enable)
> +		reg |= PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK;
> +	else
> +		reg &= ~(PHY_CTRL_SEL_DLY_TX_MASK | PHY_CTRL_SEL_DLY_RX_MASK);
> +
> +	sdhci_writew(host, reg, PHY_CTRL_REG2);
> +}
> +
> +/**
> + * arasan_phy_set_dll - Set eMMC DLL clock
> + *
> + * @host:	Pointer to the sdhci_host structure
> + * @enable:	Enable or disable DLL clock
> + * Return:	0 if success or timeout error
> + *
> + * Enable or disable eMMC DLL clock in PHY_CTRL_REG2. When DLL enable is
> + * set, wait till DLL is locked
> + */
> +static int arasan_phy_set_dll(struct sdhci_host *host, bool enable)
> +{
> +	u32 reg;
> +
> +	reg = sdhci_readw(host, PHY_CTRL_REG2);
> +	if (enable)
> +		reg |= PHY_CTRL_EN_DLL_MASK;
> +	else
> +		reg &= ~PHY_CTRL_EN_DLL_MASK;
> +
> +	sdhci_writew(host, reg, PHY_CTRL_REG2);
> +
> +	/* If DLL is disabled return success */
> +	if (!enable)
> +		return 0;
> +
> +	/* If DLL is enabled wait till DLL loop is locked, which is
> +	 * indicated by dll_rdy bit(bit1) in PHY_CTRL_REG2
> +	 */
> +	return readl_relaxed_poll_timeout(host->ioaddr + PHY_CTRL_REG2, reg,
> +					  (reg & PHY_CTRL_DLL_RDY_MASK),
> +					  1000 * PHY_DLL_TIMEOUT_MS);
> +}
> +
> +/**
> + * arasan_phy_dll_set_freq - Select frequency range of DLL for eMMC
> + *
> + * @host:	Pointer to the sdhci_host structure
> + * @clock:	clock value
> + * Return:	None
> + *
> + * Set frequency range bits based on the selected clock for eMMC
> + */
> +static void arasan_phy_dll_set_freq(struct sdhci_host *host, int clock)
> +{
> +	u32 reg, freq_sel, freq;
> +
> +	freq = DIV_ROUND_CLOSEST(clock, 1000000);
> +	if (freq <= 200 && freq > 170)
> +		freq_sel = FREQSEL_200M_170M;
> +	else if (freq <= 170 && freq > 140)
> +		freq_sel = FREQSEL_170M_140M;
> +	else if (freq <= 140 && freq > 110)
> +		freq_sel = FREQSEL_140M_110M;
> +	else if (freq <= 110 && freq > 80)
> +		freq_sel = FREQSEL_110M_80M;
> +	else
> +		freq_sel = FREQSEL_80M_50M;
> +
> +	reg = sdhci_readw(host, PHY_CTRL_REG2);
> +	reg &= ~PHY_CTRL_FREQ_SEL_MASK;
> +	reg |= (freq_sel << PHY_CTRL_FREQ_SEL_SHIFT);
> +	sdhci_writew(host, reg, PHY_CTRL_REG2);
> +}
> +
> +static int arasan_sdhci_config_dll(struct sdhci_host *host, unsigned int clock, bool enable)
> +{
> +	struct mmc *mmc = (struct mmc *)host->mmc;
> +	struct arasan_sdhci_priv *priv = dev_get_priv(mmc->dev);
> +
> +	if (enable) {
> +		if (priv->internal_phy_reg && clock >= MIN_PHY_CLK_HZ && enable)
> +			arasan_phy_set_dll(host, 1);
> +		return 0;
> +	}
> +
> +	if (priv->internal_phy_reg && clock >= MIN_PHY_CLK_HZ) {
> +		sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
> +		arasan_phy_set_dll(host, 0);
> +		arasan_phy_set_delaychain(host, 0);
> +		arasan_phy_dll_set_freq(host, clock);
> +		return 0;
> +	}
> +
> +	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
> +	arasan_phy_set_delaychain(host, 1);
> +
> +	return 0;
> +}
> +#endif
> +
>  static inline int arasan_zynqmp_set_in_tapdelay(u32 node_id, u32 itap_delay)
>  {
>  	int ret;
> @@ -585,6 +744,101 @@ static int sdhci_versal_sampleclk_set_phase(struct sdhci_host *host,
>  	return 0;
>  }
>  
> +/**
> + * sdhci_versal_net_emmc_sdcardclk_set_phase - Set eMMC Output Clock Tap Delays
> + *
> + * @host:		Pointer to the sdhci_host structure.
> + * @degrees:		The clock phase shift between 0 - 359.
> + * Return: 0
> + *
> + * Set eMMC Output Clock Tap Delays for Output path
> + */
> +static int sdhci_versal_net_emmc_sdcardclk_set_phase(struct sdhci_host *host, int degrees)
> +{
> +	struct mmc *mmc = (struct mmc *)host->mmc;
> +	int timing = mode2timing[mmc->selected_mode];
> +	u8 tap_delay, tap_max = 0;
> +	u32 regval;
> +
> +	switch (timing) {
> +	case MMC_TIMING_MMC_HS:
> +	case MMC_TIMING_MMC_DDR52:
> +		tap_max = 16;
> +		break;
> +	case MMC_TIMING_MMC_HS200:
> +	case MMC_TIMING_MMC_HS400:
> +		 /* For 200MHz clock, 32 Taps are available */
> +		tap_max = 32;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	tap_delay = (degrees * tap_max) / 360;
> +	/* Set the Clock Phase */
> +	if (tap_delay) {
> +		regval = sdhci_readl(host, PHY_CTRL_REG1);
> +		regval |= PHY_CTRL_OTAPDLY_ENA_MASK;
> +		sdhci_writel(host, regval, PHY_CTRL_REG1);
> +		regval &= ~PHY_CTRL_OTAPDLY_SEL_MASK;
> +		regval |= tap_delay << PHY_CTRL_OTAPDLY_SEL_SHIFT;
> +		sdhci_writel(host, regval, PHY_CTRL_REG1);
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * sdhci_versal_net_emmc_sampleclk_set_phase - Set eMMC Input Clock Tap Delays
> + *
> + * @host:		Pointer to the sdhci_host structure.
> + * @degrees:		The clock phase shift between 0 - 359.
> + * Return: 0
> + *
> + * Set eMMC Input Clock Tap Delays for Input path. If HS400 is selected,
> + * set strobe90 and strobe180 in PHY_CTRL_REG1.
> + */
> +static int sdhci_versal_net_emmc_sampleclk_set_phase(struct sdhci_host *host, int degrees)
> +{
> +	struct mmc *mmc = (struct mmc *)host->mmc;
> +	int timing = mode2timing[mmc->selected_mode];
> +	u8 tap_delay, tap_max = 0;
> +	u32 regval;
> +
> +	switch (timing) {
> +	case MMC_TIMING_MMC_HS:
> +	case MMC_TIMING_MMC_DDR52:
> +		tap_max = 32;
> +		break;
> +	case MMC_TIMING_MMC_HS400:
> +		/* Strobe select tap point for strb90 and strb180 */
> +		regval = sdhci_readl(host, PHY_CTRL_REG1);
> +		regval &= ~PHY_CTRL_STRB_SEL_MASK;
> +		regval |= VERSAL_NET_PHY_CTRL_STRB90_STRB180_VAL << PHY_CTRL_STRB_SEL_SHIFT;
> +		sdhci_writel(host, regval, PHY_CTRL_REG1);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	tap_delay = (degrees * tap_max) / 360;
> +	/* Set the Clock Phase */
> +	if (tap_delay) {
> +		regval = sdhci_readl(host, PHY_CTRL_REG1);
> +		regval |= PHY_CTRL_ITAP_CHG_WIN_MASK;
> +		sdhci_writel(host, regval, PHY_CTRL_REG1);
> +		regval |= PHY_CTRL_ITAPDLY_ENA_MASK;
> +		sdhci_writel(host, regval, PHY_CTRL_REG1);
> +		regval &= ~PHY_CTRL_ITAPDLY_SEL_MASK;
> +		regval |= tap_delay << PHY_CTRL_ITAPDLY_SEL_SHIFT;
> +		sdhci_writel(host, regval, PHY_CTRL_REG1);
> +		regval &= ~PHY_CTRL_ITAP_CHG_WIN_MASK;
> +		sdhci_writel(host, regval, PHY_CTRL_REG1);
> +	}
> +
> +	return 0;
> +}
> +
>  static int arasan_sdhci_set_tapdelay(struct sdhci_host *host)
>  {
>  	struct arasan_sdhci_priv *priv = dev_get_priv(host->mmc->dev);
> @@ -616,6 +870,19 @@ static int arasan_sdhci_set_tapdelay(struct sdhci_host *host)
>  		ret = sdhci_versal_sdcardclk_set_phase(host, oclk_phase);
>  		if (ret)
>  			return ret;
> +	} else if (IS_ENABLED(CONFIG_ARCH_VERSAL_NET) &&
> +		   device_is_compatible(dev, "xlnx,versal-net-5.1-emmc")) {
> +		if (mmc->clock >= MIN_PHY_CLK_HZ)
> +			if (iclk_phase == VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLY_CHAIN)
> +				iclk_phase = VERSAL_NET_EMMC_ICLK_PHASE_DDR52_DLL;
> +
> +		ret = sdhci_versal_net_emmc_sampleclk_set_phase(host, iclk_phase);
> +		if (ret)
> +			return ret;
> +
> +		ret = sdhci_versal_net_emmc_sdcardclk_set_phase(host, oclk_phase);
> +		if (ret)
> +			return ret;
>  	}
>  
>  	return 0;
> @@ -678,6 +945,14 @@ static void arasan_dt_parse_clk_phases(struct udevice *dev)
>  		}
>  	}
>  
> +	if (IS_ENABLED(CONFIG_ARCH_VERSAL_NET) &&
> +	    device_is_compatible(dev, "xlnx,versal-net-5.1-emmc")) {
> +		for (i = 0; i <= MMC_TIMING_MMC_HS400; i++) {
> +			clk_data->clk_phase_in[i] = versal_net_emmc_iclk_phases[i];
> +			clk_data->clk_phase_out[i] = versal_net_emmc_oclk_phases[i];
> +		}
> +	}
> +
>  	arasan_dt_read_clk_phase(dev, MMC_TIMING_LEGACY,
>  				 "clk-phase-legacy");
>  	arasan_dt_read_clk_phase(dev, MMC_TIMING_MMC_HS,
> @@ -706,6 +981,9 @@ static const struct sdhci_ops arasan_ops = {
>  	.platform_execute_tuning	= &arasan_sdhci_execute_tuning,
>  	.set_delay = &arasan_sdhci_set_tapdelay,
>  	.set_control_reg = &sdhci_set_control_reg,
> +#if defined(CONFIG_ARCH_VERSAL_NET)
> +	.config_dll = &arasan_sdhci_config_dll,
> +#endif
>  };
>  #endif
>  
> @@ -822,6 +1100,8 @@ static int arasan_sdhci_probe(struct udevice *dev)
>  		}
>  	}
>  #endif
> +	if (device_is_compatible(dev, "xlnx,versal-net-5.1-emmc"))
> +		priv->internal_phy_reg = true;
>  
>  	ret = clk_get_by_index(dev, 0, &clk);
>  	if (ret < 0) {
> @@ -905,7 +1185,7 @@ static int arasan_sdhci_of_to_plat(struct udevice *dev)
>  
>  	priv->host->name = dev->name;
>  
> -#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL)
> +#if defined(CONFIG_ARCH_ZYNQMP) || defined(CONFIG_ARCH_VERSAL) || defined(CONFIG_ARCH_VERSAL_NET)
>  	priv->host->ops = &arasan_ops;
>  	arasan_dt_parse_clk_phases(dev);
>  #endif
> @@ -933,6 +1213,7 @@ static int arasan_sdhci_bind(struct udevice *dev)
>  
>  static const struct udevice_id arasan_sdhci_ids[] = {
>  	{ .compatible = "arasan,sdhci-8.9a" },
> +	{ .compatible = "xlnx,versal-net-5.1-emmc" },
>  	{ }
>  };
>  

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

* Re: [2/4] mmc: sdhci: Check and call config_dll callback functions
  2023-01-10 11:31 ` [2/4] mmc: sdhci: Check and call config_dll callback functions Ashok Reddy Soma
@ 2023-01-31 12:40   ` Jaehoon Chung
  0 siblings, 0 replies; 13+ messages in thread
From: Jaehoon Chung @ 2023-01-31 12:40 UTC (permalink / raw)
  To: Ashok Reddy Soma, u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek



On 1/10/23 20:31, Ashok Reddy Soma wrote:
> Check if the low level driver supports config_dll callback function and
> call it if it does. Call with dll disable before calling set_clock and
> with dll enable after it.
> 
> Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
>  drivers/mmc/sdhci.c | 16 ++++++++++++++++
>  include/sdhci.h     |  2 ++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index a80ad8329a..181ab9b7cb 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -396,6 +396,14 @@ int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
>  		}
>  	}
>  
> +	if (host->ops && host->ops->config_dll) {
> +		ret = host->ops->config_dll(host, clock, false);
> +		if (ret) {
> +			printf("%s: Error while configuring dll\n", __func__);
> +			return ret;
> +		}
> +	}
> +
>  	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
>  		/*
>  		 * Check if the Host Controller supports Programmable Clock
> @@ -439,6 +447,14 @@ int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
>  	if (host->ops && host->ops->set_clock)
>  		host->ops->set_clock(host, div);
>  
> +	if (host->ops && host->ops->config_dll) {
> +		ret = host->ops->config_dll(host, clock, true);
> +		if (ret) {
> +			printf("%s: Error while configuring dll\n", __func__);
> +			return ret;
> +		}
> +	}
> +
>  	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
>  	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
>  		<< SDHCI_DIVIDER_HI_SHIFT;
> diff --git a/include/sdhci.h b/include/sdhci.h
> index 24b4599b85..64a3d309da 100644
> --- a/include/sdhci.h
> +++ b/include/sdhci.h
> @@ -272,6 +272,8 @@ struct sdhci_ops {
>  	void	(*set_clock)(struct sdhci_host *host, u32 div);
>  	int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
>  	int (*set_delay)(struct sdhci_host *host);
> +	/* Callback function to set DLL clock configuration */
> +	int (*config_dll)(struct sdhci_host *host, u32 clock, bool enable);>  	int	(*deferred_probe)(struct sdhci_host *host);
>  
>  	/**

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

* Re: [3/4] mmc: sdhci: Enable HS400 support if available in caps
  2023-01-10 11:31 ` [3/4] mmc: sdhci: Enable HS400 support if available in caps Ashok Reddy Soma
@ 2023-01-31 12:40   ` Jaehoon Chung
  0 siblings, 0 replies; 13+ messages in thread
From: Jaehoon Chung @ 2023-01-31 12:40 UTC (permalink / raw)
  To: Ashok Reddy Soma, u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek



On 1/10/23 20:31, Ashok Reddy Soma wrote:
> HS400 is indicated in bit63 of capability register in few IP's.
> Add a quirk to check this and add HS400 to host capabilities.
> 
> Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>

Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
>  drivers/mmc/sdhci.c | 4 ++++
>  include/sdhci.h     | 3 +++
>  2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
> index 181ab9b7cb..c6b250b9a1 100644
> --- a/drivers/mmc/sdhci.c
> +++ b/drivers/mmc/sdhci.c
> @@ -995,6 +995,10 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
>  		cfg->host_caps |= MMC_CAP(UHS_SDR50);
>  	}
>  
> +	if ((host->quirks & SDHCI_QUIRK_CAPS_BIT63_FOR_HS400) &&
> +	    (caps_1 & SDHCI_SUPPORT_HS400))
> +		cfg->host_caps |= MMC_CAP(MMC_HS_400);
> +
>  	if (caps_1 & SDHCI_SUPPORT_DDR50)
>  		cfg->host_caps |= MMC_CAP(UHS_DDR50);
>  
> diff --git a/include/sdhci.h b/include/sdhci.h
> index 64a3d309da..70fefca2a9 100644
> --- a/include/sdhci.h
> +++ b/include/sdhci.h
> @@ -189,6 +189,7 @@
>  #define  SDHCI_SUPPORT_SDR50	0x00000001
>  #define  SDHCI_SUPPORT_SDR104	0x00000002
>  #define  SDHCI_SUPPORT_DDR50	0x00000004
> +#define  SDHCI_SUPPORT_HS400	BIT(31)
>  #define  SDHCI_USE_SDR50_TUNING	0x00002000
>  
>  #define  SDHCI_CLOCK_MUL_MASK	0x00FF0000
> @@ -248,6 +249,8 @@
>  #define SDHCI_QUIRK_USE_WIDE8		(1 << 8)
>  #define SDHCI_QUIRK_NO_1_8_V		(1 << 9)
>  #define SDHCI_QUIRK_SUPPORT_SINGLE	(1 << 10)
> +/* Capability register bit-63 indicates HS400 support */
> +#define SDHCI_QUIRK_CAPS_BIT63_FOR_HS400	BIT(11)
>  
>  /* to make gcc happy */
>  struct sdhci_host;

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

* Re: [4/4] mmc: zynq_sdhci: Add support and quirk for HS400
  2023-01-10 11:31 ` [4/4] mmc: zynq_sdhci: Add support and quirk for HS400 Ashok Reddy Soma
@ 2023-01-31 12:40   ` Jaehoon Chung
  0 siblings, 0 replies; 13+ messages in thread
From: Jaehoon Chung @ 2023-01-31 12:40 UTC (permalink / raw)
  To: Ashok Reddy Soma, u-boot
  Cc: peng.fan, jh80.chung, kever.yang, hayashi.kunihiko,
	alpernebiyasak, xypron.glpk, git, michal.simek



On 1/10/23 20:31, Ashok Reddy Soma wrote:
> Add support for HS400 in mode2timing array.
> Add a quirk for Versal NET platform to indicate that HS400 is supported
> through bit63 of capability register.
> 
> Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@amd.com>

Reviewd-by: Jaehoon Chung <jh80.chung@samsung.com>

Best Regards,
Jaehoon Chung

> ---
>  drivers/mmc/zynq_sdhci.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
> index 8415da3373..72de6c6227 100644
> --- a/drivers/mmc/zynq_sdhci.c
> +++ b/drivers/mmc/zynq_sdhci.c
> @@ -153,6 +153,7 @@ static const u8 mode2timing[] = {
>  	[UHS_DDR50] = MMC_TIMING_UHS_DDR50,
>  	[UHS_SDR104] = MMC_TIMING_UHS_SDR104,
>  	[MMC_HS_200] = MMC_TIMING_MMC_HS200,
> +	[MMC_HS_400] = MMC_TIMING_MMC_HS400,
>  };
>  
>  #if defined(CONFIG_ARCH_VERSAL_NET)
> @@ -1133,6 +1134,10 @@ static int arasan_sdhci_probe(struct udevice *dev)
>  	if (priv->no_1p8)
>  		host->quirks |= SDHCI_QUIRK_NO_1_8_V;
>  
> +	if (CONFIG_IS_ENABLED(ARCH_VERSAL_NET) &&
> +	    device_is_compatible(dev, "xlnx,versal-net-5.1-emmc"))
> +		host->quirks |= SDHCI_QUIRK_CAPS_BIT63_FOR_HS400;
> +
>  	plat->cfg.f_max = CONFIG_ZYNQ_SDHCI_MAX_FREQ;
>  
>  	ret = mmc_of_parse(dev, &plat->cfg);

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

* Re: [0/4] Add eMMC 5.1 support for Versal NET
  2023-01-26  2:29   ` Jaehoon Chung
@ 2023-01-31 13:07     ` Michal Simek
  2023-01-31 23:11       ` Jaehoon Chung
  0 siblings, 1 reply; 13+ messages in thread
From: Michal Simek @ 2023-01-31 13:07 UTC (permalink / raw)
  To: Jaehoon Chung, 'Ashok Reddy Soma', u-boot
  Cc: peng.fan, kever.yang, hayashi.kunihiko, alpernebiyasak, xypron.glpk, git

Hi Jaehoon,

On 1/26/23 03:29, Jaehoon Chung wrote:
> Hi,
> 
>> -----Original Message-----
>> From: Michal Simek <michal.simek@amd.com>
>> Sent: Tuesday, January 24, 2023 10:02 PM
>> To: Ashok Reddy Soma <ashok.reddy.soma@amd.com>; u-boot@lists.denx.de; Jaehoon Chung
>> <jh80.chung@samsung.com>
>> Cc: peng.fan@nxp.com; kever.yang@rock-chips.com; hayashi.kunihiko@socionext.com;
>> alpernebiyasak@gmail.com; xypron.glpk@gmx.de; git@amd.com
>> Subject: Re: [0/4] Add eMMC 5.1 support for Versal NET
>>
>> Hi Jaehoon,
>>
>> On 1/10/23 12:31, Ashok Reddy Soma wrote:
>>> This patch series,
>>>    - Add support for eMMC5.1 on Versal NET platform by adding new compatible
>>>      string and PHY support.
>>>    - Add support for input and output tap delays for eMMC
>>>    - Add support for enabling HS400 in host capabilities by checking quirk.
>>>    - Add quirk to support HS400 for Versal NET
>>>
>>> Ashok Reddy Soma (4):
>>>     mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform
>>>     mmc: sdhci: Check and call config_dll callback functions
>>>     mmc: sdhci: Enable HS400 support if available in caps
>>>     mmc: zynq_sdhci: Add support and quirk for HS400
>>>
>>>    drivers/mmc/sdhci.c      |  20 +++
>>>    drivers/mmc/zynq_sdhci.c | 292 ++++++++++++++++++++++++++++++++++++++-
>>>    include/sdhci.h          |   5 +
>>>    3 files changed, 314 insertions(+), 3 deletions(-)
>>>
>>
>> Can you please review this series?
> 
> Sorry for too late. I will review them.

I see you just reviewed it. Are you going to pick it up to your tree or do you 
want me to queue it via my tree? Both ways work for me.

Thanks,
Michal

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

* RE: [0/4] Add eMMC 5.1 support for Versal NET
  2023-01-31 13:07     ` Michal Simek
@ 2023-01-31 23:11       ` Jaehoon Chung
  0 siblings, 0 replies; 13+ messages in thread
From: Jaehoon Chung @ 2023-01-31 23:11 UTC (permalink / raw)
  To: 'Michal Simek', 'Ashok Reddy Soma', u-boot
  Cc: peng.fan, kever.yang, hayashi.kunihiko, alpernebiyasak, xypron.glpk, git

Hi,

> -----Original Message-----
> From: Michal Simek <michal.simek@amd.com>
> Sent: Tuesday, January 31, 2023 10:08 PM
> To: Jaehoon Chung <jh80.chung@samsung.com>; 'Ashok Reddy Soma' <ashok.reddy.soma@amd.com>; u-
> boot@lists.denx.de
> Cc: peng.fan@nxp.com; kever.yang@rock-chips.com; hayashi.kunihiko@socionext.com;
> alpernebiyasak@gmail.com; xypron.glpk@gmx.de; git@amd.com
> Subject: Re: [0/4] Add eMMC 5.1 support for Versal NET
> 
> Hi Jaehoon,
> 
> On 1/26/23 03:29, Jaehoon Chung wrote:
> > Hi,
> >
> >> -----Original Message-----
> >> From: Michal Simek <michal.simek@amd.com>
> >> Sent: Tuesday, January 24, 2023 10:02 PM
> >> To: Ashok Reddy Soma <ashok.reddy.soma@amd.com>; u-boot@lists.denx.de; Jaehoon Chung
> >> <jh80.chung@samsung.com>
> >> Cc: peng.fan@nxp.com; kever.yang@rock-chips.com; hayashi.kunihiko@socionext.com;
> >> alpernebiyasak@gmail.com; xypron.glpk@gmx.de; git@amd.com
> >> Subject: Re: [0/4] Add eMMC 5.1 support for Versal NET
> >>
> >> Hi Jaehoon,
> >>
> >> On 1/10/23 12:31, Ashok Reddy Soma wrote:
> >>> This patch series,
> >>>    - Add support for eMMC5.1 on Versal NET platform by adding new compatible
> >>>      string and PHY support.
> >>>    - Add support for input and output tap delays for eMMC
> >>>    - Add support for enabling HS400 in host capabilities by checking quirk.
> >>>    - Add quirk to support HS400 for Versal NET
> >>>
> >>> Ashok Reddy Soma (4):
> >>>     mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform
> >>>     mmc: sdhci: Check and call config_dll callback functions
> >>>     mmc: sdhci: Enable HS400 support if available in caps
> >>>     mmc: zynq_sdhci: Add support and quirk for HS400
> >>>
> >>>    drivers/mmc/sdhci.c      |  20 +++
> >>>    drivers/mmc/zynq_sdhci.c | 292 ++++++++++++++++++++++++++++++++++++++-
> >>>    include/sdhci.h          |   5 +
> >>>    3 files changed, 314 insertions(+), 3 deletions(-)
> >>>
> >>
> >> Can you please review this series?
> >
> > Sorry for too late. I will review them.
> 
> I see you just reviewed it. Are you going to pick it up to your tree or do you
> want me to queue it via my tree? Both ways work for me.

I have picked this and I will do PR today.  

Best Regards,
Jaehoon Chung

> 
> Thanks,
> Michal


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

end of thread, other threads:[~2023-01-31 23:11 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-10 11:31 [0/4] Add eMMC 5.1 support for Versal NET Ashok Reddy Soma
2023-01-10 11:31 ` [1/4] mmc: zynq_sdhci: Add support for eMMC5.1 for Versal NET platform Ashok Reddy Soma
2023-01-31 12:40   ` Jaehoon Chung
2023-01-10 11:31 ` [2/4] mmc: sdhci: Check and call config_dll callback functions Ashok Reddy Soma
2023-01-31 12:40   ` Jaehoon Chung
2023-01-10 11:31 ` [3/4] mmc: sdhci: Enable HS400 support if available in caps Ashok Reddy Soma
2023-01-31 12:40   ` Jaehoon Chung
2023-01-10 11:31 ` [4/4] mmc: zynq_sdhci: Add support and quirk for HS400 Ashok Reddy Soma
2023-01-31 12:40   ` Jaehoon Chung
2023-01-24 13:01 ` [0/4] Add eMMC 5.1 support for Versal NET Michal Simek
2023-01-26  2:29   ` Jaehoon Chung
2023-01-31 13:07     ` Michal Simek
2023-01-31 23:11       ` Jaehoon Chung

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.