RE: [PATCH v19 03/12] mmc: renesas_sdhi: Add clk_mask field to support flexible clock divider widths

From: Biju Das

Date: Fri Jul 10 2026 - 04:38:49 EST



Hi All,

> -----Original Message-----
> From: Biju <biju.das.au@xxxxxxxxx>
> Sent: 09 July 2026 20:29
> Subject: [PATCH v19 03/12] mmc: renesas_sdhi: Add clk_mask field to support flexible clock divider widths
>
> From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
>
> The clock divider on the RZ/G3L SoC features an 11-bit width, requiring a wider clock mask (0x200000200)
> in renesas_sdhi_set_clock() than the historically hardcoded 32-bit value (0x80000080).
>
> To accommodate SoC variants with wider clock divider masks, expand the internal clock control variables
> (clk and clock) from u32 to u64. Introduce a clk_mask field to both struct renesas_sdhi_of_data and
> struct tmio_mmc_data to allow platform configuration data to supply SoC-specific mask properties.
>
> Update renesas_sdhi_set_clock() to read the dynamic mask from platform data. During the probe phase,
> assign a default mask fallback of SDHI_CLK_MASK_DEFAULT (0x80000080) if no specific mask is specified,
> ensuring backward compatibility with existing hardware variants.
>
> Finally, explicitly populate clk_mask with the default value across all current internal and system DMAC
> configuration profiles, in preparation for the upcoming RZ/G3L clock customization.
>
> Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
> ---
> v18->v19:
> * Fixed the clk_mask for non-DT platforms.
> 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..1787f91d1ff2 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 (mmd && !mmd->clk_mask)
> + mmd->clk_mask = SDHI_CLK_MASK_DEFAULT;


As shashiko pointed out [1]], renesas,sdhi-shmobile does not have of_data

The below changes will take care both cases OF with no device data
and non-DT in the next version

if (mmd)
*mmc_data = *mmd;

if (!mmc_data->clk_mask)
mmc_data->clk_mask = SDHI_CLK_MASK_DEFAULT;

[1]
https://sashiko.dev/#/patchset/20260709192916.630794-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 b3f4a5f8dec0..c6db0418de15 100644
> --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c
> @@ -101,6 +101,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 = { @@ -118,6 +119,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 = { @@ -134,6 +136,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 7ae488e5c1e0..fcd2edfa69db 100644
> --- a/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> +++ b/drivers/mmc/host/renesas_sdhi_sys_dmac.c
> @@ -28,6 +28,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 = { @@ -36,6 +37,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 = { @@ -43,6 +45,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 */
> @@ -70,6 +73,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