All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Kaustabh Chakraborty" <kauschluss@disroot.org>
To: "Henrik Grimler" <henrik@grimler.se>,
	"Kaustabh Chakraborty" <kauschluss@disroot.org>
Cc: "Peng Fan" <peng.fan@nxp.com>, <u-boot@lists.denx.de>,
	"Minkyu Kang" <mk7.kang@samsung.com>,
	"Tom Rini" <trini@konsulko.com>,
	"Jaehoon Chung" <jh80.chung@samsung.com>,
	"Anand Moon" <linux.amoon@gmail.com>,
	"Sam Protsenko" <semen.protsenko@linaro.org>,
	"Lukas Timmermann" <uboot@timmermann.space>
Subject: Re: [PATCH v2 1/4] mmc: exynos_dw_mmc: add proper init sequence for HS400 support
Date: Thu, 07 May 2026 01:33:28 +0530	[thread overview]
Message-ID: <DIBV2GMI0TCA.2NHUZI89OJUA0@disroot.org> (raw)
In-Reply-To: <20260505190729.GA6951@l14.localdomain>

On 2026-05-05 21:07 +02:00, Henrik Grimler wrote:
> Hi Kaustabh,
>
> On Sun, May 03, 2026 at 05:51:26PM +0530, Kaustabh Chakraborty wrote:
>> HS400 support was added, but configuration necessary for HS400 support
>> was left out. Add necessary changes, which includes:
>> - Device tree properties, such as "samsung,dw-mshc-hs400-timing" and
>>   "samsung,read-strobe-delay", which function as per dt-bindings.
>> - Registers related to HS400, which are necessary to enable HS400+ support.
>> - Appropriate timing tunings for the HS400 mode.
>> 
>> Note that these changes are loosely based off of its Linux kernel
>> counterpart.
>> 
>> Fixes: bbe3b9fa0922 ("mmc: exynos_dw_mmc: add support for MMC HS200 and HS400 modes")
>> Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
>
> Reviewed-by: Henrik Grimler <henrik@grimler.se>
>
> This works fine on exynos5422-odroid-xu4 without hs400. I was not able
> to get hs400 working on the device, seems more changes than just dts
> update are needed.

Do you have any logs or traces which may be able to help pinpoint it?
I can try to figure out the issue(s) if you want me to.

>
> Best regards,
> Henrik Grimler
>
>> ---
>>  arch/arm/mach-exynos/include/mach/dwmmc.h |  5 ++
>>  drivers/mmc/exynos_dw_mmc.c               | 81 +++++++++++++++++++++++++++++++
>>  2 files changed, 86 insertions(+)
>> 
>> diff --git a/arch/arm/mach-exynos/include/mach/dwmmc.h b/arch/arm/mach-exynos/include/mach/dwmmc.h
>> index 4432deedef7..50081326c25 100644
>> --- a/arch/arm/mach-exynos/include/mach/dwmmc.h
>> +++ b/arch/arm/mach-exynos/include/mach/dwmmc.h
>> @@ -15,6 +15,11 @@
>>  #define DWMCI_SET_DRV_CLK(x)		((x) << 16)
>>  #define DWMCI_SET_DIV_RATIO(x)		((x) << 24)
>>  
>> +/* HS400 Related Registers */
>> +#define DWMCI_HS400_DQS_EN		0x180
>> +#define DWMCI_HS400_ASYNC_FIFO_CTRL	0x184
>> +#define DWMCI_HS400_DLINE_CTRL		0x188
>> +
>>  /* Protector Register */
>>  #define DWMCI_EMMCP_BASE		0x1000
>>  #define EMMCP_MPSECURITY		(DWMCI_EMMCP_BASE + 0x0010)
>> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c
>> index 7ccd113bd79..6558cdc803d 100644
>> --- a/drivers/mmc/exynos_dw_mmc.c
>> +++ b/drivers/mmc/exynos_dw_mmc.c
>> @@ -8,6 +8,7 @@
>>  #include <dwmmc.h>
>>  #include <asm/global_data.h>
>>  #include <malloc.h>
>> +#include <mmc.h>
>>  #include <errno.h>
>>  #include <asm/arch/dwmmc.h>
>>  #include <asm/arch/clk.h>
>> @@ -30,6 +31,14 @@
>>  #define CLKSEL_UP_SAMPLE(x, y)		(((x) & ~CLKSEL_CCLK_SAMPLE(7)) | \
>>  					 CLKSEL_CCLK_SAMPLE(y))
>>  
>> +/* 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)
>> +
>>  /**
>>   * DOC: Quirk flags for different Exynos DW MMC blocks
>>   *
>> @@ -71,6 +80,11 @@ struct dwmci_exynos_priv_data {
>>  	struct clk clk;
>>  	u32 sdr_timing;
>>  	u32 ddr_timing;
>> +	u32 hs400_timing;
>> +	u32 tuned_sample;
>> +	u32 dqs_delay;
>> +	u32 saved_dqs_en;
>> +	u32 saved_strobe_ctrl;
>>  	const struct exynos_dwmmc_variant *chip;
>>  };
>>  
>> @@ -162,6 +176,27 @@ static u8 exynos_dwmmc_get_ciu_div(struct dwmci_host *host)
>>  				& DWMCI_DIVRATIO_MASK) + 1;
>>  }
>>  
>> +static void exynos_config_hs400(struct dwmci_host *host, enum bus_mode mode)
>> +{
>> +	struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
>> +	u32 dqs, strobe;
>> +
>> +	dqs = priv->saved_dqs_en;
>> +	strobe = priv->saved_strobe_ctrl;
>> +
>> +	switch (mode) {
>> +	case MMC_HS_400:
>> +		dqs |= DATA_STROBE_EN;
>> +		strobe = DQS_CTRL_RD_DELAY(strobe, priv->dqs_delay);
>> +		break;
>> +	default:
>> +		dqs &= ~DATA_STROBE_EN;
>> +	}
>> +
>> +	dwmci_writel(host, DWMCI_HS400_DQS_EN, dqs);
>> +	dwmci_writel(host, DWMCI_HS400_DLINE_CTRL, strobe);
>> +}
>> +
>>  /* Configure CLKSEL register with chosen timing values */
>>  static int exynos_dwmci_clksel(struct dwmci_host *host)
>>  {
>> @@ -170,6 +205,9 @@ static int exynos_dwmci_clksel(struct dwmci_host *host)
>>  	u32 timing;
>>  
>>  	switch (host->mmc->selected_mode) {
>> +	case MMC_HS_400:
>> +		timing = CLKSEL_UP_SAMPLE(priv->hs400_timing, priv->tuned_sample);
>> +		break;
>>  	case MMC_DDR_52:
>>  		timing = priv->ddr_timing;
>>  		break;
>> @@ -186,6 +224,9 @@ static int exynos_dwmci_clksel(struct dwmci_host *host)
>>  
>>  	dwmci_writel(host, priv->chip->clksel, timing);
>>  
>> +	if (CONFIG_IS_ENABLED(MMC_HS400_SUPPORT))
>> +		exynos_config_hs400(host, host->mmc->selected_mode);
>> +
>>  	return 0;
>>  }
>>  
>> @@ -223,6 +264,16 @@ static void exynos_dwmci_board_init(struct dwmci_host *host)
>>  {
>>  	struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
>>  
>> +	if (CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)) {
>> +		priv->saved_strobe_ctrl = dwmci_readl(host, DWMCI_HS400_DLINE_CTRL);
>> +		priv->saved_dqs_en = dwmci_readl(host, DWMCI_HS400_DQS_EN);
>> +		priv->saved_dqs_en |= AXI_NON_BLOCKING_WR;
>> +		dwmci_writel(host, DWMCI_HS400_DQS_EN, priv->saved_dqs_en);
>> +		if (!priv->dqs_delay)
>> +			priv->dqs_delay =
>> +				DQS_CTRL_GET_RD_DELAY(priv->saved_strobe_ctrl);
>> +	}
>> +
>>  	if (priv->chip->quirks & DWMCI_QUIRK_DISABLE_SMU) {
>>  		dwmci_writel(host, EMMCP_MPSBEGIN0, 0);
>>  		dwmci_writel(host, EMMCP_SEND0, 0);
>> @@ -319,6 +370,22 @@ static int exynos_dwmmc_of_to_plat(struct udevice *dev)
>>  				   DWMCI_SET_DIV_RATIO(div);
>>  	}
>>  
>> +	err = dev_read_u32_array(dev, "samsung,dw-mshc-hs400-timing", timing, 2);
>> +	if (err) {
>> +		debug("DWMMC%d: Can't get hs400-timings, using ddr-timings\n",
>> +		      host->dev_index);
>> +		priv->hs400_timing = priv->ddr_timing;
>> +	} else {
>> +		priv->hs400_timing = DWMCI_SET_SAMPLE_CLK(timing[0]) |
>> +				     DWMCI_SET_DRV_CLK(timing[1]) |
>> +				     DWMCI_SET_DIV_RATIO(1);
>> +		if (dev_read_u32(dev, "samsung,read-strobe-delay", &priv->dqs_delay)) {
>> +			priv->dqs_delay = 0;
>> +			debug("DWMMC%d: read-strobe-delay is not found, assuming usage of default value\n",
>> +			      host->dev_index);
>> +		}
>> +	}
>> +
>>  	host->buswidth = dev_read_u32_default(dev, "bus-width", 4);
>>  	host->fifo_depth = dev_read_u32_default(dev, "fifo-depth", 0);
>>  	host->bus_hz = dev_read_u32_default(dev, "clock-frequency", 0);
>> @@ -356,6 +423,16 @@ static int exynos_dwmmc_get_best_clksmpl(u8 candidates)
>>  	return -EIO;
>>  }
>>  
>> +static int dw_mci_exynos_prepare_hs400_tuning(struct dwmci_host *host)
>> +{
>> +	struct dwmci_exynos_priv_data *priv = exynos_dwmmc_get_priv(host);
>> +
>> +	dwmci_writel(host, priv->chip->clksel, priv->hs400_timing);
>> +	host->bus_hz = exynos_dwmci_get_clk(host, host->clock);
>> +
>> +	return 0;
>> +}
>> +
>>  static int exynos_dwmmc_execute_tuning(struct udevice *dev, u32 opcode)
>>  {
>>  	struct dwmci_exynos_priv_data *priv = dev_get_priv(dev);
>> @@ -365,6 +442,9 @@ static int exynos_dwmmc_execute_tuning(struct udevice *dev, u32 opcode)
>>  	u32 clksel;
>>  	int ret;
>>  
>> +	if (mmc->hs400_tuning)
>> +		dw_mci_exynos_prepare_hs400_tuning(host);
>> +
>>  	clksel = dwmci_readl(host, priv->chip->clksel);
>>  	start_smpl = CLKSEL_CCLK_SAMPLE(clksel);
>>  
>> @@ -387,6 +467,7 @@ static int exynos_dwmmc_execute_tuning(struct udevice *dev, u32 opcode)
>>  		return ret;
>>  	}
>>  
>> +	priv->tuned_sample = ret;
>>  	dwmci_writel(host, priv->chip->clksel, CLKSEL_UP_SAMPLE(clksel, ret));
>>  
>>  	return 0;
>> 
>> -- 
>> 2.53.0
>> 


  reply	other threads:[~2026-05-07  4:29 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-03 12:21 [PATCH v2 0/4] HS400 and HS400ES support for Exynos DW-MMC drivers Kaustabh Chakraborty
2026-05-03 12:21 ` [PATCH v2 1/4] mmc: exynos_dw_mmc: add proper init sequence for HS400 support Kaustabh Chakraborty
2026-05-05 19:07   ` Henrik Grimler
2026-05-06 20:03     ` Kaustabh Chakraborty [this message]
2026-05-07 19:24       ` Henrik Grimler
2026-05-08 15:27         ` Anand Moon
2026-05-13 10:58     ` Peng Fan
2026-05-13 12:52       ` Kaustabh Chakraborty
2026-05-13 13:03         ` Henrik Grimler
2026-05-03 12:21 ` [PATCH v2 2/4] mmc: dw_mmc: setup set_enhanced_strobe ops in driver Kaustabh Chakraborty
2026-05-03 12:21 ` [PATCH v2 3/4] mmc: exynos_dw_mmc: add support for HS400ES Kaustabh Chakraborty
2026-05-03 12:21 ` [PATCH v2 4/4] configs: exynos-mobile: enable support for HS400ES in MMC driver Kaustabh Chakraborty

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=DIBV2GMI0TCA.2NHUZI89OJUA0@disroot.org \
    --to=kauschluss@disroot.org \
    --cc=henrik@grimler.se \
    --cc=jh80.chung@samsung.com \
    --cc=linux.amoon@gmail.com \
    --cc=mk7.kang@samsung.com \
    --cc=peng.fan@nxp.com \
    --cc=semen.protsenko@linaro.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=uboot@timmermann.space \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.