RE: [PATCH v18 04/12] mmc: renesas_sdhi: Add max_divider field to support SoC-specific clock divider ranges

From: Biju Das

Date: Tue Jul 07 2026 - 06:54:11 EST


Hi Wolfram,

> -----Original Message-----
> From: Biju <biju.das.au@xxxxxxxxx>
> Sent: 22 June 2026 16:56
> Subject: [PATCH v18 04/12] mmc: renesas_sdhi: Add max_divider field to support SoC-specific clock divider
> ranges
>
> From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
>
> The RZ/G3L SoC supports a maximum clock divider beyond the existing hardcoded value of 512, requiring a
> configurable max_divider field.
> Introduce max_divider in both renesas_sdhi_of_data and tmio_mmc_data.
>
> Replace the two hardcoded 512 constants in renesas_sdhi_clk_enable() and renesas_sdhi_set_clock() with
> host->pdata->max_divider. A fallback of 512 is applied at probe time when no value is provided,
> preserving behaviour for existing platforms.
>
> All existing of_data entries across both the internal and system DMAC drivers are updated to explicitly
> set max_divider = 512, consistent with the approach taken for clk_mask in the previous patch.
>
> Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
> ---
> v18:
> * New patch.
> ---
> drivers/mmc/host/renesas_sdhi.h | 2 ++
> drivers/mmc/host/renesas_sdhi_core.c | 8 ++++++--
> drivers/mmc/host/renesas_sdhi_internal_dmac.c | 3 +++
> drivers/mmc/host/renesas_sdhi_sys_dmac.c | 4 ++++
> include/linux/platform_data/tmio.h | 1 +
> 5 files changed, 16 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h index
> f926a36f213c..438b2a7afe76 100644
> --- a/drivers/mmc/host/renesas_sdhi.h
> +++ b/drivers/mmc/host/renesas_sdhi.h
> @@ -23,6 +23,7 @@ struct renesas_sdhi_scc {
>
> #define SDHI_FLAG_NEED_CLKH_FALLBACK BIT(0)
> #define SDHI_CLK_MASK_DEFAULT 0x80000080
> +#define SDHI_MAX_DIVIDER_DEFAULT 512
>
> struct renesas_sdhi_of_data {
> unsigned long tmio_flags;
> @@ -39,6 +40,7 @@ struct renesas_sdhi_of_data {
> unsigned short max_segs;
> unsigned long sdhi_flags;
> u64 clk_mask;
> + unsigned int max_divider;
> };
>
> #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 cccc8fc235d2..7e48e78cbfab 100644
> --- a/drivers/mmc/host/renesas_sdhi_core.c
> +++ b/drivers/mmc/host/renesas_sdhi_core.c
> @@ -117,7 +117,7 @@ static int renesas_sdhi_clk_enable(struct tmio_mmc_host *host)
> * Minimum frequency is the minimum input clock frequency
> * divided by our maximum divider.
> */
> - mmc->f_min = max(clk_round_rate(priv->clk, 1) / 512, 1L);
> + mmc->f_min = max(clk_round_rate(priv->clk, 1) /
> +host->pdata->max_divider, 1L);
>
> /* enable 16bit data access on SDBUF as default */
> renesas_sdhi_sdbuf_width(host, 16);
> @@ -205,7 +205,7 @@ static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
> }
>
> host->mmc->actual_clock = renesas_sdhi_clk_update(host, new_clock);
> - clock = host->mmc->actual_clock / 512;
> + clock = host->mmc->actual_clock / host->pdata->max_divider;
>
> /*
> * Add a margin of 1/1024 rate higher to the clock rate in order @@ -1137,6 +1137,7 @@ int
> renesas_sdhi_probe(struct platform_device *pdev,
> mmc_data->max_blk_count = of_data->max_blk_count;
> mmc_data->max_segs = of_data->max_segs;
> mmc_data->clk_mask = of_data->clk_mask;
> + mmc_data->max_divider = of_data->max_divider;
> dma_priv->dma_buswidth = of_data->dma_buswidth;
> host->bus_shift = of_data->bus_shift;
> /* Fallback for old DTs */
> @@ -1148,6 +1149,9 @@ int renesas_sdhi_probe(struct platform_device *pdev,
> if (!mmc_data->clk_mask)
> mmc_data->clk_mask = SDHI_CLK_MASK_DEFAULT;
>
> + if (!mmc_data->max_divider)
> + mmc_data->max_divider = SDHI_MAX_DIVIDER_DEFAULT;
> +

As shaskiko [1] pointed out, for non-DT platforms

+ if (mmd && !mmd->max_divider)
+ mmd->max_divider = SDHI_MAX_DIVIDER_DEFAULT;
+

Also replaced the hardcoded value 9 with a variable as ilog2(512)=9

- for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
+ for (i = min(ilog2(host->pdata->max_divider), ilog2(UINT_MAX / new_clock)); i >= 0; i--) {

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

Cheers,
Biju


> host->write16_hook = renesas_sdhi_write16_hook;
> host->clk_enable = renesas_sdhi_clk_enable;
> host->clk_disable = renesas_sdhi_clk_disable; diff --git
> a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> index 2865ec30be66..c91b910488da 100644
> --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> @@ -103,6 +103,7 @@ static const struct renesas_sdhi_of_data of_data_rza2 = {
> .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE,
> .max_segs = 1,
> .clk_mask = SDHI_CLK_MASK_DEFAULT,
> + .max_divider = SDHI_MAX_DIVIDER_DEFAULT,
> };
>
> static const struct renesas_sdhi_of_data of_data_rcar_gen3 = { @@ -121,6 +122,7 @@ static const struct
> renesas_sdhi_of_data of_data_rcar_gen3 = {
> .max_segs = 1,
> .sdhi_flags = SDHI_FLAG_NEED_CLKH_FALLBACK,
> .clk_mask = SDHI_CLK_MASK_DEFAULT,
> + .max_divider = SDHI_MAX_DIVIDER_DEFAULT,
> };
>
> static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_sdh_fallback = { @@ -138,6 +140,7 @@
> static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_sdh_fallback = {
> .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE,
> .max_segs = 1,
> .clk_mask = SDHI_CLK_MASK_DEFAULT,
> + .max_divider = SDHI_MAX_DIVIDER_DEFAULT,
> };
>
> static const u8 r8a7796_es13_calib_table[2][SDHI_CALIB_TABLE_MAX] = { diff --git
> a/drivers/mmc/host/renesas_sdhi_sys_dmac.c b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> index d1a4f65ddd91..d91b48dce8c9 100644
> --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> @@ -30,6 +30,7 @@
> static const struct renesas_sdhi_of_data of_default_cfg = {
> .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
> .clk_mask = SDHI_CLK_MASK_DEFAULT,
> + .max_divider = SDHI_MAX_DIVIDER_DEFAULT,
> };
>
> static const struct renesas_sdhi_of_data of_rz_compatible = { @@ -39,6 +40,7 @@ static const struct
> renesas_sdhi_of_data of_rz_compatible = {
> .capabilities = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
> MMC_CAP_WAIT_WHILE_BUSY,
> .clk_mask = SDHI_CLK_MASK_DEFAULT,
> + .max_divider = SDHI_MAX_DIVIDER_DEFAULT,
> };
>
> static const struct renesas_sdhi_of_data of_rcar_gen1_compatible = { @@ -47,6 +49,7 @@ static const
> struct renesas_sdhi_of_data of_rcar_gen1_compatible = {
> MMC_CAP_WAIT_WHILE_BUSY,
> .capabilities2 = MMC_CAP2_NO_WRITE_PROTECT,
> .clk_mask = SDHI_CLK_MASK_DEFAULT,
> + .max_divider = SDHI_MAX_DIVIDER_DEFAULT,
> };
>
> /* Definitions for sampling clocks */
> @@ -75,6 +78,7 @@ static const struct renesas_sdhi_of_data of_rcar_gen2_compatible = {
> .taps_num = ARRAY_SIZE(rcar_gen2_scc_taps),
> .max_blk_count = UINT_MAX / TMIO_MAX_BLK_SIZE,
> .clk_mask = SDHI_CLK_MASK_DEFAULT,
> + .max_divider = SDHI_MAX_DIVIDER_DEFAULT,
> };
>
> static const struct of_device_id renesas_sdhi_sys_dmac_of_match[] = { diff --git
> a/include/linux/platform_data/tmio.h b/include/linux/platform_data/tmio.h
> index 76056d49f5e0..27ea21c00419 100644
> --- a/include/linux/platform_data/tmio.h
> +++ b/include/linux/platform_data/tmio.h
> @@ -62,5 +62,6 @@ struct tmio_mmc_data {
> unsigned int max_blk_count;
> unsigned short max_segs;
> u64 clk_mask;
> + unsigned int max_divider;
> };
> #endif
> --
> 2.43.0