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

From: Biju

Date: Mon Jun 22 2026 - 11:57:59 EST


From: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>

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 <biju.das.jz@xxxxxxxxxxxxxx>
---
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;
+
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