- DM support for CAxxxx SoCs
- eMMC board for presidio-asic
- Add defer probe for mmc sdhci
- TI SoCs mmc misc update
This commit is contained in:
Tom Rini 2020-03-10 21:13:26 -04:00
commit 36bdcf7f3b
29 changed files with 531 additions and 84 deletions

View File

@ -180,6 +180,7 @@ F: board/cortina/common/
F: drivers/gpio/cortina_gpio.c F: drivers/gpio/cortina_gpio.c
F: drivers/watchdog/cortina_wdt.c F: drivers/watchdog/cortina_wdt.c
F: drivers/serial/serial_cortina.c F: drivers/serial/serial_cortina.c
F: drivers/mmc/ca_dw_mmc.c
ARM/CZ.NIC TURRIS MOX SUPPORT ARM/CZ.NIC TURRIS MOX SUPPORT
M: Marek Behun <marek.behun@nic.cz> M: Marek Behun <marek.behun@nic.cz>
@ -672,6 +673,7 @@ F: board/cortina/common/
F: drivers/gpio/cortina_gpio.c F: drivers/gpio/cortina_gpio.c
F: drivers/watchdog/cortina_wdt.c F: drivers/watchdog/cortina_wdt.c
F: drivers/serial/serial_cortina.c F: drivers/serial/serial_cortina.c
F: drivers/mmc/ca_dw_mmc.c
MIPS MSCC MIPS MSCC
M: Gregory CLEMENT <gregory.clement@bootlin.com> M: Gregory CLEMENT <gregory.clement@bootlin.com>

View File

@ -98,7 +98,17 @@
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
mmc-ddr-1_8v; mmc-ddr-1_8v;
mmc-hs200-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>; ti,trm-icp = <0x8>;
dma-coherent; dma-coherent;
}; };

View File

@ -29,7 +29,16 @@
clock-names = "clk_ahb", "clk_xin"; clock-names = "clk_ahb", "clk_xin";
power-domains = <&k3_pds 48 TI_SCI_PD_EXCLUSIVE>; power-domains = <&k3_pds 48 TI_SCI_PD_EXCLUSIVE>;
max-frequency = <25000000>; 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>; ti,trm-icp = <0x8>;
}; };

View File

@ -232,9 +232,14 @@
assigned-clocks = <&k3_clks 91 1>; assigned-clocks = <&k3_clks 91 1>;
assigned-clock-parents = <&k3_clks 91 2>; assigned-clock-parents = <&k3_clks 91 2>;
bus-width = <8>; bus-width = <8>;
ti,otap-del-sel = <0x2>;
ti,trm-icp = <0x8>; ti,trm-icp = <0x8>;
dma-coherent; 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 { main_sdhci1: sdhci@4fb0000 {
@ -246,7 +251,13 @@
clocks = <&k3_clks 92 0>, <&k3_clks 92 5>; clocks = <&k3_clks 92 0>, <&k3_clks 92 5>;
assigned-clocks = <&k3_clks 92 0>; assigned-clocks = <&k3_clks 92 0>;
assigned-clock-parents = <&k3_clks 92 1>; 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>; ti,trm-icp = <0x8>;
dma-coherent; dma-coherent;
}; };

View File

@ -34,14 +34,14 @@
u-boot,dm-spl; u-boot,dm-spl;
}; };
clk_200mhz: dummy_clock { clk_200mhz: dummy_clock_200mhz {
compatible = "fixed-clock"; compatible = "fixed-clock";
#clock-cells = <0>; #clock-cells = <0>;
clock-frequency = <200000000>; clock-frequency = <200000000>;
u-boot,dm-spl; u-boot,dm-spl;
}; };
clk_19_2mhz: dummy_clock { clk_19_2mhz: dummy_clock_19_2mhz {
compatible = "fixed-clock"; compatible = "fixed-clock";
#clock-cells = <0>; #clock-cells = <0>;
clock-frequency = <19200000>; clock-frequency = <19200000>;

View File

@ -197,7 +197,8 @@ unsigned long spl_spi_get_uboot_offs(struct spi_flash *flash)
#endif #endif
#ifdef CONFIG_SPL_MMC_SUPPORT #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; int end;

View File

@ -17,6 +17,7 @@
#include <dm/uclass-internal.h> #include <dm/uclass-internal.h>
#include <dm/pinctrl.h> #include <dm/pinctrl.h>
#include <linux/soc/ti/ti_sci_protocol.h> #include <linux/soc/ti/ti_sci_protocol.h>
#include <mmc.h>
#ifdef CONFIG_SPL_BUILD #ifdef CONFIG_SPL_BUILD
#ifdef CONFIG_K3_LOAD_SYSFW #ifdef CONFIG_K3_LOAD_SYSFW
@ -86,6 +87,33 @@ static void store_boot_index_from_rom(void)
bootindex = *(u32 *)(CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX); 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) void board_init_f(ulong dummy)
{ {
#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS) #if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS)
@ -138,7 +166,10 @@ void board_init_f(ulong dummy)
* callback hook, effectively switching on (or over) the console * callback hook, effectively switching on (or over) the console
* output. * 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 */ /* Disable ROM configured firewalls right after loading sysfw */
#ifdef CONFIG_TI_SECURE_DEVICE #ifdef CONFIG_TI_SECURE_DEVICE

View File

@ -7,6 +7,6 @@
#ifndef _SYSFW_LOADER_H_ #ifndef _SYSFW_LOADER_H_
#define _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 #endif

View File

@ -18,6 +18,7 @@
#include <dm.h> #include <dm.h>
#include <dm/uclass-internal.h> #include <dm/uclass-internal.h>
#include <dm/pinctrl.h> #include <dm/pinctrl.h>
#include <mmc.h>
#ifdef CONFIG_SPL_BUILD #ifdef CONFIG_SPL_BUILD
#ifdef CONFIG_K3_LOAD_SYSFW #ifdef CONFIG_K3_LOAD_SYSFW
@ -100,6 +101,33 @@ static void ctrl_mmr_unlock(void)
mmr_unlock(CTRL_MMR0_BASE, 7); 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, * 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 * but the .bss is cleared between writing and reading this variable, so move
@ -154,7 +182,10 @@ void board_init_f(ulong dummy)
* callback hook, effectively switching on (or over) the console * callback hook, effectively switching on (or over) the console
* output. * 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 */ /* Disable ROM configured firewalls right after loading sysfw */
#ifdef CONFIG_TI_SECURE_DEVICE #ifdef CONFIG_TI_SECURE_DEVICE

View File

@ -197,7 +197,8 @@ exit:
} }
#endif #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_image_info spl_image = { 0 };
struct spl_boot_device bootdev = { 0 }; struct spl_boot_device bootdev = { 0 };
@ -291,6 +292,9 @@ void k3_sysfw_loader(void (*config_pm_done_callback)(void))
/* Get handle for accessing SYSFW services */ /* Get handle for accessing SYSFW services */
ti_sci = get_ti_sci_handle(); ti_sci = get_ti_sci_handle();
if (config_pm_pre_callback)
config_pm_pre_callback();
/* Parse and apply the different SYSFW configuration fragments */ /* Parse and apply the different SYSFW configuration fragments */
k3_sysfw_configure_using_fit(sysfw_load_address, ti_sci); k3_sysfw_configure_using_fit(sysfw_load_address, ti_sci);

View File

@ -317,13 +317,10 @@ int spl_boot_partition(const u32 boot_device)
} }
#endif #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 raw_sect;
return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR;
#else
return 0;
#endif
} }
int spl_mmc_load(struct spl_image_info *spl_image, int spl_mmc_load(struct spl_image_info *spl_image,
@ -392,7 +389,7 @@ int spl_mmc_load(struct spl_image_info *spl_image,
return err; 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 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
err = mmc_load_image_raw_partition(spl_image, mmc, raw_part, err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,

View File

@ -74,6 +74,7 @@ CONFIG_DM_KEYBOARD=y
CONFIG_DM_MAILBOX=y CONFIG_DM_MAILBOX=y
CONFIG_K3_SEC_PROXY=y CONFIG_K3_SEC_PROXY=y
CONFIG_DM_MMC=y CONFIG_DM_MMC=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ADMA=y CONFIG_MMC_SDHCI_ADMA=y
CONFIG_SPL_MMC_SDHCI_ADMA=y CONFIG_SPL_MMC_SDHCI_ADMA=y

View File

@ -73,6 +73,7 @@ CONFIG_K3_SEC_PROXY=y
CONFIG_MISC=y CONFIG_MISC=y
CONFIG_K3_AVS0=y CONFIG_K3_AVS0=y
CONFIG_DM_MMC=y CONFIG_DM_MMC=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y
CONFIG_SPL_MMC_SDHCI_ADMA=y CONFIG_SPL_MMC_SDHCI_ADMA=y
CONFIG_MMC_SDHCI_AM654=y CONFIG_MMC_SDHCI_AM654=y

View File

@ -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

View File

@ -29,6 +29,8 @@ CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=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_ENV_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_DM_MAILBOX=y CONFIG_SPL_DM_MAILBOX=y
@ -99,6 +101,7 @@ CONFIG_SYS_I2C_OMAP24XX=y
CONFIG_DM_MAILBOX=y CONFIG_DM_MAILBOX=y
CONFIG_K3_SEC_PROXY=y CONFIG_K3_SEC_PROXY=y
CONFIG_DM_MMC=y CONFIG_DM_MMC=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ADMA=y CONFIG_MMC_SDHCI_ADMA=y
CONFIG_SPL_MMC_SDHCI_ADMA=y CONFIG_SPL_MMC_SDHCI_ADMA=y

View File

@ -27,6 +27,8 @@ CONFIG_USE_BOOTCOMMAND=y
CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R=y
CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_EARLY_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_ENV_SUPPORT=y
CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_DM_MAILBOX=y CONFIG_SPL_DM_MAILBOX=y
@ -77,6 +79,7 @@ CONFIG_MISC=y
CONFIG_FS_LOADER=y CONFIG_FS_LOADER=y
CONFIG_K3_AVS0=y CONFIG_K3_AVS0=y
CONFIG_DM_MMC=y CONFIG_DM_MMC=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI=y
CONFIG_SPL_MMC_SDHCI_ADMA=y CONFIG_SPL_MMC_SDHCI_ADMA=y
CONFIG_MMC_SDHCI_AM654=y CONFIG_MMC_SDHCI_AM654=y

View File

@ -205,6 +205,17 @@ config MMC_DW
block, this provides host support for SD and MMC interfaces, in both block, this provides host support for SD and MMC interfaces, in both
PIO, internal DMA mode and external DMA mode. 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 config MMC_DW_EXYNOS
bool "Exynos specific extensions for Synopsys DW Memory Card Interface" bool "Exynos specific extensions for Synopsys DW Memory Card Interface"
depends on ARCH_EXYNOS depends on ARCH_EXYNOS

View File

@ -20,6 +20,7 @@ endif
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o
obj-$(CONFIG_MMC_DW) += dw_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_EXYNOS) += exynos_dw_mmc.o
obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o
obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o

View File

@ -74,7 +74,7 @@ struct am654_sdhci_plat {
struct mmc mmc; struct mmc mmc;
struct regmap *base; struct regmap *base;
bool non_removable; bool non_removable;
u32 otap_del_sel; u32 otap_del_sel[11];
u32 trm_icp; u32 trm_icp;
u32 drv_strength; u32 drv_strength;
u32 strb_sel; u32 strb_sel;
@ -86,6 +86,25 @@ struct am654_sdhci_plat {
bool dll_on; 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 { struct am654_driver_data {
const struct sdhci_ops *ops; const struct sdhci_ops *ops;
u32 flags; 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); struct am654_sdhci_plat *plat = dev_get_platdata(dev);
unsigned int speed = host->mmc->clock; unsigned int speed = host->mmc->clock;
int sel50, sel100, freqsel; int sel50, sel100, freqsel;
u32 otap_del_sel;
u32 mask, val; u32 mask, val;
int ret; int ret;
@ -132,9 +152,10 @@ static int am654_sdhci_set_ios_post(struct sdhci_host *host)
/* switch phy back on */ /* switch phy back on */
if (speed > AM654_SDHCI_MIN_FREQ) { if (speed > AM654_SDHCI_MIN_FREQ) {
otap_del_sel = plat->otap_del_sel[host->mmc->selected_mode];
mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK; mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
val = (1 << OTAPDLYENA_SHIFT) | val = (1 << OTAPDLYENA_SHIFT) |
(plat->otap_del_sel << OTAPDLYSEL_SHIFT); (otap_del_sel << OTAPDLYSEL_SHIFT);
/* Write to STRBSEL for HS400 speed mode */ /* Write to STRBSEL for HS400 speed mode */
if (host->mmc->selected_mode == MMC_HS_400) { 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; 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) int am654_sdhci_init(struct am654_sdhci_plat *plat)
{ {
u32 ctl_cfg_2 = 0; u32 ctl_cfg_2 = 0;
@ -281,6 +264,104 @@ int am654_sdhci_init(struct am654_sdhci_plat *plat)
return 0; 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) static int am654_sdhci_probe(struct udevice *dev)
{ {
struct am654_driver_data *drv_data = struct am654_driver_data *drv_data =
@ -313,15 +394,17 @@ static int am654_sdhci_probe(struct udevice *dev)
if (ret) if (ret)
return ret; return ret;
ret = sdhci_am654_get_otap_delay(dev, cfg);
if (ret)
return ret;
host->ops = drv_data->ops; host->ops = drv_data->ops;
host->mmc->priv = host; host->mmc->priv = host;
upriv->mmc = host->mmc; upriv->mmc = host->mmc;
regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1); regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
am654_sdhci_init(plat); return 0;
return sdhci_probe(dev);
} }
static int am654_sdhci_ofdata_to_platdata(struct udevice *dev) 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); host->ioaddr = (void *)dev_read_addr(dev);
plat->non_removable = dev_read_bool(dev, "non-removable"); 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) { if (plat->flags & DLL_PRESENT) {
ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp); ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
if (ret) if (ret)

181
drivers/mmc/ca_dw_mmc.c Normal file
View File

@ -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),
};

View File

@ -743,7 +743,6 @@ static int esdhc_set_timing(struct mmc *mmc)
switch (mmc->selected_mode) { switch (mmc->selected_mode) {
case MMC_LEGACY: case MMC_LEGACY:
case SD_LEGACY:
esdhc_reset_tuning(mmc); esdhc_reset_tuning(mmc);
writel(mixctrl, &regs->mixctrl); writel(mixctrl, &regs->mixctrl);
break; break;

View File

@ -138,6 +138,21 @@ int mmc_host_power_cycle(struct mmc *mmc)
return dm_mmc_host_power_cycle(mmc->dev); 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 mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
{ {
int val; int val;

View File

@ -132,7 +132,6 @@ const char *mmc_mode_name(enum bus_mode mode)
{ {
static const char *const names[] = { static const char *const names[] = {
[MMC_LEGACY] = "MMC legacy", [MMC_LEGACY] = "MMC legacy",
[SD_LEGACY] = "SD Legacy",
[MMC_HS] = "MMC High Speed (26MHz)", [MMC_HS] = "MMC High Speed (26MHz)",
[SD_HS] = "SD High Speed (50MHz)", [SD_HS] = "SD High Speed (50MHz)",
[UHS_SDR12] = "UHS SDR12 (25MHz)", [UHS_SDR12] = "UHS SDR12 (25MHz)",
@ -158,7 +157,6 @@ static uint mmc_mode2freq(struct mmc *mmc, enum bus_mode mode)
{ {
static const int freqs[] = { static const int freqs[] = {
[MMC_LEGACY] = 25000000, [MMC_LEGACY] = 25000000,
[SD_LEGACY] = 25000000,
[MMC_HS] = 26000000, [MMC_HS] = 26000000,
[SD_HS] = 50000000, [SD_HS] = 50000000,
[MMC_HS_52] = 52000000, [MMC_HS_52] = 52000000,
@ -1239,7 +1237,7 @@ static int sd_get_capabilities(struct mmc *mmc)
u32 sd3_bus_mode; u32 sd3_bus_mode;
#endif #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)) if (mmc_host_is_spi(mmc))
return 0; return 0;
@ -1352,7 +1350,7 @@ static int sd_set_card_speed(struct mmc *mmc, enum bus_mode mode)
return 0; return 0;
switch (mode) { switch (mode) {
case SD_LEGACY: case MMC_LEGACY:
speed = UHS_SDR12_BUS_SPEED; speed = UHS_SDR12_BUS_SPEED;
break; break;
case SD_HS: case SD_HS:
@ -1695,7 +1693,7 @@ static const struct mode_width_tuning sd_modes_by_pref[] = {
}, },
#endif #endif
{ {
.mode = SD_LEGACY, .mode = MMC_LEGACY,
.widths = MMC_MODE_4BIT | MMC_MODE_1BIT, .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)) { if (mmc_host_is_spi(mmc)) {
mmc_set_bus_width(mmc, 1); 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); mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE);
return 0; return 0;
} }
@ -1784,7 +1782,7 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
error: error:
/* revert to a safer bus speed */ /* 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_set_clock(mmc, mmc->tran_speed,
MMC_CLK_ENABLE); MMC_CLK_ENABLE);
} }
@ -2561,7 +2559,7 @@ static int mmc_startup(struct mmc *mmc)
#if CONFIG_IS_ENABLED(MMC_TINY) #if CONFIG_IS_ENABLED(MMC_TINY)
mmc_set_clock(mmc, mmc->legacy_speed, false); 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); mmc_set_bus_width(mmc, 1);
#else #else
if (IS_SD(mmc)) { 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 * all hosts are capable of 1 bit bus-width and able to use the legacy
* timings. * 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; MMC_CAP(MMC_LEGACY) | MMC_MODE_1BIT;
#if CONFIG_IS_ENABLED(DM_MMC)
mmc_deferred_probe(mmc);
#endif
#if !defined(CONFIG_MMC_BROKEN_CD) #if !defined(CONFIG_MMC_BROKEN_CD)
no_card = mmc_getcd(mmc) == 0; no_card = mmc_getcd(mmc) == 0;
#else #else

View File

@ -392,7 +392,6 @@ static void omap_hsmmc_set_timing(struct mmc *mmc)
break; break;
case MMC_LEGACY: case MMC_LEGACY:
case MMC_HS: case MMC_HS:
case SD_LEGACY:
case UHS_SDR12: case UHS_SDR12:
val |= AC12_UHSMC_SDR12; val |= AC12_UHSMC_SDR12;
break; break;

View File

@ -658,6 +658,20 @@ int sdhci_probe(struct udevice *dev)
return sdhci_init(mmc); 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) static int sdhci_get_cd(struct udevice *dev)
{ {
struct mmc *mmc = mmc_get_mmc_dev(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, .send_cmd = sdhci_send_command,
.set_ios = sdhci_set_ios, .set_ios = sdhci_set_ios,
.get_cd = sdhci_get_cd, .get_cd = sdhci_get_cd,
.deferred_probe = sdhci_deferred_probe,
#ifdef MMC_SUPPORTS_TUNING #ifdef MMC_SUPPORTS_TUNING
.execute_tuning = sdhci_execute_tuning, .execute_tuning = sdhci_execute_tuning,
#endif #endif

View File

@ -37,7 +37,6 @@ struct arasan_sdhci_priv {
static const u8 mode2timing[] = { static const u8 mode2timing[] = {
[MMC_LEGACY] = UHS_SDR12_BUS_SPEED, [MMC_LEGACY] = UHS_SDR12_BUS_SPEED,
[SD_LEGACY] = UHS_SDR12_BUS_SPEED,
[MMC_HS] = HIGH_SPEED_BUS_SPEED, [MMC_HS] = HIGH_SPEED_BUS_SPEED,
[SD_HS] = HIGH_SPEED_BUS_SPEED, [SD_HS] = HIGH_SPEED_BUS_SPEED,
[MMC_HS_52] = HIGH_SPEED_BUS_SPEED, [MMC_HS_52] = HIGH_SPEED_BUS_SPEED,

View File

@ -127,8 +127,6 @@
#define CONFIG_SYS_MMC_ENV_PART 1 #define CONFIG_SYS_MMC_ENV_PART 1
#endif #endif
#define CONFIG_SUPPORT_EMMC_BOOT
/* Now for the remaining common defines */ /* Now for the remaining common defines */
#include <configs/ti_armv7_common.h> #include <configs/ti_armv7_common.h>

View File

@ -15,6 +15,8 @@
#include <linux/dma-direction.h> #include <linux/dma-direction.h>
#include <part.h> #include <part.h>
struct bd_info;
#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
#define MMC_SUPPORTS_TUNING #define MMC_SUPPORTS_TUNING
#endif #endif
@ -407,6 +409,14 @@ struct mmc;
#if CONFIG_IS_ENABLED(DM_MMC) #if CONFIG_IS_ENABLED(DM_MMC)
struct dm_mmc_ops { 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 * send_cmd() - Send a command to the MMC device
* *
@ -490,6 +500,7 @@ int dm_mmc_get_wp(struct udevice *dev);
int dm_mmc_execute_tuning(struct udevice *dev, uint opcode); 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_wait_dat0(struct udevice *dev, int state, int timeout_us);
int dm_mmc_host_power_cycle(struct udevice *dev); int dm_mmc_host_power_cycle(struct udevice *dev);
int dm_mmc_deferred_probe(struct udevice *dev);
/* Transition functions for compatibility */ /* Transition functions for compatibility */
int mmc_set_ios(struct mmc *mmc); int mmc_set_ios(struct mmc *mmc);
@ -499,6 +510,7 @@ int mmc_execute_tuning(struct mmc *mmc, uint opcode);
int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us); int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us);
int mmc_set_enhanced_strobe(struct mmc *mmc); int mmc_set_enhanced_strobe(struct mmc *mmc);
int mmc_host_power_cycle(struct mmc *mmc); int mmc_host_power_cycle(struct mmc *mmc);
int mmc_deferred_probe(struct mmc *mmc);
#else #else
struct mmc_ops { struct mmc_ops {
@ -533,7 +545,6 @@ struct sd_ssr {
enum bus_mode { enum bus_mode {
MMC_LEGACY, MMC_LEGACY,
SD_LEGACY,
MMC_HS, MMC_HS,
SD_HS, SD_HS,
MMC_HS_52, MMC_HS_52,
@ -603,6 +614,7 @@ struct mmc {
bool clk_disable; /* true if the clock can be turned off */ bool clk_disable; /* true if the clock can be turned off */
uint bus_width; uint bus_width;
uint clock; uint clock;
uint saved_clock;
enum mmc_voltage signal_voltage; enum mmc_voltage signal_voltage;
uint card_caps; uint card_caps;
uint host_caps; uint host_caps;
@ -712,7 +724,7 @@ void mmc_destroy(struct mmc *mmc);
* @return 0 if OK, -ve on error * @return 0 if OK, -ve on error
*/ */
int mmc_unbind(struct udevice *dev); 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_device(int num);
int mmc_init(struct mmc *mmc); int mmc_init(struct mmc *mmc);
int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error); int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
@ -857,8 +869,8 @@ void mmc_set_preinit(struct mmc *mmc, int preinit);
#endif #endif
void board_mmc_power_init(void); void board_mmc_power_init(void);
int board_mmc_init(bd_t *bis); int board_mmc_init(struct bd_info *bis);
int cpu_mmc_init(bd_t *bis); int cpu_mmc_init(struct bd_info *bis);
int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr); int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr);
# ifdef CONFIG_SYS_MMC_ENV_PART # ifdef CONFIG_SYS_MMC_ENV_PART
extern uint mmc_get_env_part(struct mmc *mmc); extern uint mmc_get_env_part(struct mmc *mmc);

View File

@ -268,6 +268,7 @@ struct sdhci_ops {
void (*set_clock)(struct sdhci_host *host, u32 div); void (*set_clock)(struct sdhci_host *host, u32 div);
int (*platform_execute_tuning)(struct mmc *host, u8 opcode); int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
void (*set_delay)(struct sdhci_host *host); void (*set_delay)(struct sdhci_host *host);
int (*deferred_probe)(struct sdhci_host *host);
}; };
#if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA) #if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA)