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

Biju Das <[email protected]>
Newsgroups org.kernel.vger.linux-renesas-soc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-mmc
Message-ID <TY3PR01MB11346CFB7B99FB22483112D7786F02@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi Wolfram,

> -----Original Message-----
> From: Biju <[email protected]>
> 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 <[email protected]>
> 
> 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 <[email protected]>
> ---
> 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.