RE: [PATCH v19 12/12] mmc: renesas_sdhi: Add HS400 enhanced strobe support for RZ/G3L

Biju Das <[email protected]>
Newsgroups org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-mmc
Message-ID <TY3PR01MB11346F6F629176C46DEC3498D86FD2@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi All,

> -----Original Message-----
> From: Biju <[email protected]>
> Sent: 09 July 2026 20:29
> Subject: [PATCH v19 12/12] mmc: renesas_sdhi: Add HS400 enhanced strobe support for RZ/G3L
> 
> From: Biju Das <[email protected]>
> 
> The RZ/G3L SoC supports HS400 enhanced strobe mode, which requires additional SCC register programming
> beyond the standard HS400 path.
> 
> Introduce a TMIO_MMC_HS400ES flag (bit 17) to identify controllers that support enhanced strobe. Add
> renesas_sdhi_hs400_enhanced_strobe(),
> which, when ios->enhanced_strobe is set, disables DTSEL in SCC_CKSEL, clears TAPEN in SCC_DTCNTL,
> programs SCC_TMPPORT3, sets HWADJ2 to 0xFF, enables the HS400 interface mode bit in CTL_SDIF_MODE, sets
> HS400EN2 in HS400MODE2, and sets both HS400EN and the new HS400MODE1_ENHANCED_STROBE bit (BIT(30)) in
> TMPPORT2. On exit from enhanced strobe, only the enhanced strobe bit is cleared. Register this callback
> as host->ops.hs400_enhanced_strobe for controllers carrying the TMIO_MMC_HS400ES flag.
> 
> Update renesas_sdhi_reset_hs400_mode() to also mask off HS400MODE1_ENHANCED_STROBE from TMPPORT2 when
> TMIO_MMC_HS400ES is set, ensuring a clean reset on mode exit.
> 
> Enable the TMIO_MMC_HS400ES flag in of_data_rzg3l to finalize support.
> 
> Signed-off-by: Biju Das <[email protected]>
> ---
> v18->v19:
>  * Updated commit description.
>  * HS400ES support is enabled based on of_data.
>  * Fixed the space in HS400ES comment block.
> v18:
>  * New patch.
> ---
>  drivers/mmc/host/renesas_sdhi_core.c          | 49 +++++++++++++++++--
>  drivers/mmc/host/renesas_sdhi_internal_dmac.c |  2 +-
>  include/linux/platform_data/tmio.h            |  3 ++
>  3 files changed, 49 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
> index ae6b7d8c5b98..894da06b0d2b 100644
> --- a/drivers/mmc/host/renesas_sdhi_core.c
> +++ b/drivers/mmc/host/renesas_sdhi_core.c
> @@ -308,7 +308,8 @@ static int renesas_sdhi_card_busy(struct mmc_host *mmc)
>  #define SH_MOBILE_SDHI_SCC_SMPCMP_CMD_REQUP	BIT(24)
>  #define SH_MOBILE_SDHI_SCC_SMPCMP_CMD_ERR	(BIT(8) | BIT(24))
> 
> -#define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN	BIT(31)
> +#define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN		BIT(31)
> +#define SH_MOBILE_SDHI_SCC_HS400MODE1_ENHANCED_STROBE	BIT(30)
> 
>  /* Definitions for values the SH_MOBILE_SDHI_SCC_TMPPORT4 register */
>  #define SH_MOBILE_SDHI_SCC_TMPPORT4_DLL_ACC_START	BIT(0)
> @@ -589,6 +590,8 @@ static void renesas_sdhi_adjust_hs400_mode_disable(struct tmio_mmc_host *host)
> static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
>  					  struct renesas_sdhi *priv)
>  {
> +	u32 val = ~(SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
> +host->pdata->osel_tmpout);
> +
>  	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
>  			sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
> 
> @@ -598,10 +601,11 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
> 
>  	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DT2FF, priv->scc_tappos);
> 
> +	if (host->pdata->flags & TMIO_MMC_HS400ES)
> +		val &= ~SH_MOBILE_SDHI_SCC_HS400MODE1_ENHANCED_STROBE;
> +
>  	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2,
> -		       ~(SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
> -			 host->pdata->osel_tmpout) &
> -			sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
> +		       val & sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));
> 
>  	if (host->pdata->flags & TMIO_MMC_HS400MODE2)
>  		sd_scc_write32(host, priv, RZG3L_SDHI_SCC_HS400MODE2, 0x0); @@ -806,6 +810,41 @@ static int
> renesas_sdhi_execute_tuning(struct mmc_host *mmc, u32 opcode)
>  	return ret;
>  }
> 
> +static void renesas_sdhi_hs400_enhanced_strobe(struct mmc_host *mmc,
> +					       struct mmc_ios *ios)
> +{

Looks it is false positive as mentioned by sashiko[1], I can enter
and exit suspend to RAM without any issues. On this platform during
STR all power supplies down except PMIC which puts the DDR into retention mode.

[1] https://sashiko.dev/#/patchset/20260709192916.630794-1-biju.das.jz%40bp.renesas.com


root@smarc-rzg3l:~# cat /sys/kernel/debug/mmc0/ios
clock:          150000000 Hz
actual clock:   150000000 Hz
vdd:            21 (3.3 ~ 3.4 V)
bus mode:       2 (push-pull)
chip select:    0 (don't care)
power mode:     2 (on)
bus width:      3 (8 bits)
timing spec:    10 (mmc HS400 enhanced strobe)
signal voltage: 1 (1.80 V)
driver type:    1 (driver type A)

root@smarc-rzg3l:~# mount -t auto /dev/mmcblk0p2 /media/
[   75.719668] EXT4-fs (mmcblk0p2): recovery complete
[   75.725806] EXT4-fs (mmcblk0p2): mounted filesystem 3a87d114-78ab-4be0-8fac-d055b25f4bd0 r/w with ordered data mode. Quota mode: none.
root@smarc-rzg3l:~#

echo TEST > /media/1.txt

root@smarc-rzg3l:~# echo mem > /sys/power/state
[  105.965920] PM: suspend entry (deep)
[  105.980163] Filesystems sync: 0.009 seconds
[  105.992243] Freezing user space processes
[  106.001271] Freezing user space processes completed (elapsed 0.003 seconds)
[  106.008260] OOM killer disabled.
[  106.011496] Freezing remaining freezable tasks
[  106.017309] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[  106.024713] printk: Suspending console(s) (use no_console_suspend to debug)
NOTICE:  BL2: v2.10.5(release):2.10.5/rzg3l_1.0.1_rc2
NOTICE:  BL2: Built : 09:19:29, Jun 16 2026
INFO:    BL2: Doing platform setup
INFO:    Configuring TrustZone Controller
INFO:    Total 3 regions set.
INFO:    Configuring TrustZone Controller
INFO:    Total 1 regions set.
INFO:    Configuring TrustZone Controller
INFO:    Total 1 regions set.
INFO:    Loading image id=39 at address 0x44428
INFO:    Image id=39 loaded: 0x44428 - 0x45428
INFO:    DDR: Retention Exit (Rev. 02.05)
NOTICE:  BL2: SYS_LSI_MODE: 0x12061
NOTICE:  BL2: SYS_LSI_DEVID: 0x87d9447
INFO:    BL2: Skip loading image id 3
INFO:    BL2: Skip loading image id 5
NOTICE:  BL2: Booting BL31
INFO:    Entry point address = 0x44000000
INFO:    SPSR = 0x3cd
[  106.061768] renesas-gbeth 11c30000.ethernet end0: Link is Down
[  106.065811] Disabling non-boot CPUs ...
[  106.068100] psci: CPU3 killed (polled 4 ms)
[  106.071161] psci: CPU2 killed (polled 4 ms)
[  106.075159] psci: CPU1 killed (polled 4 ms)
[  106.076800] Enabling non-boot CPUs ...
[  106.077070] Detected VIPT I-cache on CPU1
[  106.077135] GICv3: CPU1: found redistributor 100 region 0:0x0000000012460000
[  106.077182] CPU1: Booted secondary processor 0x0000000100 [0x412fd050]
[  106.078267] CPU1 is up
[  106.078429] Detected VIPT I-cache on CPU2
[  106.078469] GICv3: CPU2: found redistributor 200 region 0:0x0000000012480000
[  106.078502] CPU2: Booted secondary processor 0x0000000200 [0x412fd050]
[  106.079474] CPU2 is up
[  106.079661] Detected VIPT I-cache on CPU3
[  106.079708] GICv3: CPU3: found redistributor 300 region 0:0x00000000124a0000
[  106.079751] CPU3: Booted secondary processor 0x0000000300 [0x412fd050]
[  106.080888] CPU3 is up
[  106.095014] dwmac4: Master AXI performs fixed burst length
[  106.095061] renesas-gbeth 11c30000.ethernet end0: No Safety Features support found
[  106.095104] renesas-gbeth 11c30000.ethernet end0: IEEE 1588-2008 Advanced Timestamp supported
[  106.096191] renesas-gbeth 11c30000.ethernet end0: configuring for phy/rgmii-id link mode
[  106.111005] dwmac4: Master AXI performs fixed burst length
[  106.111035] renesas-gbeth 11c40000.ethernet end1: No Safety Features support found
[  106.111066] renesas-gbeth 11c40000.ethernet end1: IEEE 1588-2008 Advanced Timestamp supported
[  106.112144] renesas-gbeth 11c40000.ethernet end1: configuring for phy/rgmii-id link mode
[  106.283664] OOM killer enabled.
[  106.286800] Restarting tasks: Starting
[  106.292440] Restarting tasks: Done
[  106.296062] random: crng reseeded on system resumption
[  106.301515] PM: suspend exit
[  109.062679] renesas-gbeth 11c30000.ethernet end0: Link is Up - 1Gbps/Full - flow control rx/tx

root@smarc-rzg3l:~# cat /media/1.txt
TEST
root@smarc-rzg3l:~# cat /sys/kernel/debug/mmc0/ios
clock:          150000000 Hz
actual clock:   150000000 Hz
vdd:            21 (3.3 ~ 3.4 V)
bus mode:       2 (push-pull)
chip select:    0 (don't care)
power mode:     2 (on)
bus width:      3 (8 bits)
timing spec:    10 (mmc HS400 enhanced strobe)
signal voltage: 1 (1.80 V)
driver type:    1 (driver type A)
root@smarc-rzg3l:~#


> +	struct tmio_mmc_host *host = mmc_priv(mmc);
> +	struct renesas_sdhi *priv = host_to_priv(host);
> +	u32 val = sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2);
> +
> +	if (!(host->pdata->flags & TMIO_MMC_HS400ES))
> +		return;
> +
> +	if (ios->enhanced_strobe) {
> +		sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL,
> +			       ~SH_MOBILE_SDHI_SCC_CKSEL_DTSEL &
> +			       sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_CKSEL));

OK,  hardware manual mention this "When this bit is switched, stop the SD clock output from the SD/MMC host interface (set
SCLKEN in SD_CLK_CTRL to 0)."

So, I will disable CLK_CTL_SCLKEN before changing these registers.

Cheers,
Biju

> +
> +		sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
> +			       ~SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN &
> +			       sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL));
> +
> +		sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT3, BIT(8) | BIT(9));
> +		sd_scc_write32(host, priv, RZG3L_SDHI_SCC_HWADJ2, 0xFF);
> +		sd_ctrl_write16(host, CTL_SDIF_MODE, SDIF_MODE_HS400 |
> +				sd_ctrl_read16(host, CTL_SDIF_MODE));
> +		sd_scc_write32(host, priv, RZG3L_SDHI_SCC_HS400MODE2,
> +			       RZG3L_SDHI_SCC_HS400MODE2_HS400EN2);
> +
> +		val |= SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
> +		       SH_MOBILE_SDHI_SCC_HS400MODE1_ENHANCED_STROBE;
> +	} else {
> +		val &= ~SH_MOBILE_SDHI_SCC_HS400MODE1_ENHANCED_STROBE;
> +	}
> +
> +	sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2, val); }
> +
>  static bool renesas_sdhi_manual_correction(struct tmio_mmc_host *host, bool use_4tap)  {
>  	struct renesas_sdhi *priv = host_to_priv(host); @@ -1358,6 +1397,8 @@ int
> renesas_sdhi_probe(struct platform_device *pdev,
>  		host->ops.prepare_hs400_tuning = renesas_sdhi_prepare_hs400_tuning;
>  		host->ops.hs400_downgrade = renesas_sdhi_disable_scc;
>  		host->ops.hs400_complete = renesas_sdhi_hs400_complete;
> +		if (host->pdata->flags & TMIO_MMC_HS400ES)
> +			host->ops.hs400_enhanced_strobe =
> +renesas_sdhi_hs400_enhanced_strobe;
>  	}
> 
>  	sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask_all); diff --git
> a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> index 4000673ed7f8..ea993197aff2 100644
> --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> @@ -175,7 +175,7 @@ static const struct renesas_sdhi_of_data of_data_rzg3l = {
>  			  TMIO_MMC_HAVE_CBSY | TMIO_MMC_MIN_RCAR2 |
>  			  TMIO_MMC_64BIT_DATA_PORT | TMIO_MMC_TUNING_DELAY |
>  			  TMIO_MMC_INTERNAL_DIVIDER | TMIO_MMC_HWADJ |
> -			  TMIO_MMC_HS400MODE2,
> +			  TMIO_MMC_HS400MODE2 | TMIO_MMC_HS400ES,
>  	.capabilities	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
>  			  MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY,
>  	.capabilities2	= MMC_CAP2_NO_WRITE_PROTECT | MMC_CAP2_MERGE_CAPABLE,
> diff --git a/include/linux/platform_data/tmio.h b/include/linux/platform_data/tmio.h
> index 8a5dc18d43da..75d32c8ee57a 100644
> --- a/include/linux/platform_data/tmio.h
> +++ b/include/linux/platform_data/tmio.h
> @@ -62,6 +62,9 @@
>  /* Some controllers have HS400MODE2 */
>  #define TMIO_MMC_HS400MODE2		BIT(16)
> 
> +/* Some controllers have HS400ES */
> +#define TMIO_MMC_HS400ES		BIT(17)
> +
>  struct tmio_mmc_data {
>  	void				*chan_priv_tx;
>  	void				*chan_priv_rx;
> --
> 2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.