RE: [PATCH v18 03/12] mmc: renesas_sdhi: Add clk_mask field to support SoC-specific clock divider widths

Biju Das <[email protected]> Tue, 7 Jul 2026 10:49:59 +0000
Newsgroups org.kernel.vger.linux-mmc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-renesas-soc
Message-ID <TY3PR01MB113466B8CC9D1658C61DA5C7086F02@TY3PR01MB11346.jpnprd01.prod.outlook.com>
Hi Wolfram,

> -----Original Message-----
> From: Biju <[email protected]>
> Sent: 22 June 2026 16:56
> Subject: [PATCH v18 03/12] mmc: renesas_sdhi: Add clk_mask field to support SoC-specific clock divider
> widths
> 
> From: Biju Das <[email protected]>
> 
> The RZ/G3L SoC uses an 11-bit clock divider, which requires a wider clock mask of 0x200000200 in
> renesas_sdhi_set_clock() compared to the existing hardcoded 0x80000080. This exceeds 32 bits, so clk_mask
> and the related clk/clock locals are widened to u64.
> 
> Add a clk_mask field to renesas_sdhi_of_data and tmio_mmc_data so each SoC can supply its own clock mask.
> renesas_sdhi_set_clock() now reads
> host->pdata->clk_mask instead of using a hardcoded constant, and
> renesas_sdhi_probe() falls back to SDHI_CLK_MASK_DEFAULT (0x80000080) when no mask is provided,
> preserving existing behaviour.
> 
> All current of_data entries in both the internal and system DMAC drivers are updated to set clk_mask =
> SDHI_CLK_MASK_DEFAULT explicitly, in preparation for RZ/G3L support supplying its own clk_mask value in a
> later patch.
> 
> Signed-off-by: Biju Das <[email protected]>
> ---
> v18:
>  * New patch dropping struct renesas_sdhi_hw_info instead using
>    renesas_sdhi_of_data and tmio_mmc_data.
> ---
>  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
> 09bf9b24a8c3..f926a36f213c 100644
> --- a/drivers/mmc/host/renesas_sdhi.h
> +++ b/drivers/mmc/host/renesas_sdhi.h
> @@ -22,6 +22,7 @@ struct renesas_sdhi_scc {  };
> 
>  #define SDHI_FLAG_NEED_CLKH_FALLBACK	BIT(0)
> +#define SDHI_CLK_MASK_DEFAULT		0x80000080
> 
>  struct renesas_sdhi_of_data {
>  	unsigned long tmio_flags;
> @@ -37,6 +38,7 @@ struct renesas_sdhi_of_data {
>  	unsigned int max_blk_count;
>  	unsigned short max_segs;
>  	unsigned long sdhi_flags;
> +	u64 clk_mask;
>  };
> 
>  #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 f9ec78d699f4..cccc8fc235d2 100644
> --- a/drivers/mmc/host/renesas_sdhi_core.c
> +++ b/drivers/mmc/host/renesas_sdhi_core.c
> @@ -194,7 +194,7 @@ static void renesas_sdhi_set_clock(struct tmio_mmc_host *host,
>  				   unsigned int new_clock)
>  {
>  	unsigned int clk_margin;
> -	u32 clk = 0, clock;
> +	u64 clk = 0, clock;
> 
>  	sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
>  		sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); @@ -213,7 +213,7 @@ static void
> renesas_sdhi_set_clock(struct tmio_mmc_host *host,
>  	 * provided for actual_clock in renesas_sdhi_clk_update().
>  	 */
>  	clk_margin = new_clock >> 10;
> -	for (clk = 0x80000080; new_clock + clk_margin >= (clock << 1); clk >>= 1)
> +	for (clk = host->pdata->clk_mask; new_clock + clk_margin >= (clock <<
> +1); clk >>= 1)
>  		clock <<= 1;
> 
>  	/* 1/1 clock is option */
> @@ -1136,6 +1136,7 @@ int renesas_sdhi_probe(struct platform_device *pdev,
>  		mmc_data->dma_rx_offset = of_data->dma_rx_offset;
>  		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;
>  		dma_priv->dma_buswidth = of_data->dma_buswidth;
>  		host->bus_shift = of_data->bus_shift;
>  		/* Fallback for old DTs */
> @@ -1144,6 +1145,9 @@ int renesas_sdhi_probe(struct platform_device *pdev,
> 
>  	}
> 
> +	if (!mmc_data->clk_mask)
> +		mmc_data->clk_mask = SDHI_CLK_MASK_DEFAULT;


As shashiko pointed out [1], for non-DT platforms this should be

[1] +	if (mmd && !mmd->clk_mask)
+		mmd->clk_mask = SDHI_CLK_MASK_DEFAULT;


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 990e3d18d560..2865ec30be66 100644
> --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> @@ -102,6 +102,7 @@ static const struct renesas_sdhi_of_data of_data_rza2 = {
>  	/* DMAC can handle 32bit blk count but only 1 segment */
>  	.max_blk_count	= UINT_MAX / TMIO_MAX_BLK_SIZE,
>  	.max_segs	= 1,
> +	.clk_mask	= SDHI_CLK_MASK_DEFAULT,
>  };
> 
>  static const struct renesas_sdhi_of_data of_data_rcar_gen3 = { @@ -119,6 +120,7 @@ static const struct
> renesas_sdhi_of_data of_data_rcar_gen3 = {
>  	.max_blk_count	= UINT_MAX / TMIO_MAX_BLK_SIZE,
>  	.max_segs	= 1,
>  	.sdhi_flags	= SDHI_FLAG_NEED_CLKH_FALLBACK,
> +	.clk_mask	= SDHI_CLK_MASK_DEFAULT,
>  };
> 
>  static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_sdh_fallback = { @@ -135,6 +137,7 @@
> static const struct renesas_sdhi_of_data of_data_rcar_gen3_no_sdh_fallback = {
>  	/* DMAC can handle 32bit blk count but only 1 segment */
>  	.max_blk_count	= UINT_MAX / TMIO_MAX_BLK_SIZE,
>  	.max_segs	= 1,
> +	.clk_mask	= SDHI_CLK_MASK_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 13f9a25f4722..d1a4f65ddd91 100644
> --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> @@ -29,6 +29,7 @@
> 
>  static const struct renesas_sdhi_of_data of_default_cfg = {
>  	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT,
> +	.clk_mask	= SDHI_CLK_MASK_DEFAULT,
>  };
> 
>  static const struct renesas_sdhi_of_data of_rz_compatible = { @@ -37,6 +38,7 @@ static const struct
> renesas_sdhi_of_data of_rz_compatible = {
>  	.tmio_ocr_mask	= MMC_VDD_32_33,
>  	.capabilities	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
>  			  MMC_CAP_WAIT_WHILE_BUSY,
> +	.clk_mask	= SDHI_CLK_MASK_DEFAULT,
>  };
> 
>  static const struct renesas_sdhi_of_data of_rcar_gen1_compatible = { @@ -44,6 +46,7 @@ static const
> struct renesas_sdhi_of_data of_rcar_gen1_compatible = {
>  	.capabilities	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
>  			  MMC_CAP_WAIT_WHILE_BUSY,
>  	.capabilities2	= MMC_CAP2_NO_WRITE_PROTECT,
> +	.clk_mask	= SDHI_CLK_MASK_DEFAULT,
>  };
> 
>  /* Definitions for sampling clocks */
> @@ -71,6 +74,7 @@ static const struct renesas_sdhi_of_data of_rcar_gen2_compatible = {
>  	.taps		= rcar_gen2_scc_taps,
>  	.taps_num	= ARRAY_SIZE(rcar_gen2_scc_taps),
>  	.max_blk_count	= UINT_MAX / TMIO_MAX_BLK_SIZE,
> +	.clk_mask	= SDHI_CLK_MASK_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 426291713b83..76056d49f5e0 100644
> --- a/include/linux/platform_data/tmio.h
> +++ b/include/linux/platform_data/tmio.h
> @@ -61,5 +61,6 @@ struct tmio_mmc_data {
>  	dma_addr_t			dma_rx_offset;
>  	unsigned int			max_blk_count;
>  	unsigned short			max_segs;
> +	u64				clk_mask;
>  };
>  #endif
> --
> 2.43.0