[U-Boot] [PATCH] mmc: dw_mmc: Handle pin voltage configuration

Carlo Caione carlo at caione.org
Thu Jun 7 11:00:46 UTC 2018


From: Carlo Caione <carlo at endlessm.com>

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 <carlo at endlessm.com>
---
 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 <memalign.h>
 #include <mmc.h>
 #include <dwmmc.h>
+#include <power/regulator.h>
 
 #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



More information about the U-Boot mailing list