From bd15d31cef50060d90356384ba7b878d398fc9f3 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Wed, 12 Apr 2023 23:46:02 +0200 Subject: [PATCH] mmc(4): Don't call bridge driver for timings not requiring tuning The original idea behind calling into the bridge driver was to have the logic deciding whether tuning is actually required for a particular bus timing in a given slot as well as doing the sanity checking only on the controller layer which also generally is better suited for these due to say SDHCI_SDR50_NEEDS_TUNING. On another thought, not every such driver should need to check whether tuning is required at all, though, and not everything is SDHCI in the first place. Adjust sdhci{,_fsl_fdt}(4) accordingly, but keep sdhci_generic_tune() a bit cautious still. --- sys/dev/mmc/mmc.c | 9 +++++++++ sys/dev/sdhci/sdhci.c | 6 ++++-- sys/dev/sdhci/sdhci_fsl_fdt.c | 17 +++-------------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c index 5fce6cbf47a..54caadb2b3c 100644 --- a/sys/dev/mmc/mmc.c +++ b/sys/dev/mmc/mmc.c @@ -2237,6 +2237,15 @@ mmc_calculate_clock(struct mmc_softc *sc) mmcbr_set_clock(dev, max_dtr); mmcbr_update_ios(dev); + /* + * Don't call into the bridge driver for timings definitely + * not requiring tuning. Note that it's up to the upper + * layer to actually execute tuning otherwise. + */ + if (timing <= bus_timing_uhs_sdr25 || + timing == bus_timing_mmc_ddr52) + goto power_class; + if (mmcbr_tune(dev, hs400) != 0) { device_printf(dev, "Card at relative address %d " "failed to execute initial tuning\n", rca); diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index a7283e66df3..69dbd3d7ffd 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -1492,10 +1492,12 @@ sdhci_generic_tune(device_t brdev __unused, device_t reqdev, bool hs400) case bus_timing_uhs_sdr50: if (slot->opt & SDHCI_SDR50_NEEDS_TUNING) break; - /* FALLTHROUGH */ - default: SDHCI_UNLOCK(slot); return (0); + default: + slot_printf(slot, "Tuning requested but not required.\n"); + SDHCI_UNLOCK(slot); + return (EINVAL); } tune_cmd = slot->tune_cmd; diff --git a/sys/dev/sdhci/sdhci_fsl_fdt.c b/sys/dev/sdhci/sdhci_fsl_fdt.c index 470cbd16930..2c600e1291f 100644 --- a/sys/dev/sdhci/sdhci_fsl_fdt.c +++ b/sys/dev/sdhci/sdhci_fsl_fdt.c @@ -1199,22 +1199,10 @@ sdhci_fsl_fdt_tune(device_t bus, device_t child, bool hs400) sc = device_get_softc(bus); slot = device_get_ivars(child); - error = 0; - clk_divider = sc->baseclk_hz / slot->clock; - switch (sc->slot.host.ios.timing) { - case bus_timing_mmc_hs400: - return (EINVAL); - case bus_timing_mmc_hs200: - case bus_timing_uhs_ddr50: - case bus_timing_uhs_sdr104: - break; - case bus_timing_uhs_sdr50: - if (slot->opt & SDHCI_SDR50_NEEDS_TUNING) - break; - default: + if (sc->slot.host.ios.timing == bus_timing_uhs_sdr50 && + !(slot->opt & SDHCI_SDR50_NEEDS_TUNING)) return (0); - } /* * For tuning mode SD clock divider must be within 3 to 16. @@ -1222,6 +1210,7 @@ sdhci_fsl_fdt_tune(device_t bus, device_t child, bool hs400) * For that reason we're just bailing if the dividers don't match * that requirement. */ + clk_divider = sc->baseclk_hz / slot->clock; if (clk_divider < 3 || clk_divider > 16) return (ENXIO); -- 2.45.2