[v3,12/24] mmc: omap_hsmmc: Add support to get pinctrl values and max frequency for different hw revisions

Message ID 1517324513-13875-13-git-send-email-jjhiblot@ti.com
State New
Headers show
Series
  • Untitled series #8505
Related show

Commit Message

Jean-Jacques Hiblot Jan. 30, 2018, 3:01 p.m.
From: Kishon Vijay Abraham I <kishon@ti.com>

AM572x SR1.1 requires different IODelay values to be used than that used
in AM572x SR2.0. These values are populated in device tree. Add
capability in omap_hsmmc driver to extract IOdelay values for different
silicon revision. The maximum frequency is also reduced when using a ES1.1.
To keep the ability to boot both revsions with the same dtb, those values
can be provided by the platform code.

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

Changes in v3: None

 arch/arm/include/asm/arch-omap5/sys_proto.h |  7 ++++
 arch/arm/include/asm/omap_mmc.h             |  1 +
 drivers/mmc/omap_hsmmc.c                    | 58 ++++++++++++++++++++++-------
 3 files changed, 52 insertions(+), 14 deletions(-)

Patch

diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h
index a6b3557..d43cd7f 100644
--- a/arch/arm/include/asm/arch-omap5/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap5/sys_proto.h
@@ -35,6 +35,12 @@  struct pad_conf_entry {
 	u32 val;
 };
 
+struct mmc_platform_fixups {
+	const char *hw_rev;
+	u32 unsupported_caps;
+	u32 max_freq;
+};
+
 struct omap_sysinfo {
 	char *board_string;
 };
@@ -71,6 +77,7 @@  void force_emif_self_refresh(void);
 void get_ioregs(const struct ctrl_ioregs **regs);
 void srcomp_enable(void);
 void setup_warmreset_time(void);
+const struct mmc_platform_fixups *platform_fixups_mmc(uint32_t addr);
 
 static inline u32 div_round_up(u32 num, u32 den)
 {
diff --git a/arch/arm/include/asm/omap_mmc.h b/arch/arm/include/asm/omap_mmc.h
index 635ce1e..c50087e 100644
--- a/arch/arm/include/asm/omap_mmc.h
+++ b/arch/arm/include/asm/omap_mmc.h
@@ -70,6 +70,7 @@  struct omap_hsmmc_plat {
 	struct mmc mmc;
 	bool cd_inverted;
 	u32 controller_flags;
+	const char *hw_rev;
 };
 
 /*
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 2b77422..766cd09 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -96,6 +96,7 @@  struct omap_hsmmc_data {
 	struct omap_hsmmc_adma_desc *adma_desc_table;
 	uint desc_slot;
 #endif
+	const char *hw_rev;
 #ifdef CONFIG_IODELAY_RECALIBRATION
 	struct omap_hsmmc_pinctrl_state *default_pinctrl_state;
 	struct omap_hsmmc_pinctrl_state *hs_pinctrl_state;
@@ -1368,6 +1369,7 @@  int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
 	if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21))
 		cfg->b_max = 1;
 #endif
+
 	mmc = mmc_create(cfg, priv);
 	if (mmc == NULL)
 		return -1;
@@ -1587,20 +1589,28 @@  err_pinctrl_state:
 	return 0;
 }
 
-#define OMAP_HSMMC_SETUP_PINCTRL(capmask, mode)			\
-	do {							\
-		struct omap_hsmmc_pinctrl_state *s;		\
-		if (!(cfg->host_caps & capmask))		\
-			break;					\
-								\
-		s = omap_hsmmc_get_pinctrl_by_mode(mmc, #mode);	\
-		if (!s) {					\
-			debug("%s: no pinctrl for %s\n",	\
-			      mmc->dev->name, #mode);		\
-			cfg->host_caps &= ~(capmask);		\
-		} else {					\
-			priv->mode##_pinctrl_state = s;		\
-		}						\
+#define OMAP_HSMMC_SETUP_PINCTRL(capmask, mode)				\
+	do {								\
+		struct omap_hsmmc_pinctrl_state *s = NULL;		\
+		char str[20];						\
+		if (!(cfg->host_caps & capmask))			\
+			break;						\
+									\
+		if (priv->hw_rev) {					\
+			sprintf(str, "%s-%s", #mode, priv->hw_rev);	\
+			s = omap_hsmmc_get_pinctrl_by_mode(mmc, str);	\
+		}							\
+									\
+		if (!s)							\
+			s = omap_hsmmc_get_pinctrl_by_mode(mmc, #mode);	\
+									\
+		if (!s) {						\
+			debug("%s: no pinctrl for %s\n",		\
+			      mmc->dev->name, #mode);			\
+			cfg->host_caps &= ~(capmask);			\
+		} else {						\
+			priv->mode##_pinctrl_state = s;			\
+		}							\
 	} while (0)
 
 static int omap_hsmmc_get_pinctrl_state(struct mmc *mmc)
@@ -1635,12 +1645,22 @@  static int omap_hsmmc_get_pinctrl_state(struct mmc *mmc)
 #endif
 
 #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+#ifdef CONFIG_OMAP54XX
+__weak const struct mmc_platform_fixups *platform_fixups_mmc(uint32_t addr)
+{
+	return NULL;
+}
+#endif
+
 static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
 {
 	struct omap_hsmmc_plat *plat = dev_get_platdata(dev);
 	struct omap_mmc_of_data *of_data = (void *)dev_get_driver_data(dev);
 
 	struct mmc_config *cfg = &plat->cfg;
+#ifdef CONFIG_OMAP54XX
+	const struct mmc_platform_fixups *fixups;
+#endif
 	const void *fdt = gd->fdt_blob;
 	int node = dev_of_offset(dev);
 	int ret;
@@ -1664,6 +1684,15 @@  static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev)
 	if (of_data)
 		plat->controller_flags |= of_data->controller_flags;
 
+#ifdef CONFIG_OMAP54XX
+	fixups = platform_fixups_mmc(devfdt_get_addr(dev));
+	if (fixups) {
+		plat->hw_rev = fixups->hw_rev;
+		cfg->host_caps &= ~fixups->unsupported_caps;
+		cfg->f_max = fixups->max_freq;
+	}
+#endif
+
 #ifdef OMAP_HSMMC_USE_GPIO
 	plat->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted");
 #endif
@@ -1695,6 +1724,7 @@  static int omap_hsmmc_probe(struct udevice *dev)
 	cfg->name = "OMAP SD/MMC";
 	priv->base_addr = plat->base_addr;
 	priv->controller_flags = plat->controller_flags;
+	priv->hw_rev = plat->hw_rev;
 #ifdef OMAP_HSMMC_USE_GPIO
 	priv->cd_inverted = plat->cd_inverted;
 #endif