From mboxrd@z Thu Jan 1 00:00:00 1970 From: Carlo Caione Date: Thu, 7 Jun 2018 12:00:46 +0100 Subject: [U-Boot] [PATCH] mmc: dw_mmc: Handle pin voltage configuration Message-ID: <20180607110046.25770-1-carlo@caione.org> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de From: Carlo Caione Add support for pin voltage configuration. Besides to support UHS mode this is useful when the IO lines are connected to a configurable regulator not enabled at boot or always on. Signed-off-by: Carlo Caione --- drivers/mmc/dw_mmc.c | 34 ++++++++++++++++++++++++++++++++++ include/dwmmc.h | 26 ++++++++++++++------------ 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index 13180fc0d6..0841d516d2 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -12,6 +12,7 @@ #include #include #include +#include #define PAGE_SIZE 4096 @@ -382,6 +383,34 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) return 0; } +#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE) && CONFIG_IS_ENABLED(DM_REGULATOR) +static int dwmci_set_io_regulators(struct mmc *mmc) +{ + struct dwmci_host *host = (struct dwmci_host *)mmc->priv; + int uv = mmc_voltage_to_mv(mmc->signal_voltage) * 1000; + int ret = 0; + + if (!mmc->vqmmc_supply) + return 0; + + host->signal_voltage = mmc->signal_voltage; + + ret = regulator_set_enable(mmc->vqmmc_supply, false); + if (ret && ret != -ENOSYS) + return ret; + + ret = regulator_set_value(mmc->vqmmc_supply, uv); + if (ret) + return ret; + + ret = regulator_set_enable(mmc->vqmmc_supply, true); + if (ret && ret != -ENOSYS) + return ret; + + return 0; +} +#endif + #ifdef CONFIG_DM_MMC static int dwmci_set_ios(struct udevice *dev) { @@ -421,6 +450,11 @@ static int dwmci_set_ios(struct mmc *mmc) if (host->clksel) host->clksel(host); +#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE) && CONFIG_IS_ENABLED(DM_REGULATOR) + if (host->signal_voltage != mmc->signal_voltage) + return dwmci_set_io_regulators(mmc); +#endif + return 0; } diff --git a/include/dwmmc.h b/include/dwmmc.h index bc1d6e3abb..461141af54 100644 --- a/include/dwmmc.h +++ b/include/dwmmc.h @@ -133,18 +133,19 @@ /** * struct dwmci_host - Information about a designware MMC host * - * @name: Device name - * @ioaddr: Base I/O address of controller - * @quirks: Quick flags - see DWMCI_QUIRK_... - * @caps: Capabilities - see MMC_MODE_... - * @bus_hz: Bus speed in Hz, if @get_mmc_clk() is NULL - * @div: Arbitrary clock divider value for use by controller - * @dev_index: Arbitrary device index for use by controller - * @dev_id: Arbitrary device ID for use by controller - * @buswidth: Bus width in bits (8 or 4) - * @fifoth_val: Value for FIFOTH register (or 0 to leave unset) - * @mmc: Pointer to generic MMC structure for this device - * @priv: Private pointer for use by controller + * @name: Device name + * @ioaddr: Base I/O address of controller + * @quirks: Quick flags - see DWMCI_QUIRK_... + * @caps: Capabilities - see MMC_MODE_... + * @bus_hz: Bus speed in Hz, if @get_mmc_clk() is NULL + * @div: Arbitrary clock divider value for use by controller + * @signal_voltage: Current voltage for the IO lines + * @dev_index: Arbitrary device index for use by controller + * @dev_id: Arbitrary device ID for use by controller + * @buswidth: Bus width in bits (8 or 4) + * @fifoth_val: Value for FIFOTH register (or 0 to leave unset) + * @mmc: Pointer to generic MMC structure for this device + * @priv: Private pointer for use by controller */ struct dwmci_host { const char *name; @@ -155,6 +156,7 @@ struct dwmci_host { unsigned int clock; unsigned int bus_hz; unsigned int div; + unsigned int signal_voltage; int dev_index; int dev_id; int buswidth; -- 2.17.1