summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-03-11 04:13:26 +0300
committerTom Rini <trini@konsulko.com>2020-03-11 04:13:26 +0300
commit36bdcf7f3b17ec6d8cec782e7f1d5b0b8014300a (patch)
tree69ae3cbd98f15b99fc390c4ba19457b103a8ebd7 /drivers
parentdb41d985f6bbf42f83a91b1e4a321a97d72aa843 (diff)
parent59af57f3cfaa4416e4b918c07f7360c5b80ce448 (diff)
downloadu-boot-36bdcf7f3b17ec6d8cec782e7f1d5b0b8014300a.tar.xz
Merge tag 'mmc-2020-3-9' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmc
- DM support for CAxxxx SoCs - eMMC board for presidio-asic - Add defer probe for mmc sdhci - TI SoCs mmc misc update
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/Kconfig11
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/am654_sdhci.c173
-rw-r--r--drivers/mmc/ca_dw_mmc.c181
-rw-r--r--drivers/mmc/fsl_esdhc_imx.c1
-rw-r--r--drivers/mmc/mmc-uclass.c15
-rw-r--r--drivers/mmc/mmc.c20
-rw-r--r--drivers/mmc/omap_hsmmc.c1
-rw-r--r--drivers/mmc/sdhci.c15
-rw-r--r--drivers/mmc/zynq_sdhci.c1
10 files changed, 359 insertions, 60 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 2f0eedc22f..bb38787eca 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -205,6 +205,17 @@ config MMC_DW
block, this provides host support for SD and MMC interfaces, in both
PIO, internal DMA mode and external DMA mode.
+config MMC_DW_CORTINA
+ bool "Cortina specific extensions for Synopsys DW Memory Card Interface"
+ depends on DM_MMC
+ depends on MMC_DW
+ depends on BLK
+ default n
+ help
+ This selects support for Cortina SoC specific extensions to the
+ Synopsys DesignWare Memory Card Interface driver. Select this option
+ for platforms based on Cortina CAxxxx Soc's.
+
config MMC_DW_EXYNOS
bool "Exynos specific extensions for Synopsys DW Memory Card Interface"
depends on ARCH_EXYNOS
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 9c1f8e56e2..615b724bf0 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -20,6 +20,7 @@ endif
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o
obj-$(CONFIG_MMC_DW) += dw_mmc.o
+obj-$(CONFIG_MMC_DW_CORTINA) += ca_dw_mmc.o
obj-$(CONFIG_MMC_DW_EXYNOS) += exynos_dw_mmc.o
obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o
obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
index aad9d8b85b..ca76e1f559 100644
--- a/drivers/mmc/am654_sdhci.c
+++ b/drivers/mmc/am654_sdhci.c
@@ -74,7 +74,7 @@ struct am654_sdhci_plat {
struct mmc mmc;
struct regmap *base;
bool non_removable;
- u32 otap_del_sel;
+ u32 otap_del_sel[11];
u32 trm_icp;
u32 drv_strength;
u32 strb_sel;
@@ -86,6 +86,25 @@ struct am654_sdhci_plat {
bool dll_on;
};
+struct timing_data {
+ const char *binding;
+ u32 capability;
+};
+
+static const struct timing_data td[] = {
+ [MMC_LEGACY] = {"ti,otap-del-sel-legacy", 0},
+ [MMC_HS] = {"ti,otap-del-sel-mmc-hs", MMC_CAP(MMC_HS)},
+ [SD_HS] = {"ti,otap-del-sel-sd-hs", MMC_CAP(SD_HS)},
+ [UHS_SDR12] = {"ti,otap-del-sel-sdr12", MMC_CAP(UHS_SDR12)},
+ [UHS_SDR25] = {"ti,otap-del-sel-sdr25", MMC_CAP(UHS_SDR25)},
+ [UHS_SDR50] = {"ti,otap-del-sel-sdr50", MMC_CAP(UHS_SDR50)},
+ [UHS_SDR104] = {"ti,otap-del-sel-sdr104", MMC_CAP(UHS_SDR104)},
+ [UHS_DDR50] = {"ti,otap-del-sel-ddr50", MMC_CAP(UHS_DDR50)},
+ [MMC_DDR_52] = {"ti,otap-del-sel-ddr52", MMC_CAP(MMC_DDR_52)},
+ [MMC_HS_200] = {"ti,otap-del-sel-hs200", MMC_CAP(MMC_HS_200)},
+ [MMC_HS_400] = {"ti,otap-del-sel-hs400", MMC_CAP(MMC_HS_400)},
+};
+
struct am654_driver_data {
const struct sdhci_ops *ops;
u32 flags;
@@ -112,6 +131,7 @@ static int am654_sdhci_set_ios_post(struct sdhci_host *host)
struct am654_sdhci_plat *plat = dev_get_platdata(dev);
unsigned int speed = host->mmc->clock;
int sel50, sel100, freqsel;
+ u32 otap_del_sel;
u32 mask, val;
int ret;
@@ -132,9 +152,10 @@ static int am654_sdhci_set_ios_post(struct sdhci_host *host)
/* switch phy back on */
if (speed > AM654_SDHCI_MIN_FREQ) {
+ otap_del_sel = plat->otap_del_sel[host->mmc->selected_mode];
mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
val = (1 << OTAPDLYENA_SHIFT) |
- (plat->otap_del_sel << OTAPDLYSEL_SHIFT);
+ (otap_del_sel << OTAPDLYSEL_SHIFT);
/* Write to STRBSEL for HS400 speed mode */
if (host->mmc->selected_mode == MMC_HS_400) {
@@ -197,44 +218,6 @@ static int am654_sdhci_set_ios_post(struct sdhci_host *host)
return 0;
}
-const struct sdhci_ops am654_sdhci_ops = {
- .set_ios_post = &am654_sdhci_set_ios_post,
- .set_control_reg = &am654_sdhci_set_control_reg,
-};
-
-const struct am654_driver_data am654_drv_data = {
- .ops = &am654_sdhci_ops,
- .flags = IOMUX_PRESENT | FREQSEL_2_BIT | DLL_PRESENT | STRBSEL_4_BIT,
-};
-
-const struct am654_driver_data j721e_8bit_drv_data = {
- .ops = &am654_sdhci_ops,
- .flags = DLL_PRESENT,
-};
-
-static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host)
-{
- struct udevice *dev = host->mmc->dev;
- struct am654_sdhci_plat *plat = dev_get_platdata(dev);
- u32 mask, val;
-
- mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
- val = (1 << OTAPDLYENA_SHIFT) |
- (plat->otap_del_sel << OTAPDLYSEL_SHIFT);
- regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
-
- return 0;
-}
-
-const struct sdhci_ops j721e_4bit_sdhci_ops = {
- .set_ios_post = &j721e_4bit_sdhci_set_ios_post,
-};
-
-const struct am654_driver_data j721e_4bit_drv_data = {
- .ops = &j721e_4bit_sdhci_ops,
- .flags = IOMUX_PRESENT,
-};
-
int am654_sdhci_init(struct am654_sdhci_plat *plat)
{
u32 ctl_cfg_2 = 0;
@@ -281,6 +264,104 @@ int am654_sdhci_init(struct am654_sdhci_plat *plat)
return 0;
}
+#define MAX_SDCD_DEBOUNCE_TIME 2000
+static int am654_sdhci_deferred_probe(struct sdhci_host *host)
+{
+ struct udevice *dev = host->mmc->dev;
+ struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+ unsigned long start;
+ int val;
+
+ /*
+ * The controller takes about 1 second to debounce the card detect line
+ * and doesn't let us power on until that time is up. Instead of waiting
+ * for 1 second at every stage, poll on the CARD_PRESENT bit upto a
+ * maximum of 2 seconds to be safe..
+ */
+ start = get_timer(0);
+ do {
+ if (get_timer(start) > MAX_SDCD_DEBOUNCE_TIME)
+ return -ENOMEDIUM;
+
+ val = mmc_getcd(host->mmc);
+ } while (!val);
+
+ am654_sdhci_init(plat);
+
+ return sdhci_probe(dev);
+}
+
+const struct sdhci_ops am654_sdhci_ops = {
+ .deferred_probe = am654_sdhci_deferred_probe,
+ .set_ios_post = &am654_sdhci_set_ios_post,
+ .set_control_reg = &am654_sdhci_set_control_reg,
+};
+
+const struct am654_driver_data am654_drv_data = {
+ .ops = &am654_sdhci_ops,
+ .flags = IOMUX_PRESENT | FREQSEL_2_BIT | DLL_PRESENT | STRBSEL_4_BIT,
+};
+
+const struct am654_driver_data j721e_8bit_drv_data = {
+ .ops = &am654_sdhci_ops,
+ .flags = DLL_PRESENT,
+};
+
+static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host)
+{
+ struct udevice *dev = host->mmc->dev;
+ struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+ u32 otap_del_sel, mask, val;
+
+ otap_del_sel = plat->otap_del_sel[host->mmc->selected_mode];
+ mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
+ val = (1 << OTAPDLYENA_SHIFT) | (otap_del_sel << OTAPDLYSEL_SHIFT);
+ regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
+
+ return 0;
+}
+
+const struct sdhci_ops j721e_4bit_sdhci_ops = {
+ .deferred_probe = am654_sdhci_deferred_probe,
+ .set_ios_post = &j721e_4bit_sdhci_set_ios_post,
+};
+
+const struct am654_driver_data j721e_4bit_drv_data = {
+ .ops = &j721e_4bit_sdhci_ops,
+ .flags = IOMUX_PRESENT,
+};
+
+static int sdhci_am654_get_otap_delay(struct udevice *dev,
+ struct mmc_config *cfg)
+{
+ struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+ int ret;
+ int i;
+
+ /* ti,otap-del-sel-legacy is mandatory */
+ ret = dev_read_u32(dev, "ti,otap-del-sel-legacy",
+ &plat->otap_del_sel[0]);
+ if (ret)
+ return ret;
+ /*
+ * Remove the corresponding capability if an otap-del-sel
+ * value is not found
+ */
+ for (i = MMC_HS; i <= MMC_HS_400; i++) {
+ ret = dev_read_u32(dev, td[i].binding, &plat->otap_del_sel[i]);
+ if (ret) {
+ dev_dbg(dev, "Couldn't find %s\n", td[i].binding);
+ /*
+ * Remove the corresponding capability
+ * if an otap-del-sel value is not found
+ */
+ cfg->host_caps &= ~td[i].capability;
+ }
+ }
+
+ return 0;
+}
+
static int am654_sdhci_probe(struct udevice *dev)
{
struct am654_driver_data *drv_data =
@@ -313,15 +394,17 @@ static int am654_sdhci_probe(struct udevice *dev)
if (ret)
return ret;
+ ret = sdhci_am654_get_otap_delay(dev, cfg);
+ if (ret)
+ return ret;
+
host->ops = drv_data->ops;
host->mmc->priv = host;
upriv->mmc = host->mmc;
regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
- am654_sdhci_init(plat);
-
- return sdhci_probe(dev);
+ return 0;
}
static int am654_sdhci_ofdata_to_platdata(struct udevice *dev)
@@ -336,10 +419,6 @@ static int am654_sdhci_ofdata_to_platdata(struct udevice *dev)
host->ioaddr = (void *)dev_read_addr(dev);
plat->non_removable = dev_read_bool(dev, "non-removable");
- ret = dev_read_u32(dev, "ti,otap-del-sel", &plat->otap_del_sel);
- if (ret)
- return ret;
-
if (plat->flags & DLL_PRESENT) {
ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
if (ret)
diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c
new file mode 100644
index 0000000000..acbc850fcb
--- /dev/null
+++ b/drivers/mmc/ca_dw_mmc.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Cortina Access
+ * Arthur Li <arthur.li@cortina-access.com>
+ */
+
+#include <common.h>
+#include <dwmmc.h>
+#include <fdtdec.h>
+#include <linux/libfdt.h>
+#include <malloc.h>
+#include <errno.h>
+#include <dm.h>
+#include <mapmem.h>
+
+#define SD_CLK_SEL_MASK (0x3)
+#define SD_DLL_DEFAULT (0x143000)
+#define SD_SCLK_MAX (200000000)
+
+#define SD_CLK_SEL_200MHZ (0x2)
+#define SD_CLK_SEL_100MHZ (0x1)
+
+#define IO_DRV_SD_DS_OFFSET (16)
+#define IO_DRV_SD_DS_MASK (0xff << IO_DRV_SD_DS_OFFSET)
+
+#define MIN_FREQ (400000)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ca_mmc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+struct ca_dwmmc_priv_data {
+ struct dwmci_host host;
+ void __iomem *sd_dll_reg;
+ void __iomem *io_drv_reg;
+ u8 ds;
+};
+
+static void ca_dwmci_clksel(struct dwmci_host *host)
+{
+ struct ca_dwmmc_priv_data *priv = host->priv;
+ u32 val = readl(priv->sd_dll_reg);
+
+ if (host->bus_hz >= 200000000) {
+ val &= ~SD_CLK_SEL_MASK;
+ val |= SD_CLK_SEL_200MHZ;
+ } else if (host->bus_hz >= 100000000) {
+ val &= ~SD_CLK_SEL_MASK;
+ val |= SD_CLK_SEL_100MHZ;
+ } else {
+ val &= ~SD_CLK_SEL_MASK;
+ }
+
+ writel(val, priv->sd_dll_reg);
+}
+
+static void ca_dwmci_board_init(struct dwmci_host *host)
+{
+ struct ca_dwmmc_priv_data *priv = host->priv;
+ u32 val = readl(priv->io_drv_reg);
+
+ writel(SD_DLL_DEFAULT, priv->sd_dll_reg);
+
+ val &= ~IO_DRV_SD_DS_MASK;
+ if (priv && priv->ds)
+ val |= priv->ds << IO_DRV_SD_DS_OFFSET;
+ writel(val, priv->io_drv_reg);
+}
+
+unsigned int ca_dwmci_get_mmc_clock(struct dwmci_host *host, uint freq)
+{
+ struct ca_dwmmc_priv_data *priv = host->priv;
+ u8 sd_clk_sel = readl(priv->sd_dll_reg) & SD_CLK_SEL_MASK;
+ u8 clk_div;
+
+ switch (sd_clk_sel) {
+ case 2:
+ clk_div = 1;
+ break;
+ case 1:
+ clk_div = 2;
+ break;
+ default:
+ clk_div = 4;
+ }
+
+ return SD_SCLK_MAX / clk_div / (host->div + 1);
+}
+
+static int ca_dwmmc_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
+ u32 tmp;
+
+ host->name = dev->name;
+ host->dev_index = 0;
+
+ host->buswidth = dev_read_u32_default(dev, "bus-width", 1);
+ if (host->buswidth != 1 && host->buswidth != 4)
+ return -EINVAL;
+
+ host->bus_hz = dev_read_u32_default(dev, "max-frequency", 50000000);
+ priv->ds = dev_read_u32_default(dev, "io_ds", 0x33);
+ host->fifo_mode = dev_read_bool(dev, "fifo-mode");
+
+ dev_read_u32(dev, "sd_dll_ctrl", &tmp);
+ priv->sd_dll_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
+ if (!priv->sd_dll_reg)
+ return -EINVAL;
+
+ dev_read_u32(dev, "io_drv_ctrl", &tmp);
+ priv->io_drv_reg = map_sysmem((uintptr_t)tmp, sizeof(uintptr_t));
+ if (!priv->io_drv_reg)
+ return -EINVAL;
+
+ host->ioaddr = dev_read_addr_ptr(dev);
+ if (host->ioaddr == (void *)FDT_ADDR_T_NONE) {
+ printf("DWMMC: base address is invalid\n");
+ return -EINVAL;
+ }
+
+ host->priv = priv;
+
+ return 0;
+}
+
+struct dm_mmc_ops ca_dwmci_dm_ops;
+
+static int ca_dwmmc_probe(struct udevice *dev)
+{
+ struct ca_mmc_plat *plat = dev_get_platdata(dev);
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct ca_dwmmc_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
+
+ memcpy(&ca_dwmci_dm_ops, &dm_dwmci_ops, sizeof(struct dm_mmc_ops));
+
+ dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, MIN_FREQ);
+ if (host->buswidth == 1) {
+ (&plat->cfg)->host_caps &= ~MMC_MODE_8BIT;
+ (&plat->cfg)->host_caps &= ~MMC_MODE_4BIT;
+ }
+
+ host->mmc = &plat->mmc;
+ host->mmc->priv = &priv->host;
+ upriv->mmc = host->mmc;
+ host->mmc->dev = dev;
+ host->clksel = ca_dwmci_clksel;
+ host->board_init = ca_dwmci_board_init;
+ host->get_mmc_clk = ca_dwmci_get_mmc_clock;
+
+ return dwmci_probe(dev);
+}
+
+static int ca_dwmmc_bind(struct udevice *dev)
+{
+ struct ca_mmc_plat *plat = dev_get_platdata(dev);
+
+ return dwmci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id ca_dwmmc_ids[] = {
+ { .compatible = "snps,dw-cortina" },
+ { }
+};
+
+U_BOOT_DRIVER(ca_dwmmc_drv) = {
+ .name = "cortina_dwmmc",
+ .id = UCLASS_MMC,
+ .of_match = ca_dwmmc_ids,
+ .ofdata_to_platdata = ca_dwmmc_ofdata_to_platdata,
+ .bind = ca_dwmmc_bind,
+ .ops = &ca_dwmci_dm_ops,
+ .probe = ca_dwmmc_probe,
+ .priv_auto_alloc_size = sizeof(struct ca_dwmmc_priv_data),
+ .platdata_auto_alloc_size = sizeof(struct ca_mmc_plat),
+};
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 4900498e9b..6bca2a9c82 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -743,7 +743,6 @@ static int esdhc_set_timing(struct mmc *mmc)
switch (mmc->selected_mode) {
case MMC_LEGACY:
- case SD_LEGACY:
esdhc_reset_tuning(mmc);
writel(mixctrl, &regs->mixctrl);
break;
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 0b90a97650..c75892a72c 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -138,6 +138,21 @@ int mmc_host_power_cycle(struct mmc *mmc)
return dm_mmc_host_power_cycle(mmc->dev);
}
+int dm_mmc_deferred_probe(struct udevice *dev)
+{
+ struct dm_mmc_ops *ops = mmc_get_ops(dev);
+
+ if (ops->deferred_probe)
+ return ops->deferred_probe(dev);
+
+ return 0;
+}
+
+int mmc_deferred_probe(struct mmc *mmc)
+{
+ return dm_mmc_deferred_probe(mmc->dev);
+}
+
int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
{
int val;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index b50fcbf6cf..3e36566693 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -132,7 +132,6 @@ const char *mmc_mode_name(enum bus_mode mode)
{
static const char *const names[] = {
[MMC_LEGACY] = "MMC legacy",
- [SD_LEGACY] = "SD Legacy",
[MMC_HS] = "MMC High Speed (26MHz)",
[SD_HS] = "SD High Speed (50MHz)",
[UHS_SDR12] = "UHS SDR12 (25MHz)",
@@ -158,7 +157,6 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
{
static const int freqs[] = {
[MMC_LEGACY] = 25000000,
- [SD_LEGACY] = 25000000,
[MMC_HS] = 26000000,
[SD_HS] = 50000000,
[MMC_HS_52] = 52000000,
@@ -1239,7 +1237,7 @@ static int sd_get_capabilities(struct mmc *mmc)
u32 sd3_bus_mode;
#endif
- mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
+ mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(MMC_LEGACY);
if (mmc_host_is_spi(mmc))
return 0;
@@ -1352,7 +1350,7 @@ static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
return 0;
switch (mode) {
- case SD_LEGACY:
+ case MMC_LEGACY:
speed = UHS_SDR12_BUS_SPEED;
break;
case SD_HS:
@@ -1695,7 +1693,7 @@ static const struct mode_width_tuning sd_modes_by_pref[] = {
},
#endif
{
- .mode = SD_LEGACY,
+ .mode = MMC_LEGACY,
.widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
}
};
@@ -1725,7 +1723,7 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
if (mmc_host_is_spi(mmc)) {
mmc_set_bus_width(mmc, 1);
- mmc_select_mode(mmc, SD_LEGACY);
+ mmc_select_mode(mmc, MMC_LEGACY);
mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
return 0;
}
@@ -1784,7 +1782,7 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
error:
/* revert to a safer bus speed */
- mmc_select_mode(mmc, SD_LEGACY);
+ mmc_select_mode(mmc, MMC_LEGACY);
mmc_set_clock(mmc, mmc->tran_speed,
MMC_CLK_ENABLE);
}
@@ -2561,7 +2559,7 @@ static int mmc_startup(struct mmc *mmc)
#if CONFIG_IS_ENABLED(MMC_TINY)
mmc_set_clock(mmc, mmc->legacy_speed, false);
- mmc_select_mode(mmc, IS_SD(mmc) ? SD_LEGACY : MMC_LEGACY);
+ mmc_select_mode(mmc, MMC_LEGACY);
mmc_set_bus_width(mmc, 1);
#else
if (IS_SD(mmc)) {
@@ -2843,9 +2841,11 @@ int mmc_start_init(struct mmc *mmc)
* all hosts are capable of 1 bit bus-width and able to use the legacy
* timings.
*/
- mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(SD_LEGACY) |
+ mmc->host_caps = mmc->cfg->host_caps | MMC_CAP(MMC_LEGACY) |
MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
-
+#if CONFIG_IS_ENABLED(DM_MMC)
+ mmc_deferred_probe(mmc);
+#endif
#if !defined(CONFIG_MMC_BROKEN_CD)
no_card = mmc_getcd(mmc) == 0;
#else
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 5334723a9f..4d0dc33936 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -392,7 +392,6 @@ static void omap_hsmmc_set_timing(struct mmc *mmc)
break;
case MMC_LEGACY:
case MMC_HS:
- case SD_LEGACY:
case UHS_SDR12:
val |= AC12_UHSMC_SDR12;
break;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 9b7c5f8f68..520c9f9feb 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -658,6 +658,20 @@ int sdhci_probe(struct udevice *dev)
return sdhci_init(mmc);
}
+static int sdhci_deferred_probe(struct udevice *dev)
+{
+ int err;
+ struct mmc *mmc = mmc_get_mmc_dev(dev);
+ struct sdhci_host *host = mmc->priv;
+
+ if (host->ops && host->ops->deferred_probe) {
+ err = host->ops->deferred_probe(host);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
static int sdhci_get_cd(struct udevice *dev)
{
struct mmc *mmc = mmc_get_mmc_dev(dev);
@@ -692,6 +706,7 @@ const struct dm_mmc_ops sdhci_ops = {
.send_cmd = sdhci_send_command,
.set_ios = sdhci_set_ios,
.get_cd = sdhci_get_cd,
+ .deferred_probe = sdhci_deferred_probe,
#ifdef MMC_SUPPORTS_TUNING
.execute_tuning = sdhci_execute_tuning,
#endif
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 24fabeee95..da3ff53da1 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -37,7 +37,6 @@ struct arasan_sdhci_priv {
static const u8 mode2timing[] = {
[MMC_LEGACY] = UHS_SDR12_BUS_SPEED,
- [SD_LEGACY] = UHS_SDR12_BUS_SPEED,
[MMC_HS] = HIGH_SPEED_BUS_SPEED,
[SD_HS] = HIGH_SPEED_BUS_SPEED,
[MMC_HS_52] = HIGH_SPEED_BUS_SPEED,