mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-01 17:10:11 +00:00
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>
This commit is contained in:
parent
48a2f11443
commit
b594481709
2 changed files with 77 additions and 2 deletions
|
@ -65,6 +65,7 @@ struct omap_hsmmc_plat {
|
|||
struct hsmmc *base_addr;
|
||||
struct mmc mmc;
|
||||
bool cd_inverted;
|
||||
u32 controller_flags;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -124,8 +125,10 @@ struct omap_hsmmc_plat {
|
|||
#define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/
|
||||
#define SDBP_PWROFF (0x0 << 8)
|
||||
#define SDBP_PWRON (0x1 << 8)
|
||||
#define SDVS_MASK (0x7 << 9)
|
||||
#define SDVS_1V8 (0x5 << 9)
|
||||
#define SDVS_3V0 (0x6 << 9)
|
||||
#define SDVS_3V3 (0x7 << 9)
|
||||
#define DMA_SELECT (0x2 << 3)
|
||||
#define ICE_MASK (0x1 << 0)
|
||||
#define ICE_STOP (0x0 << 0)
|
||||
|
@ -159,8 +162,13 @@ struct omap_hsmmc_plat {
|
|||
#define IE_CERR (0x01 << 28)
|
||||
#define IE_BADA (0x01 << 29)
|
||||
|
||||
#define VS30_3V0SUP (1 << 25)
|
||||
#define VS18_1V8SUP (1 << 26)
|
||||
#define VS33_3V3SUP BIT(24)
|
||||
#define VS30_3V0SUP BIT(25)
|
||||
#define VS18_1V8SUP BIT(26)
|
||||
|
||||
#define IOV_3V3 3300000
|
||||
#define IOV_3V0 3000000
|
||||
#define IOV_1V8 1800000
|
||||
|
||||
/* Driver definitions */
|
||||
#define MMCSD_SECTOR_SIZE 512
|
||||
|
|
|
@ -73,6 +73,9 @@ struct omap_hsmmc_data {
|
|||
int cd_gpio;
|
||||
int wp_gpio;
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_IS_ENABLED(DM_MMC)
|
||||
uint iov;
|
||||
#endif
|
||||
u8 controller_flags;
|
||||
#ifndef CONFIG_OMAP34XX
|
||||
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue