* [PATCH] mmc: hisilicon: mv200: stop treating the CIU clock as the card clock
@ 2026-11-04 14:22 David Yang
0 siblings, 0 replies; only message in thread
From: David Yang @ 2026-11-04 14:22 UTC (permalink / raw)
To: linux-mmc; +Cc: David Yang, Jaehoon Chung, Shawn Lin, Ulf Hansson, linux-kernel
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@gmail.com>
---
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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-11-04 14:23 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-04 14:22 [PATCH] mmc: hisilicon: mv200: stop treating the CIU clock as the card clock David Yang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®