]> git.ipfire.org Git - people/ms/u-boot.git/commitdiff
mmc: omap_hsmmc: Add support to get pinctrl values and max frequency for different...
authorKishon Vijay Abraham I <kishon@ti.com>
Tue, 30 Jan 2018 15:01:41 +0000 (16:01 +0100)
committerJaehoon Chung <jh80.chung@samsung.com>
Mon, 19 Feb 2018 07:58:55 +0000 (16:58 +0900)
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>
arch/arm/include/asm/arch-omap5/sys_proto.h
arch/arm/include/asm/omap_mmc.h
drivers/mmc/omap_hsmmc.c

index a6b3557b503bc376930c108b678881ecea7fdc65..d43cd7f2e72e8dc40cbd47e8be8ca0a2ac5f521a 100644 (file)
@@ -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)
 {
index 635ce1e488064b58cf385e288146ce6af8173c01..c50087e1357df23a3e961a863baea543c5f96648 100644 (file)
@@ -70,6 +70,7 @@ struct omap_hsmmc_plat {
        struct mmc mmc;
        bool cd_inverted;
        u32 controller_flags;
+       const char *hw_rev;
 };
 
 /*
index 2b77422eeebb3936ba0ddb044fbbbb675a898fc1..766cd09f7a764cfb273d874d903450ecb35c0083 100644 (file)
@@ -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