On 1/21/21 9:40 PM, Aswath Govindraju wrote: > From: Faiz Abbas <faiz_ab...@ti.com> > > Add a set_voltage() function which handles the switch from 3.3V to 1.8V > for SD card UHS modes. > > Signed-off-by: Faiz Abbas <faiz_ab...@ti.com> > Signed-off-by: Aswath Govindraju <a-govindr...@ti.com> > --- > drivers/mmc/sdhci.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ > include/sdhci.h | 1 + > 2 files changed, 81 insertions(+) > > diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c > index 06289343124e..e7e3e22d1a7e 100644 > --- a/drivers/mmc/sdhci.c > +++ b/drivers/mmc/sdhci.c > @@ -20,6 +20,7 @@ > #include <linux/delay.h> > #include <linux/dma-mapping.h> > #include <phys2bus.h> > +#include <power/regulator.h> > > static void sdhci_reset(struct sdhci_host *host, u8 mask) > { > @@ -509,6 +510,85 @@ void sdhci_set_uhs_timing(struct sdhci_host *host) > sdhci_writew(host, reg, SDHCI_HOST_CONTROL2); > } > > +#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE) > +static void sdhci_set_voltage(struct sdhci_host *host) > +{ > + struct mmc *mmc = (struct mmc *)host->mmc; > + u32 ctrl; > + int ret; > + > + ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); > + > + switch (mmc->signal_voltage) { > + case MMC_SIGNAL_VOLTAGE_330: > +#if CONFIG_IS_ENABLED(DM_REGULATOR) > + if (mmc->vqmmc_supply) { > + ret = regulator_set_enable(mmc->vqmmc_supply, false); > + if (ret) { > + pr_err("failed to disable vqmmc-supply: %d\n", > ret); > + return; > + } > + > + ret = regulator_set_value(mmc->vqmmc_supply, 3300000); > + if (ret) { > + pr_err("failed to set vqmmc-voltage to 3.3V: > %d\n", ret); > + return; > + } > + > + ret = regulator_set_enable(mmc->vqmmc_supply, true); > + if (ret) { > + pr_err("failed to enable vqmmc-supply: %d\n", > ret); > + return; > + } > + } > +#endif > + mdelay(5);
Could you add just comment for mdelay(5)? Maybe it needs to be stable, right? Best Regards, Jaehoon Chung > + if (IS_SD(mmc)) { > + ctrl &= ~SDHCI_CTRL_VDD_180; > + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); > + } > + break; > + case MMC_SIGNAL_VOLTAGE_180: > +#if CONFIG_IS_ENABLED(DM_REGULATOR) > + if (mmc->vqmmc_supply) { > + regulator_set_enable(mmc->vqmmc_supply, false); > + if (ret) { > + pr_err("failed to disable vqmmc-supply: %d\n", > ret); > + return; > + } > + > + regulator_set_value(mmc->vqmmc_supply, 1800000); > + if (ret) { > + pr_err("failed to set vqmmc-voltage to 1.8V: > %d\n", ret); > + return; > + } > + > + regulator_set_enable(mmc->vqmmc_supply, true); > + if (ret) { > + pr_err("failed to enable vqmmc-supply: %d\n", > ret); > + return; > + } > + } > +#endif > + if (IS_SD(mmc)) { > + ctrl |= SDHCI_CTRL_VDD_180; > + sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); > + } > + break; > + default: > + /* No signal voltage switch required */ > + return; > + } > +} > +#else > +static void sdhci_set_voltage(struct sdhci_host *host) { } > +#endif > +void sdhci_set_control_reg(struct sdhci_host *host) > +{ > + sdhci_set_voltage(host); > + sdhci_set_uhs_timing(host); > +} > + > #ifdef CONFIG_DM_MMC > static int sdhci_set_ios(struct udevice *dev) > { > diff --git a/include/sdhci.h b/include/sdhci.h > index 3e5a64981857..0f820c6d2669 100644 > --- a/include/sdhci.h > +++ b/include/sdhci.h > @@ -491,6 +491,7 @@ void sdhci_set_uhs_timing(struct sdhci_host *host); > /* Export the operations to drivers */ > int sdhci_probe(struct udevice *dev); > int sdhci_set_clock(struct mmc *mmc, unsigned int clock); > +void sdhci_set_control_reg(struct sdhci_host *host); > extern const struct dm_mmc_ops sdhci_ops; > #else > #endif >