[PATCH v23 07/14] mmc: renesas_sdhi: Add TMIO_MMC_INTERNAL_DIVIDER flag
Biju <[email protected]> Thu, 30 Jul 2026 12:31:45 +0100
| Newsgroups | org.kernel.vger.linux-mmc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-renesas-soc |
|---|---|
| Message-ID | <[email protected]> |
From: Biju Das <[email protected]> RZ/G3L has a fixed internal /2 clock divider active in all bus timing modes except HS400, where the divider is bypassed. Add a TMIO_MMC_INTERNAL_DIVIDER flag to mark controllers with this divider. Add renesas_sdhi_clk_get_rate() to fold the /2 division into the reported clock rate when the flag is set, and use it in renesas_sdhi_clk_update() in place of clk_get_rate(). HS400 is not yet supported in software for this SoC. Adjust clkh_shift for the internal divider case. No existing platform sets this flag, so this is infrastructure only, with no functional change for current SoCs. Signed-off-by: Biju Das <[email protected]> --- v22->v23: * Updated commit description. v21->v22: * Updated commit description. * Added renesas_sdhi_is_internal_divider_enabled() and renesas_sdhi_clk_get_rate() to simplify the clock rate logic. v20->v21: * No change. v19->v20: * No change. v18->v19: * Updated commit description. * Dropped divider variable from struct renesas_sdhi. * Updated renesas_sdhi_clk_update() to return rate for HS400mode and nonHS400mode(uses 1/2 internal divider). v18: * New patch using flag. --- drivers/mmc/host/renesas_sdhi_core.c | 31 +++++++++++++++++++++++++--- include/linux/platform_data/tmio.h | 3 +++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index a0922bc9d4a5..655f0920c015 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -125,6 +125,27 @@ static int renesas_sdhi_clk_enable(struct tmio_mmc_host *host) return 0; } +static bool renesas_sdhi_is_internal_divider_enabled(struct tmio_mmc_host *host) +{ + bool enable = false; + + if (host->pdata->flags & TMIO_MMC_INTERNAL_DIVIDER) + enable = true; + + return enable; +} + +static unsigned int renesas_sdhi_clk_get_rate(struct tmio_mmc_host *host, + struct clk *clk) +{ + unsigned int freq = clk_get_rate(clk); + + if (renesas_sdhi_is_internal_divider_enabled(host)) + freq /= 2; + + return freq; +} + static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host, unsigned int wanted_clock) { @@ -141,7 +162,7 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host, * clock during tuning, so we don't change the external clock setup. */ if (!(host->pdata->flags & TMIO_MMC_MIN_RCAR2) || mmc_doing_tune(host->mmc)) - return clk_get_rate(priv->clk); + return renesas_sdhi_clk_get_rate(host, priv->clk); if (priv->clkh) { /* HS400 with 4TAP needs different clock settings */ @@ -184,10 +205,14 @@ static unsigned int renesas_sdhi_clk_update(struct tmio_mmc_host *host, clk_set_rate(ref_clk, best_freq); - if (priv->clkh) + if (priv->clkh) { + if (host->pdata->flags & TMIO_MMC_INTERNAL_DIVIDER) + clkh_shift = 1; + clk_set_rate(priv->clk, best_freq >> clkh_shift); + } - return clk_get_rate(priv->clk); + return renesas_sdhi_clk_get_rate(host, priv->clk); } static void renesas_sdhi_set_clock(struct tmio_mmc_host *host, diff --git a/include/linux/platform_data/tmio.h b/include/linux/platform_data/tmio.h index abf4134a8bd8..8d435f7690a5 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