Merge tag 'efi-2020-04-rc4-3' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi

Pull request for UEFI sub-system for efi-2020-04-rc4 (3)

This pull request provides the hardware RNG driver for Amlogic systems needed
for the EFI_RNG_PROTOCOL.

Furthermore bug fixes are provided:

* correct an error message in the efidebug command
* correct an error in the 'efidebug rm' command
* remove an unnecessary assignment in efi_queue_event()
diff --git a/MAINTAINERS b/MAINTAINERS
index 37ff21a..2c43573 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -180,6 +180,7 @@
 F:	drivers/gpio/cortina_gpio.c
 F:	drivers/watchdog/cortina_wdt.c
 F:	drivers/serial/serial_cortina.c
+F:	drivers/mmc/ca_dw_mmc.c
 
 ARM/CZ.NIC TURRIS MOX SUPPORT
 M:	Marek Behun <marek.behun@nic.cz>
@@ -672,6 +673,7 @@
 F:	drivers/gpio/cortina_gpio.c
 F:	drivers/watchdog/cortina_wdt.c
 F:	drivers/serial/serial_cortina.c
+F:	drivers/mmc/ca_dw_mmc.c
 
 MIPS MSCC
 M:	Gregory CLEMENT <gregory.clement@bootlin.com>
diff --git a/arch/arm/dts/k3-am65-main.dtsi b/arch/arm/dts/k3-am65-main.dtsi
index ab40daf..028f573 100644
--- a/arch/arm/dts/k3-am65-main.dtsi
+++ b/arch/arm/dts/k3-am65-main.dtsi
@@ -98,7 +98,17 @@
 		interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
 		mmc-ddr-1_8v;
 		mmc-hs200-1_8v;
-		ti,otap-del-sel = <0x2>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-mmc-hs = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0x0>;
+		ti,otap-del-sel-sdr25 = <0x0>;
+		ti,otap-del-sel-sdr50 = <0x8>;
+		ti,otap-del-sel-sdr104 = <0x5>;
+		ti,otap-del-sel-ddr50 = <0x5>;
+		ti,otap-del-sel-ddr52 = <0x5>;
+		ti,otap-del-sel-hs200 = <0x5>;
+		ti,otap-del-sel-hs400 = <0x0>;
 		ti,trm-icp = <0x8>;
 		dma-coherent;
 	};
diff --git a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
index a349edc..54ecb3d 100644
--- a/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
+++ b/arch/arm/dts/k3-am654-base-board-u-boot.dtsi
@@ -29,7 +29,16 @@
 		clock-names = "clk_ahb", "clk_xin";
 		power-domains = <&k3_pds 48 TI_SCI_PD_EXCLUSIVE>;
 		max-frequency = <25000000>;
-		ti,otap-del-sel = <0x2>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-mmc-hs = <0x0>;
+		ti,otap-del-sel-sd-hs = <0x0>;
+		ti,otap-del-sel-sdr12 = <0x0>;
+		ti,otap-del-sel-sdr25 = <0x0>;
+		ti,otap-del-sel-sdr50 = <0x8>;
+		ti,otap-del-sel-sdr104 = <0x7>;
+		ti,otap-del-sel-ddr50 = <0x4>;
+		ti,otap-del-sel-ddr52 = <0x4>;
+		ti,otap-del-sel-hs200 = <0x7>;
 		ti,trm-icp = <0x8>;
 	};
 
diff --git a/arch/arm/dts/k3-j721e-main.dtsi b/arch/arm/dts/k3-j721e-main.dtsi
index 45ac98c..1433932 100644
--- a/arch/arm/dts/k3-j721e-main.dtsi
+++ b/arch/arm/dts/k3-j721e-main.dtsi
@@ -232,9 +232,14 @@
 		assigned-clocks = <&k3_clks 91 1>;
 		assigned-clock-parents = <&k3_clks 91 2>;
 		bus-width = <8>;
-		ti,otap-del-sel = <0x2>;
 		ti,trm-icp = <0x8>;
 		dma-coherent;
+		mmc-ddr-1_8v;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-mmc-hs = <0x0>;
+		ti,otap-del-sel-ddr52 = <0x5>;
+		ti,otap-del-sel-hs200 = <0x6>;
+		ti,otap-del-sel-hs400 = <0x0>;
 	};
 
 	main_sdhci1: sdhci@4fb0000 {
@@ -246,7 +251,13 @@
 		clocks = <&k3_clks 92 0>, <&k3_clks 92 5>;
 		assigned-clocks = <&k3_clks 92 0>;
 		assigned-clock-parents = <&k3_clks 92 1>;
-		ti,otap-del-sel = <0x2>;
+		ti,otap-del-sel-legacy = <0x0>;
+		ti,otap-del-sel-sd-hs = <0xf>;
+		ti,otap-del-sel-sdr12 = <0xf>;
+		ti,otap-del-sel-sdr25 = <0xf>;
+		ti,otap-del-sel-sdr50 = <0xc>;
+		ti,otap-del-sel-sdr104 = <0x5>;
+		ti,otap-del-sel-ddr50 = <0xc>;
 		ti,trm-icp = <0x8>;
 		dma-coherent;
 	};
diff --git a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
index eb577cd..5973e21 100644
--- a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
+++ b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
@@ -34,14 +34,14 @@
 		u-boot,dm-spl;
 	};
 
-	clk_200mhz: dummy_clock {
+	clk_200mhz: dummy_clock_200mhz {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <200000000>;
 		u-boot,dm-spl;
 	};
 
-	clk_19_2mhz: dummy_clock {
+	clk_19_2mhz: dummy_clock_19_2mhz {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <19200000>;
diff --git a/arch/arm/mach-imx/imx8/image.c b/arch/arm/mach-imx/imx8/image.c
index c956a80..e6b2996 100644
--- a/arch/arm/mach-imx/imx8/image.c
+++ b/arch/arm/mach-imx/imx8/image.c
@@ -197,7 +197,8 @@
 #endif
 
 #ifdef CONFIG_SPL_MMC_SUPPORT
-unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc)
+unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
+					   unsigned long raw_sect)
 {
 	int end;
 
diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
index 63cd7e0..d0b10e5 100644
--- a/arch/arm/mach-k3/am6_init.c
+++ b/arch/arm/mach-k3/am6_init.c
@@ -17,6 +17,7 @@
 #include <dm/uclass-internal.h>
 #include <dm/pinctrl.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <mmc.h>
 
 #ifdef CONFIG_SPL_BUILD
 #ifdef CONFIG_K3_LOAD_SYSFW
@@ -86,6 +87,33 @@
 	bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX);
 }
 
+#if defined(CONFIG_K3_LOAD_SYSFW)
+void k3_mmc_stop_clock(void)
+{
+	if (spl_boot_device() == BOOT_DEVICE_MMC1) {
+		struct mmc *mmc = find_mmc_device(0);
+
+		if (!mmc)
+			return;
+
+		mmc->saved_clock = mmc->clock;
+		mmc_set_clock(mmc, 0, true);
+	}
+}
+
+void k3_mmc_restart_clock(void)
+{
+	if (spl_boot_device() == BOOT_DEVICE_MMC1) {
+		struct mmc *mmc = find_mmc_device(0);
+
+		if (!mmc)
+			return;
+
+		mmc_set_clock(mmc, mmc->saved_clock, false);
+	}
+}
+#endif
+
 void board_init_f(ulong dummy)
 {
 #if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS)
@@ -138,7 +166,10 @@
 	 * callback hook, effectively switching on (or over) the console
 	 * output.
 	 */
-	k3_sysfw_loader(preloader_console_init);
+	k3_sysfw_loader(k3_mmc_stop_clock, k3_mmc_restart_clock);
+
+	/* Prepare console output */
+	preloader_console_init();
 
 	/* Disable ROM configured firewalls right after loading sysfw */
 #ifdef CONFIG_TI_SECURE_DEVICE
diff --git a/arch/arm/mach-k3/include/mach/sysfw-loader.h b/arch/arm/mach-k3/include/mach/sysfw-loader.h
index 36eb265..6f5612b 100644
--- a/arch/arm/mach-k3/include/mach/sysfw-loader.h
+++ b/arch/arm/mach-k3/include/mach/sysfw-loader.h
@@ -7,6 +7,6 @@
 #ifndef _SYSFW_LOADER_H_
 #define _SYSFW_LOADER_H_
 
-void k3_sysfw_loader(void (*config_pm_done_callback)(void));
+void k3_sysfw_loader(void (*config_pm_pre_callback)(void), void (*config_pm_done_callback)(void));
 
 #endif
diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c
index f7f7398..0994522 100644
--- a/arch/arm/mach-k3/j721e_init.c
+++ b/arch/arm/mach-k3/j721e_init.c
@@ -18,6 +18,7 @@
 #include <dm.h>
 #include <dm/uclass-internal.h>
 #include <dm/pinctrl.h>
+#include <mmc.h>
 
 #ifdef CONFIG_SPL_BUILD
 #ifdef CONFIG_K3_LOAD_SYSFW
@@ -100,6 +101,33 @@
 	mmr_unlock(CTRL_MMR0_BASE, 7);
 }
 
+#if defined(CONFIG_K3_LOAD_SYSFW)
+void k3_mmc_stop_clock(void)
+{
+	if (spl_boot_device() == BOOT_DEVICE_MMC1) {
+		struct mmc *mmc = find_mmc_device(0);
+
+		if (!mmc)
+			return;
+
+		mmc->saved_clock = mmc->clock;
+		mmc_set_clock(mmc, 0, true);
+	}
+}
+
+void k3_mmc_restart_clock(void)
+{
+	if (spl_boot_device() == BOOT_DEVICE_MMC1) {
+		struct mmc *mmc = find_mmc_device(0);
+
+		if (!mmc)
+			return;
+
+		mmc_set_clock(mmc, mmc->saved_clock, false);
+	}
+}
+#endif
+
 /*
  * This uninitialized global variable would normal end up in the .bss section,
  * but the .bss is cleared between writing and reading this variable, so move
@@ -154,7 +182,10 @@
 	 * callback hook, effectively switching on (or over) the console
 	 * output.
 	 */
-	k3_sysfw_loader(preloader_console_init);
+	k3_sysfw_loader(k3_mmc_stop_clock, k3_mmc_restart_clock);
+
+	/* Prepare console output */
+	preloader_console_init();
 
 	/* Disable ROM configured firewalls right after loading sysfw */
 #ifdef CONFIG_TI_SECURE_DEVICE
diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c
index 94dbeb9..db02607 100644
--- a/arch/arm/mach-k3/sysfw-loader.c
+++ b/arch/arm/mach-k3/sysfw-loader.c
@@ -197,7 +197,8 @@
 }
 #endif
 
-void k3_sysfw_loader(void (*config_pm_done_callback)(void))
+void k3_sysfw_loader(void (*config_pm_pre_callback) (void),
+		     void (*config_pm_done_callback)(void))
 {
 	struct spl_image_info spl_image = { 0 };
 	struct spl_boot_device bootdev = { 0 };
@@ -291,6 +292,9 @@
 	/* Get handle for accessing SYSFW services */
 	ti_sci = get_ti_sci_handle();
 
+	if (config_pm_pre_callback)
+		config_pm_pre_callback();
+
 	/* Parse and apply the different SYSFW configuration fragments */
 	k3_sysfw_configure_using_fit(sysfw_load_address, ti_sci);
 
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index e4d621d..9615369 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -119,7 +119,7 @@
 
 config STM32_ETZPC
 	bool "STM32 Extended TrustZone Protection"
-	depends on TARGET_STM32MP1
+	depends on STM32MP15x
 	default y
 	help
 	  Say y to enable STM32 Extended TrustZone Protection
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 3e6a17c..a2ea363 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -317,13 +317,10 @@
 }
 #endif
 
-unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc)
+unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
+						  unsigned long raw_sect)
 {
-#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
-	return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;
-#else
-	return 0;
-#endif
+	return raw_sect;
 }
 
 int spl_mmc_load(struct spl_image_info *spl_image,
@@ -392,7 +389,7 @@
 				return err;
 		}
 
-		raw_sect = spl_mmc_get_uboot_raw_sector(mmc);
+		raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
 
 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
 		err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
index 121d8de..df7723b 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -74,6 +74,7 @@
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_DM_MMC=y
+CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig
index 69055d5..b475ace 100644
--- a/configs/am65x_evm_r5_defconfig
+++ b/configs/am65x_evm_r5_defconfig
@@ -73,6 +73,7 @@
 CONFIG_MISC=y
 CONFIG_K3_AVS0=y
 CONFIG_DM_MMC=y
+CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
diff --git a/configs/cortina_presidio-asic-emmc_defconfig b/configs/cortina_presidio-asic-emmc_defconfig
new file mode 100644
index 0000000..e10008a
--- /dev/null
+++ b/configs/cortina_presidio-asic-emmc_defconfig
@@ -0,0 +1,33 @@
+CONFIG_ARM=y
+# CONFIG_SYS_ARCH_TIMER is not set
+CONFIG_TARGET_PRESIDIO_ASIC=y
+CONFIG_SYS_TEXT_BASE=0x04000000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DM_GPIO=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_IDENT_STRING="Presidio-SoC"
+CONFIG_SHOW_BOOT_PROGRESS=y
+CONFIG_BOOTDELAY=3
+CONFIG_BOARD_EARLY_INIT_R=y
+CONFIG_SYS_PROMPT="G3#"
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_WDT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIMER=y
+CONFIG_CMD_SMC=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="ca-presidio-engboard"
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_CORTINA_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_CORTINA=y
+CONFIG_DM_SERIAL=y
+CONFIG_CORTINA_UART=y
+CONFIG_WDT=y
+CONFIG_WDT_CORTINA=y
diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig
index ef44ed0..b27f9ba 100644
--- a/configs/j721e_evm_a72_defconfig
+++ b/configs/j721e_evm_a72_defconfig
@@ -29,6 +29,8 @@
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
@@ -99,6 +101,7 @@
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_DM_MMC=y
+CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ADMA=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig
index 607e748..ea70c34 100644
--- a/configs/j721e_evm_r5_defconfig
+++ b/configs/j721e_evm_r5_defconfig
@@ -27,6 +27,8 @@
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_EARLY_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
 CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
@@ -77,6 +79,7 @@
 CONFIG_FS_LOADER=y
 CONFIG_K3_AVS0=y
 CONFIG_DM_MMC=y
+CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_MMC_SDHCI=y
 CONFIG_SPL_MMC_SDHCI_ADMA=y
 CONFIG_MMC_SDHCI_AM654=y
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 2f0eedc..bb38787 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -205,6 +205,17 @@
 	  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 9c1f8e5..615b724 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -20,6 +20,7 @@
 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 aad9d8b..ca76e1f 100644
--- a/drivers/mmc/am654_sdhci.c
+++ b/drivers/mmc/am654_sdhci.c
@@ -74,7 +74,7 @@
 	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 @@
 	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 @@
 	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 @@
 
 	/* 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 0000000..acbc850
--- /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 4900498..6bca2a9 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -743,7 +743,6 @@
 
 	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 0b90a97..c75892a 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -138,6 +138,21 @@
 	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 b50fcbf..3e36566 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -132,7 +132,6 @@
 {
 	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 const int freqs[] = {
 	      [MMC_LEGACY]	= 25000000,
-	      [SD_LEGACY]	= 25000000,
 	      [MMC_HS]		= 26000000,
 	      [SD_HS]		= 50000000,
 	      [MMC_HS_52]	= 52000000,
@@ -1239,7 +1237,7 @@
 	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 @@
 		return 0;
 
 	switch (mode) {
-	case SD_LEGACY:
+	case MMC_LEGACY:
 		speed = UHS_SDR12_BUS_SPEED;
 		break;
 	case SD_HS:
@@ -1695,7 +1693,7 @@
 	},
 #endif
 	{
-		.mode = SD_LEGACY,
+		.mode = MMC_LEGACY,
 		.widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
 	}
 };
@@ -1725,7 +1723,7 @@
 
 	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 @@
 
 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 @@
 
 #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 @@
 	 * 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 5334723..4d0dc33 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -392,7 +392,6 @@
 		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 9b7c5f8..520c9f9 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -658,6 +658,20 @@
 	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 @@
 	.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 24fabee..da3ff53 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -37,7 +37,6 @@
 
 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,
diff --git a/include/configs/am65x_evm.h b/include/configs/am65x_evm.h
index 7d7f86a..23ee225 100644
--- a/include/configs/am65x_evm.h
+++ b/include/configs/am65x_evm.h
@@ -127,8 +127,6 @@
 #define CONFIG_SYS_MMC_ENV_PART	1
 #endif
 
-#define CONFIG_SUPPORT_EMMC_BOOT
-
 /* Now for the remaining common defines */
 #include <configs/ti_armv7_common.h>
 
diff --git a/include/mmc.h b/include/mmc.h
index 71e2e17..e83c224 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -15,6 +15,8 @@
 #include <linux/dma-direction.h>
 #include <part.h>
 
+struct bd_info;
+
 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
 #define MMC_SUPPORTS_TUNING
 #endif
@@ -408,6 +410,14 @@
 #if CONFIG_IS_ENABLED(DM_MMC)
 struct dm_mmc_ops {
 	/**
+	 * deferred_probe() - Some configurations that need to be deferred
+	 * to just before enumerating the device
+	 *
+	 * @dev:	Device to init
+	 * @return 0 if Ok, -ve if error
+	 */
+	int (*deferred_probe)(struct udevice *dev);
+	/**
 	 * send_cmd() - Send a command to the MMC device
 	 *
 	 * @dev:	Device to receive the command
@@ -490,6 +500,7 @@
 int dm_mmc_execute_tuning(struct udevice *dev, uint opcode);
 int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us);
 int dm_mmc_host_power_cycle(struct udevice *dev);
+int dm_mmc_deferred_probe(struct udevice *dev);
 
 /* Transition functions for compatibility */
 int mmc_set_ios(struct mmc *mmc);
@@ -499,6 +510,7 @@
 int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us);
 int mmc_set_enhanced_strobe(struct mmc *mmc);
 int mmc_host_power_cycle(struct mmc *mmc);
+int mmc_deferred_probe(struct mmc *mmc);
 
 #else
 struct mmc_ops {
@@ -533,7 +545,6 @@
 
 enum bus_mode {
 	MMC_LEGACY,
-	SD_LEGACY,
 	MMC_HS,
 	SD_HS,
 	MMC_HS_52,
@@ -603,6 +614,7 @@
 	bool clk_disable; /* true if the clock can be turned off */
 	uint bus_width;
 	uint clock;
+	uint saved_clock;
 	enum mmc_voltage signal_voltage;
 	uint card_caps;
 	uint host_caps;
@@ -712,7 +724,7 @@
  * @return 0 if OK, -ve on error
  */
 int mmc_unbind(struct udevice *dev);
-int mmc_initialize(bd_t *bis);
+int mmc_initialize(struct bd_info *bis);
 int mmc_init_device(int num);
 int mmc_init(struct mmc *mmc);
 int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
@@ -857,8 +869,8 @@
 #endif
 
 void board_mmc_power_init(void);
-int board_mmc_init(bd_t *bis);
-int cpu_mmc_init(bd_t *bis);
+int board_mmc_init(struct bd_info *bis);
+int cpu_mmc_init(struct bd_info *bis);
 int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
 # ifdef CONFIG_SYS_MMC_ENV_PART
 extern uint mmc_get_env_part(struct mmc *mmc);
diff --git a/include/sdhci.h b/include/sdhci.h
index 7f8feef..aa4378f 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -268,6 +268,7 @@
 	void	(*set_clock)(struct sdhci_host *host, u32 div);
 	int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
 	void (*set_delay)(struct sdhci_host *host);
+	int	(*deferred_probe)(struct sdhci_host *host);
 };
 
 #if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)