On Thu, 24 Nov 2022 at 18:07, Adrian Hunter <adrian.hunter@xxxxxxxxx> wrote: > > Commit 20b92a30b561 ("mmc: sdhci: update signal voltage switch code") > removed voltage switch delays from sdhci because mmc core had been > enhanced to support them. However that assumed that sdhci_set_ios() > did a single clock change, which it did not, and so the delays in mmc > core, which should have come after the first clock change, were not > effective. > > Fix by avoiding re-configuring UHS and preset settings when the clock > is turning on and the settings have not changed. That then also avoids > the associated clock changes, so that then sdhci_set_ios() does a single > clock change when voltage switching, and the mmc core delays become > effective. > > To do that has meant keeping track of driver strength (host->drv_type), > and cases of reinitialization (host->reinit_uhs). > > Note also, the 'turning_on_clk' restriction should not be necessary > but is done to minimize the impact of the change on stable kernels. > > Fixes: 20b92a30b561 ("mmc: sdhci: update signal voltage switch code") > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx> [...] > @@ -2335,6 +2362,18 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) > > host->ops->set_bus_width(host, ios->bus_width); > > + /* > + * Special case to avoid multiple clock changes during voltage > + * switching. > + */ > + if (!reinit_uhs && > + turning_on_clk && > + host->timing == ios->timing && > + host->version >= SDHCI_SPEC_300 && > + (host->preset_enabled || host->drv_type == ios->drv_type) && > + (host->preset_enabled || !sdhci_preset_needed(host, ios->timing))) This caught my eyes, as it looks a bit messy. Not sure if it's possible to simplify, but the last two lines could be replaced with: (host->preset_enabled || (host->drv_type == ios->drv_type && !sdhci_preset_needed(host, ios->timing)))) But, I am not sure that really helps... [...] Kind regards Uffe