summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/omap_mmc.h12
-rw-r--r--drivers/mmc/omap_hsmmc.c47
2 files changed, 58 insertions, 1 deletions
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index c4d326dfc15..507435a11f3 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -53,7 +53,8 @@ struct hsmmc {
unsigned int sysctl; /* 0x12C */
unsigned int stat; /* 0x130 */
unsigned int ie; /* 0x134 */
- unsigned char res4[0x8];
+ unsigned char res4[0x4];
+ unsigned int ac12; /* 0x13C */
unsigned int capa; /* 0x140 */
unsigned char res5[0x10];
unsigned int admaes; /* 0x154 */
@@ -170,6 +171,15 @@ struct omap_hsmmc_plat {
#define IOV_3V0 3000000
#define IOV_1V8 1800000
+#define AC12_ET BIT(22)
+#define AC12_UHSMC_MASK (7 << 16)
+#define AC12_UHSMC_DDR50 (4 << 16)
+#define AC12_UHSMC_SDR104 (3 << 16)
+#define AC12_UHSMC_SDR50 (2 << 16)
+#define AC12_UHSMC_SDR25 (1 << 16)
+#define AC12_UHSMC_SDR12 (0 << 16)
+#define AC12_UHSMC_RES (0x7 << 16)
+
/* Driver definitions */
#define MMCSD_SECTOR_SIZE 512
#define MMC_CARD 0
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 5141bf66e12..c6b74a1263f 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -76,6 +76,7 @@ struct omap_hsmmc_data {
#endif
#if CONFIG_IS_ENABLED(DM_MMC)
uint iov;
+ enum bus_mode mode;
#endif
u8 controller_flags;
#ifndef CONFIG_OMAP34XX
@@ -258,6 +259,48 @@ void mmc_init_stream(struct hsmmc *mmc_base)
}
#if CONFIG_IS_ENABLED(DM_MMC)
+static void omap_hsmmc_set_timing(struct mmc *mmc)
+{
+ u32 val;
+ struct hsmmc *mmc_base;
+ struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc);
+
+ mmc_base = priv->base_addr;
+
+ val = readl(&mmc_base->ac12);
+ val &= ~AC12_UHSMC_MASK;
+ priv->mode = mmc->selected_mode;
+
+ switch (priv->mode) {
+ case MMC_HS_200:
+ case UHS_SDR104:
+ val |= AC12_UHSMC_SDR104;
+ break;
+ case UHS_SDR50:
+ val |= AC12_UHSMC_SDR50;
+ break;
+ case MMC_DDR_52:
+ case UHS_DDR50:
+ val |= AC12_UHSMC_DDR50;
+ break;
+ case SD_HS:
+ case MMC_HS_52:
+ case UHS_SDR25:
+ val |= AC12_UHSMC_SDR25;
+ break;
+ case MMC_LEGACY:
+ case MMC_HS:
+ case SD_LEGACY:
+ case UHS_SDR12:
+ val |= AC12_UHSMC_SDR12;
+ break;
+ default:
+ val |= AC12_UHSMC_RES;
+ break;
+ }
+ writel(val, &mmc_base->ac12);
+}
+
static void omap_hsmmc_conf_bus_power(struct mmc *mmc)
{
struct hsmmc *mmc_base;
@@ -928,6 +971,10 @@ static int omap_hsmmc_set_ios(struct udevice *dev)
if (priv->clock != mmc->clock)
omap_hsmmc_set_clock(mmc);
+#if CONFIG_IS_ENABLED(DM_MMC)
+ if (priv->mode != mmc->selected_mode)
+ omap_hsmmc_set_timing(mmc);
+#endif
return 0;
}