[PATCH v18 06/12] mmc: renesas_sdhi: Add TMIO_MMC_INTERNAL_DIVIDER flag

From: Biju

Date: Mon Jun 22 2026 - 11:57:24 EST


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

The RZ/G3L SoC has an internal clock divider active for all modes
except HS400. To compensate, the rate requested from clk_set_rate()
for clk relative to clkh must be doubled in those cases so that the
SoC's internal /2 divider brings the actual card clock back to the
intended rate.

Introduce a TMIO_MMC_INTERNAL_DIVIDER flag (bit 14) in tmio.h and a
divider field in struct renesas_sdhi. During probe, when the flag is
set and the device tree does not include the mmc-hs400-1_8v property,
priv->divider is set to 2; otherwise it defaults to 1. The divider is
applied in renesas_sdhi_clk_update() when computing the rate for
priv->clk, replacing the previously implicit multiply-by-1.

No existing platform sets TMIO_MMC_INTERNAL_DIVIDER; this patch
introduces the infrastructure only, with no functional change for
current platforms.

Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
---
v18:
* New patch using flag.
---
drivers/mmc/host/renesas_sdhi.h | 2 ++
drivers/mmc/host/renesas_sdhi_core.c | 8 +++++++-
include/linux/platform_data/tmio.h | 3 +++
3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
index 438b2a7afe76..6f6b41fbe91e 100644
--- a/drivers/mmc/host/renesas_sdhi.h
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -102,6 +102,8 @@ struct renesas_sdhi {
struct reset_control *rstc;
struct tmio_mmc_host *host;
struct regulator_dev *rdev;
+
+ unsigned int divider;
};

#define host_to_priv(host) \
diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c
index e9767aa83b00..8890859d0777 100644
--- a/drivers/mmc/host/renesas_sdhi_core.c
+++ b/drivers/mmc/host/renesas_sdhi_core.c
@@ -185,7 +185,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host,
clk_set_rate(ref_clk, best_freq);

if (priv->clkh)
- clk_set_rate(priv->clk, best_freq >> clkh_shift);
+ clk_set_rate(priv->clk, (best_freq >> clkh_shift) * priv->divider);

return clk_get_rate(priv->clk);
}
@@ -1231,6 +1231,12 @@ int renesas_sdhi_probe(struct platform_device *pdev,

dev_pm_domain_start(&pdev->dev);

+ if ((host->pdata->flags & TMIO_MMC_INTERNAL_DIVIDER) &&
+ !device_property_read_bool(dev, "mmc-hs400-1_8v"))
+ priv->divider = 2;
+ else
+ priv->divider = 1;
+
ret = renesas_sdhi_clk_enable(host);
if (ret)
return ret;
diff --git a/include/linux/platform_data/tmio.h b/include/linux/platform_data/tmio.h
index 868a21842fa5..6c512e96e192 100644
--- a/include/linux/platform_data/tmio.h
+++ b/include/linux/platform_data/tmio.h
@@ -53,6 +53,9 @@
/* Some controllers have tuning delay */
#define TMIO_MMC_TUNING_DELAY BIT(13)

+/* Some controllers have internal divider */
+#define TMIO_MMC_INTERNAL_DIVIDER BIT(14)
+
struct tmio_mmc_data {
void *chan_priv_tx;
void *chan_priv_rx;
--
2.43.0