diff mbox series

[U-Boot,v3,04/24] mmc: omap_hsmmc: set MMC mode in the UHSMS bit field

Message ID 1517324513-13875-5-git-send-email-jjhiblot@ti.com
State Accepted
Commit 8fc238bfada16d61dee4240de2d49f38a6a6f941
Delegated to: Jaehoon Chung
Headers show
Series omap_hsmmc: Add support for HS200 and UHS modes | expand

Commit Message

Jean-Jacques Hiblot Jan. 30, 2018, 3:01 p.m. UTC
Use the timing parameter set in the MMC core to set the
mode in UHSMS  bit field. This is in preparation for
adding HS200 support in omap hsmmc driver.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>

---

Changes in v3:
- prefer the usage of the BIT() macro over the construct ( 1 << x )

 arch/arm/include/asm/omap_mmc.h | 12 ++++++++++-
 drivers/mmc/omap_hsmmc.c        | 47 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index c4d326d..507435a 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 5141bf6..c6b74a1 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;
 }