mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-01 22:07:21 +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 hsmmc *base_addr;
|
||||||
struct mmc mmc;
|
struct mmc mmc;
|
||||||
bool cd_inverted;
|
bool cd_inverted;
|
||||||
|
u32 controller_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -124,8 +125,10 @@ struct omap_hsmmc_plat {
|
||||||
#define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/
|
#define DTW_8_BITMODE (0x1 << 5) /* CON[DW8]*/
|
||||||
#define SDBP_PWROFF (0x0 << 8)
|
#define SDBP_PWROFF (0x0 << 8)
|
||||||
#define SDBP_PWRON (0x1 << 8)
|
#define SDBP_PWRON (0x1 << 8)
|
||||||
|
#define SDVS_MASK (0x7 << 9)
|
||||||
#define SDVS_1V8 (0x5 << 9)
|
#define SDVS_1V8 (0x5 << 9)
|
||||||
#define SDVS_3V0 (0x6 << 9)
|
#define SDVS_3V0 (0x6 << 9)
|
||||||
|
#define SDVS_3V3 (0x7 << 9)
|
||||||
#define DMA_SELECT (0x2 << 3)
|
#define DMA_SELECT (0x2 << 3)
|
||||||
#define ICE_MASK (0x1 << 0)
|
#define ICE_MASK (0x1 << 0)
|
||||||
#define ICE_STOP (0x0 << 0)
|
#define ICE_STOP (0x0 << 0)
|
||||||
|
@ -159,8 +162,13 @@ struct omap_hsmmc_plat {
|
||||||
#define IE_CERR (0x01 << 28)
|
#define IE_CERR (0x01 << 28)
|
||||||
#define IE_BADA (0x01 << 29)
|
#define IE_BADA (0x01 << 29)
|
||||||
|
|
||||||
#define VS30_3V0SUP (1 << 25)
|
#define VS33_3V3SUP BIT(24)
|
||||||
#define VS18_1V8SUP (1 << 26)
|
#define VS30_3V0SUP BIT(25)
|
||||||
|
#define VS18_1V8SUP BIT(26)
|
||||||
|
|
||||||
|
#define IOV_3V3 3300000
|
||||||
|
#define IOV_3V0 3000000
|
||||||
|
#define IOV_1V8 1800000
|
||||||
|
|
||||||
/* Driver definitions */
|
/* Driver definitions */
|
||||||
#define MMCSD_SECTOR_SIZE 512
|
#define MMCSD_SECTOR_SIZE 512
|
||||||
|
|
|
@ -73,6 +73,9 @@ struct omap_hsmmc_data {
|
||||||
int cd_gpio;
|
int cd_gpio;
|
||||||
int wp_gpio;
|
int wp_gpio;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IS_ENABLED(DM_MMC)
|
||||||
|
uint iov;
|
||||||
#endif
|
#endif
|
||||||
u8 controller_flags;
|
u8 controller_flags;
|
||||||
#ifndef CONFIG_OMAP34XX
|
#ifndef CONFIG_OMAP34XX
|
||||||
|
@ -111,6 +114,8 @@ struct omap_hsmmc_adma_desc {
|
||||||
* that the bandwidth is always above 3MB/s).
|
* that the bandwidth is always above 3MB/s).
|
||||||
*/
|
*/
|
||||||
#define DMA_TIMEOUT_PER_MB 333
|
#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)
|
#define OMAP_HSMMC_USE_ADMA BIT(2)
|
||||||
|
|
||||||
static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size);
|
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);
|
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)
|
static int omap_hsmmc_init_setup(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
struct omap_hsmmc_data *priv = omap_hsmmc_get_data(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)
|
if (reg_val & MADMA_EN)
|
||||||
priv->controller_flags |= OMAP_HSMMC_USE_ADMA;
|
priv->controller_flags |= OMAP_HSMMC_USE_ADMA;
|
||||||
#endif
|
#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(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
|
||||||
writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
|
writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
|
||||||
&mmc_base->capa);
|
&mmc_base->capa);
|
||||||
|
#endif
|
||||||
|
|
||||||
reg_val = readl(&mmc_base->con) & RESERVED_MASK;
|
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->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->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
||||||
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
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
|
#ifdef OMAP_HSMMC_USE_GPIO
|
||||||
plat->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted");
|
plat->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted");
|
||||||
|
|
Loading…
Add table
Reference in a new issue