[PATCH v21 11/12] mmc: renesas_sdhi: Make HS400 OSEL bit configurable per SoC

From: Biju

Date: Sat Jul 18 2026 - 09:40:07 EST


From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>

RZ/G3L and R-Car both use SH_MOBILE_SDHI_SCC_TMPPORT2 but interpret
its bitfields differently. R-Car uses BIT(4) (HS400OSEL) to control
HS400 data output timing, while RZ/G3L uses the lower 16 bits for tuning
delay and does not require the OSEL bit.

Remove the hardcoded SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL constant
and replace it with a per-platform osel_tmpout field in both
renesas_sdhi_of_data and tmio_mmc_data. The field is propagated
during probe and consumed in renesas_sdhi_hs400_complete() and
renesas_sdhi_reset_hs400_mode() when setting or clearing the HS400EN
bit in TMPPORT2.

Set osel_tmpout = BIT(4) explicitly on of_data_rcar_gen3 and
of_data_rcar_gen3_no_sdh_fallback; platforms that omit it (such as
RZ/G2L and RZ/G3L) default to zero, leaving the OSEL bit untouched
during HS400 mode transitions.

Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
v20->v21:
* No change.
v19->v20:
* No change.
v18->v19:
* No change.
v18:
* New patch.
---
drivers/mmc/host/renesas_sdhi.h | 1 +
drivers/mmc/host/renesas_sdhi_core.c | 6 +++---
drivers/mmc/host/renesas_sdhi_internal_dmac.c | 2 ++
include/linux/platform_data/tmio.h | 1 +
4 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index e2c26917b884..7ed92229e937 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -41,6 +41,7 @@ struct renesas_sdhi_of_data {
unsigned long sdhi_flags;
u64 clk_mask;
unsigned int max_divider;
+ u32 osel_tmpout;
u16 clk_div_mask;
};

diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index d5d8afde9bfc..e44751647982 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -310,7 +310,6 @@ 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_HS400OSEL BIT(4)
#define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN BIT(31)

/* Definitions for values the SH_MOBILE_SDHI_SCC_TMPPORT4 register */
@@ -457,7 +456,7 @@ static void renesas_sdhi_hs400_complete(struct mmc_host *mmc)

sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2,
(SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
- SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) |
+ host->pdata->osel_tmpout) |
sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));

sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL,
@@ -598,7 +597,7 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,

sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2,
~(SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
- SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) &
+ host->pdata->osel_tmpout) &
sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2));

if (sdhi_has_quirk(priv, hs400_calib_table) || sdhi_has_quirk(priv, hs400_bad_taps))
@@ -1198,6 +1197,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
mmc_data->max_segs = of_data->max_segs;
mmc_data->clk_mask = of_data->clk_mask;
mmc_data->max_divider = of_data->max_divider;
+ mmc_data->osel_tmpout = of_data->osel_tmpout;
dma_priv->dma_buswidth = of_data->dma_buswidth;
host->bus_shift = of_data->bus_shift;
/* Fallback for old DTs */
diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
index 893d9395e9d6..b1146dca94ca 100644
--- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
+++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
@@ -130,6 +130,7 @@ static const struct renesas_sdhi_of_data of_data_rcar_gen3 = {
.sdhi_flags = SDHI_FLAG_NEED_CLKH_FALLBACK,
.clk_mask = SDHI_CLK_MASK_DEFAULT,
.max_divider = SDHI_MAX_DIVIDER_DEFAULT,
+ .osel_tmpout = BIT(4),
.clk_div_mask = GENMASK(7, 0),
};

@@ -149,6 +150,7 @@ static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_sdh_fallback = {
.max_segs = 1,
.clk_mask = SDHI_CLK_MASK_DEFAULT,
.max_divider = SDHI_MAX_DIVIDER_DEFAULT,
+ .osel_tmpout = BIT(4),
.clk_div_mask = GENMASK(7, 0),
};

diff --git a/include/linux/platform_data/tmio.h b/include/linux/platform_data/tmio.h
index 99b05c8c840a..501ca4355c34 100644
--- a/include/linux/platform_data/tmio.h
+++ b/include/linux/platform_data/tmio.h
@@ -72,6 +72,7 @@ struct tmio_mmc_data {
unsigned short max_segs;
u64 clk_mask;
unsigned int max_divider;
+ u32 osel_tmpout;
u16 clk_div_mask;
};
#endif
--
2.43.0