[PATCH] mmc: hisilicon: mv200: stop treating the CIU clock as the card clock
From: David Yang
Date: Wed Nov 04 2026 - 09:37:05 EST
The card clock comes from the controller's own divider; the CIU only
runs at the rates its mux offers, 25/50/100/150/200 MHz. The driver
nevertheless asked the framework for the card clock on every
set_ios() and warned on every refusal. The refusals are the framework
working as designed: the 400 kHz identification clock is below the
lowest mux rate, and clock == 0 is a clock-stop, not a rate. On an
Hi3798MV200H board that warning accounts for 18 of the 24 error
lines of one boot.
Ask for the rate only when there is one, ignore refusals, and read
the settled rate back, so the divider always starts from the rate the
framework actually provides.
Signed-off-by: David Yang <mmyangfl@xxxxxxxxx>
---
drivers/mmc/host/dw_mmc-hi3798mv200.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc-hi3798mv200.c b/drivers/mmc/host/dw_mmc-hi3798mv200.c
index fda417888be9..e64d5bdc068e 100644
--- a/drivers/mmc/host/dw_mmc-hi3798mv200.c
+++ b/drivers/mmc/host/dw_mmc-hi3798mv200.c
@@ -53,15 +53,19 @@ static void dw_mci_hi3798mv200_set_ios(struct dw_mci *host, struct mmc_ios *ios)
val &= ~SDMMC_DDR_HS400;
mci_writel(host, DDR_REG, val);
- if (clk_set_rate(host->ciu_clk, ios->clock))
- dev_warn(host->dev, "Failed to set rate to %u\n", ios->clock);
- else
+ if (ios->clock) {
/*
- * CLK_MUX_ROUND_NEAREST is enabled for this clock
- * The actual clock rate is not what we set, but a rounded value
- * so we should get the rate once again
+ * The card clock comes from the controller's divider, which
+ * only divides down, so a fast mode needs the CIU lifted
+ * first. Ask for the card clock and ignore the outcome: the
+ * mux has nothing below 25 MHz, so the 400 kHz identification
+ * clock is refused and just leaves the CIU where it was.
+ * Whatever the framework settles on is the divider input, so
+ * read it back; clock == 0 is a stop request, not a rate.
*/
+ clk_set_rate(host->ciu_clk, ios->clock);
host->bus_hz = clk_get_rate(host->ciu_clk);
+ }
if (phase.valid) {
clk_set_phase(priv->drive_clk, phase.out_deg);
--
2.53.0