Improve error reporting when setting or enabling the VQMMC regulator fails.
Refactor voltage handling to determine the target signal voltage before updating the regulator, and report failures when the SDHCI voltage-switch bit does not reflect the requested state. Keep the SDHCI host-control voltage-bit handling specific to SD devices, while allowing the VQMMC regulator to be configured for other MMC device types. Cc: Dave Klotz <[email protected]> Cc: Eric Chung <[email protected]> Cc: Hung-Chun Tseng <[email protected]> Cc: E Shattow <[email protected]> Cc: Yixun Lan <[email protected]> Signed-off-by: Anand Moon <[email protected]> --- drivers/mmc/spacemit_sdhci.c | 85 ++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/drivers/mmc/spacemit_sdhci.c b/drivers/mmc/spacemit_sdhci.c index f5578f38bdd..836201ce83c 100644 --- a/drivers/mmc/spacemit_sdhci.c +++ b/drivers/mmc/spacemit_sdhci.c @@ -222,15 +222,26 @@ static int spacemit_sdhci_set_vqmmc_voltage(struct mmc *mmc, int voltage) #if CONFIG_IS_ENABLED(DM_REGULATOR) int ret; - if (!mmc->vqmmc_supply) + /* + * eMMC VCCQ is fixed at 1.8V on the BPI-F3. + * Do not attempt to switch its VQMMC regulator. + */ + if (!IS_SD(mmc) || !mmc->vqmmc_supply) return 0; ret = regulator_set_value(mmc->vqmmc_supply, voltage); - if (ret) + if (ret) { + log_err("%s: failed to set VQMMC to %d uV: %d\n", + mmc->dev->name, voltage, ret); return ret; + } + ret = regulator_set_enable_if_allowed(mmc->vqmmc_supply, true); - if (ret) + if (ret) { + log_err("%s: failed to enable VQMMC: %d\n", + mmc->dev->name, ret); return ret; + } #endif return 0; } @@ -239,44 +250,54 @@ static void spacemit_sdhci_set_voltage(struct sdhci_host *host) { if (IS_ENABLED(CONFIG_MMC_IO_VOLTAGE)) { struct mmc *mmc = host->mmc; + bool to_180, ok; + int voltage_uv, ret; u32 ctrl; - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); - switch (mmc->signal_voltage) { case MMC_SIGNAL_VOLTAGE_330: - case MMC_SIGNAL_VOLTAGE_180: { - bool to_180 = mmc->signal_voltage == - MMC_SIGNAL_VOLTAGE_180; - bool ok; - int voltage_mv = to_180 ? 1800000 : 3300000; - - if (spacemit_sdhci_set_vqmmc_voltage(mmc, voltage_mv)) - return; - if (!IS_SD(mmc)) - return; - if (to_180) - ctrl |= SDHCI_CTRL_VDD_180; - else - ctrl &= ~SDHCI_CTRL_VDD_180; - sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); - - mdelay(5); - - ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); - ok = !!(ctrl & SDHCI_CTRL_VDD_180) == to_180; - if (ok) - return; - - log_err("%d.%dV regulator output not stable\n", - voltage_mv / 1000000, - (voltage_mv / 100000) % 10); + to_180 = false; + voltage_uv = 3300000; + break; + case MMC_SIGNAL_VOLTAGE_180: + to_180 = true; + voltage_uv = 1800000; break; - } default: /* No signal voltage switch required */ return; } + + ret = spacemit_sdhci_set_vqmmc_voltage(mmc, voltage_uv); + if (ret) { + log_err("%s: VQMMC switch to %d uV failed: %d\n", + mmc->dev->name, voltage_uv, ret); + return; + } + + /* + * Non-SD devices may not use the SD Host Control 2 + * voltage-switch bit. Keep their handling separate. + */ + if (!IS_SD(mmc)) + return; + + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + + if (to_180) + ctrl |= SDHCI_CTRL_VDD_180; + else + ctrl &= ~SDHCI_CTRL_VDD_180; + + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); + mdelay(5); + + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); + ok = !!(ctrl & SDHCI_CTRL_VDD_180) == to_180; + if (!ok) { + log_err("%s: SDHCI voltage bit did not switch to %d uV\n", + mmc->dev->name, voltage_uv); + } } } -- 2.56.0
