@@ -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)
{
@@ -70,6 +70,7 @@ struct omap_hsmmc_plat {
struct mmc mmc;
bool cd_inverted;
u32 controller_flags;
+ const char *hw_rev;
};
/*
@@ -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