diff --git a/sys/dev/sdhci/sdhci_fsl_fdt.c b/sys/dev/sdhci/sdhci_fsl_fdt.c --- a/sys/dev/sdhci/sdhci_fsl_fdt.c +++ b/sys/dev/sdhci/sdhci_fsl_fdt.c @@ -1284,6 +1284,42 @@ return (0); } +static void +sdhci_fsl_fdt_retune_req(void *arg) +{ + struct sdhci_slot *slot; + + slot = arg; + slot->retune_req |= SDHCI_RETUNE_REQ_NEEDED; +} + +static int +sdhci_fsl_fdt_retune(device_t dev, device_t child, bool hs400) +{ + struct sdhci_slot *slot; + uint32_t retune_ticks; + int err; + + slot = device_get_ivars(child); + + if (!(slot->opt & SDHCI_TUNING_ENABLED)) + return (0); + + if (slot->host.ios.timing == bus_timing_mmc_hs400) + return (EINVAL); + + retune_ticks = slot->retune_ticks; + + err = sdhci_fsl_fdt_tune(dev, child, hs400); + if (err && retune_ticks) { + slot->retune_ticks = retune_ticks; + callout_reset(&slot->retune_callout, slot->retune_ticks, + sdhci_fsl_fdt_retune_req, slot); + } + + return (err); +} + static void sdhci_fsl_disable_hs400_mode(device_t dev, struct sdhci_fsl_fdt_softc *sc) { @@ -1452,7 +1488,7 @@ DEVMETHOD(mmcbr_switch_vccq, sdhci_fsl_fdt_switch_vccq), DEVMETHOD(mmcbr_update_ios, sdhci_fsl_fdt_update_ios), DEVMETHOD(mmcbr_tune, sdhci_fsl_fdt_tune), - DEVMETHOD(mmcbr_retune, sdhci_generic_retune), + DEVMETHOD(mmcbr_retune, sdhci_fsl_fdt_retune), /* SDHCI accessors. */ DEVMETHOD(sdhci_read_1, sdhci_fsl_fdt_read_1),