summaryrefslogtreecommitdiff
path: root/drivers/mmc/omap_hsmmc.c
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2018-01-30 16:01:32 +0100
committerJaehoon Chung <jh80.chung@samsung.com>2018-02-19 16:58:54 +0900
commitb59448170934094570a497ff7c5b4b2e94cff5a2 (patch)
tree4bc713080efeceb587d93d685b2af83815915e83 /drivers/mmc/omap_hsmmc.c
parent48a2f11443a1f15c1dcee4f2051f12edc6378510 (diff)
mmc: omap_hsmmc: add support to set default io voltage
"ti,dual-volt" is used in linux kernel to set the voltage capabilities. For host controller dt nodes that doesn't have "ti,dual-volt", it's assumed 1.8v is the io voltage. This is not always true (like in the case of beagle-x15 where the io lines are connected to 3.3v). Hence if "no-1-8-v" property is set, io voltage will be set to 3v. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Diffstat (limited to 'drivers/mmc/omap_hsmmc.c')
-rw-r--r--drivers/mmc/omap_hsmmc.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 713faab110..5141bf66e1 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -74,6 +74,9 @@ struct omap_hsmmc_data {
int wp_gpio;
#endif
#endif
+#if CONFIG_IS_ENABLED(DM_MMC)
+ uint iov;
+#endif
u8 controller_flags;
#ifndef CONFIG_OMAP34XX
struct omap_hsmmc_adma_desc *adma_desc_table;
@@ -111,6 +114,8 @@ struct omap_hsmmc_adma_desc {
* that the bandwidth is always above 3MB/s).
*/
#define DMA_TIMEOUT_PER_MB 333
+#define OMAP_HSMMC_SUPPORTS_DUAL_VOLT BIT(0)
+#define OMAP_HSMMC_NO_1_8_V BIT(1)
#define OMAP_HSMMC_USE_ADMA BIT(2)
static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
@@ -252,6 +257,58 @@ void mmc_init_stream(struct hsmmc *mmc_base)
writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
}
+#if CONFIG_IS_ENABLED(DM_MMC)
+static void omap_hsmmc_conf_bus_power(struct mmc *mmc)
+{
+ struct hsmmc *mmc_base;
+ struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+ u32 val;
+
+ mmc_base = priv->base_addr;
+
+ val = readl(&mmc_base->hctl) & ~SDVS_MASK;
+
+ switch (priv->iov) {
+ case IOV_3V3:
+ val |= SDVS_3V3;
+ break;
+ case IOV_3V0:
+ val |= SDVS_3V0;
+ break;
+ case IOV_1V8:
+ val |= SDVS_1V8;
+ break;
+ }
+
+ writel(val, &mmc_base->hctl);
+}
+
+static void omap_hsmmc_set_capabilities(struct mmc *mmc)
+{
+ struct hsmmc *mmc_base;
+ struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+ u32 val;
+
+ mmc_base = priv->base_addr;
+ val = readl(&mmc_base->capa);
+
+ if (priv->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
+ val |= (VS30_3V0SUP | VS18_1V8SUP);
+ priv->iov = IOV_3V0;
+ } else if (priv->controller_flags & OMAP_HSMMC_NO_1_8_V) {
+ val |= VS30_3V0SUP;
+ val &= ~VS18_1V8SUP;
+ priv->iov = IOV_3V0;
+ } else {
+ val |= VS18_1V8SUP;
+ val &= ~VS30_3V0SUP;
+ priv->iov = IOV_1V8;
+ }
+
+ writel(val, &mmc_base->capa);
+}
+#endif
+
static int omap_hsmmc_init_setup(struct mmc *mmc)
{
struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
@@ -286,9 +343,15 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
if (reg_val & MADMA_EN)
priv->controller_flags |= OMAP_HSMMC_USE_ADMA;
#endif
+
+#if CONFIG_IS_ENABLED(DM_MMC)
+ omap_hsmmc_set_capabilities(mmc);
+ omap_hsmmc_conf_bus_power(mmc);
+#else
writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
&mmc_base->capa);
+#endif
reg_val = readl(&mmc_base->con) & RESERVED_MASK;
@@ -1071,6 +1134,10 @@ static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000);
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+ if (fdtdec_get_bool(fdt, node, "ti,dual-volt"))
+ plat->controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT;
+ if (fdtdec_get_bool(fdt, node, "no-1-8-v"))
+ plat->controller_flags |= OMAP_HSMMC_NO_1_8_V;
#ifdef OMAP_HSMMC_USE_GPIO
plat->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted");