[PATCH v18 10/12] mmc: renesas_sdhi: Make HS400 OSEL bit configurable per SoC
From: Biju
Date: Mon Jun 22 2026 - 12:00:36 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>
---
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 9d5e591ef2f5..3099330c7304 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;
};
#define SDHI_CALIB_TABLE_MAX 32
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index f77985d305c0..42645480b62f 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -292,7 +292,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 */
@@ -439,7 +438,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,
@@ -580,7 +579,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))
@@ -1180,6 +1179,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 9cb69003ac96..709351693efa 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),
};
static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_sdh_fallback = {
@@ -148,6 +149,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),
};
static const struct renesas_sdhi_of_data of_data_rz_g2l = {
diff --git a/include/linux/platform_data/tmio.h b/include/linux/platform_data/tmio.h
index 96eff17179cc..8b4032b24d36 100644
--- a/include/linux/platform_data/tmio.h
+++ b/include/linux/platform_data/tmio.h
@@ -72,5 +72,6 @@ struct tmio_mmc_data {
unsigned short max_segs;
u64 clk_mask;
unsigned int max_divider;
+ u32 osel_tmpout;
};
#endif
--
2.43.0