aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/Kconfig23
-rw-r--r--drivers/mmc/Makefile2
-rw-r--r--drivers/mmc/am654_sdhci.c2
-rw-r--r--drivers/mmc/arm_pl180_mmci.c66
-rw-r--r--drivers/mmc/cv1800b_sdhci.c2
-rw-r--r--drivers/mmc/dw_mmc.c4
-rw-r--r--drivers/mmc/fsl_esdhc.c2
-rw-r--r--drivers/mmc/fsl_esdhc_imx.c2
-rw-r--r--drivers/mmc/hi6220_dw_mmc.c72
-rw-r--r--drivers/mmc/meson_gx_mmc.c2
-rw-r--r--drivers/mmc/mmc-uclass.c21
-rw-r--r--drivers/mmc/mmc.c38
-rw-r--r--drivers/mmc/mtk-sd.c21
-rw-r--r--drivers/mmc/octeontx_hsmmc.c8
-rw-r--r--drivers/mmc/omap_hsmmc.c6
-rw-r--r--drivers/mmc/renesas-sdhi.c21
-rw-r--r--drivers/mmc/rockchip_dw_mmc.c2
-rw-r--r--drivers/mmc/sdhci-cadence.c2
-rw-r--r--drivers/mmc/tmio-common.c8
19 files changed, 174 insertions, 130 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index f7fe6d1042e..06e32e75696 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -20,11 +20,19 @@ config MMC_WRITE
config MMC_PWRSEQ
bool "HW reset support for eMMC"
- depends on PWRSEQ
+ depends on PWRSEQ && DM_GPIO
help
- Ths select Hardware reset support aka pwrseq-emmc for eMMC
+ This select Hardware reset support aka pwrseq-emmc for eMMC
devices.
+config SPL_MMC_PWRSEQ
+ bool "HW reset support for eMMC in SPL"
+ depends on SPL_PWRSEQ && SPL_DM_GPIO
+ default y if MMC_PWRSEQ
+ help
+ This select Hardware reset support aka pwrseq-emmc for eMMC
+ devices in SPL.
+
config MMC_BROKEN_CD
bool "Poll for broken card detection case"
help
@@ -79,11 +87,12 @@ config MMC_SPI_CRC_ON
config ARM_PL180_MMCI
bool "ARM AMBA Multimedia Card Interface and compatible support"
+ depends on DM_MMC
help
This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card
Interface (PL180, PL181 and compatible) support.
If you have an ARM(R) platform with a Multimedia Card slot,
- say Y or M here.
+ say Y here.
config MMC_QUIRKS
bool "Enable quirks"
@@ -599,7 +608,7 @@ config MMC_SDHCI_IPROC
This selects the iProc SD/MMC controller.
If you have a Broadcom IPROC platform with SD or MMC devices,
- say Y or M here.
+ say Y here.
If unsure, say N.
@@ -610,7 +619,7 @@ config MMC_SDHCI_F_SDH30
help
This selects the Secure Digital Host Controller Interface (SDHCI)
Needed by some Fujitsu/Socionext SoC for MMC / SD / SDIO support.
- If you have a controller with this interface, say Y or M here.
+ If you have a controller with this interface, say Y here.
If unsure, say N.
config MMC_SDHCI_KONA
@@ -804,7 +813,7 @@ config STM32_SDMMC2
help
This selects support for the SD/MMC controller on STM32H7 SoCs.
If you have a board based on such a SoC and with a SD/MMC slot,
- say Y or M here.
+ say Y here.
config FTSDC010
bool "Ftsdc010 SD/MMC controller Support"
@@ -824,7 +833,7 @@ config MMC_MTK
depends on OF_CONTROL
help
This selects the MediaTek(R) Secure digital and Multimedia card Interface.
- If you have a machine with a integrated SD/MMC card reader, say Y or M here.
+ If you have a machine with a integrated SD/MMC card reader, say Y here.
This is needed if support for any SD/SDIO/MMC devices is required.
If unsure, say N.
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 3374321e290..72c3fb66ce0 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += mmc_bootdev.o
endif
obj-$(CONFIG_$(SPL_TPL_)MMC_WRITE) += mmc_write.o
-obj-$(CONFIG_MMC_PWRSEQ) += mmc-pwrseq.o
+obj-$(CONFIG_$(SPL_)MMC_PWRSEQ) += mmc-pwrseq.o
obj-$(CONFIG_MMC_SDHCI_ADMA_HELPERS) += sdhci-adma.o
ifndef CONFIG_$(SPL_)BLK
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
index 05595bdac39..2139fea04d5 100644
--- a/drivers/mmc/am654_sdhci.c
+++ b/drivers/mmc/am654_sdhci.c
@@ -390,7 +390,7 @@ static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
for (itap = 0; itap < ITAP_MAX; itap++) {
am654_sdhci_write_itapdly(plat, itap);
- cur_val = !mmc_send_tuning(mmc, opcode, NULL);
+ cur_val = !mmc_send_tuning(mmc, opcode);
if (cur_val && !prev_val)
pass_window = itap;
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index 5cf5502ed54..2666b65362b 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -18,6 +18,7 @@
#include <malloc.h>
#include <mmc.h>
#include <dm/device_compat.h>
+#include <dm.h>
#include <asm/io.h>
#include <asm-generic/gpio.h>
@@ -25,8 +26,6 @@
#include "arm_pl180_mmci.h"
#include <linux/delay.h>
-#ifdef CONFIG_DM_MMC
-#include <dm.h>
#define MMC_CLOCK_MAX 48000000
#define MMC_CLOCK_MIN 400000
@@ -34,7 +33,6 @@ struct arm_pl180_mmc_plat {
struct mmc_config cfg;
struct mmc mmc;
};
-#endif
static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
{
@@ -358,65 +356,6 @@ static int host_set_ios(struct mmc *dev)
return 0;
}
-#ifndef CONFIG_DM_MMC
-/* MMC uses open drain drivers in the enumeration phase */
-static int mmc_host_reset(struct mmc *dev)
-{
- struct pl180_mmc_host *host = dev->priv;
-
- writel(host->pwr_init, &host->base->power);
-
- return 0;
-}
-
-static const struct mmc_ops arm_pl180_mmci_ops = {
- .send_cmd = host_request,
- .set_ios = host_set_ios,
- .init = mmc_host_reset,
-};
-
-/*
- * mmc_host_init - initialize the mmc controller.
- * Set initial clock and power for mmc slot.
- * Initialize mmc struct and register with mmc framework.
- */
-
-int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
-{
- u32 sdi_u32;
-
- writel(host->pwr_init, &host->base->power);
- writel(host->clkdiv_init, &host->base->clock);
- udelay(CLK_CHANGE_DELAY);
-
- /* Disable mmc interrupts */
- sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
- writel(sdi_u32, &host->base->mask0);
-
- host->cfg.name = host->name;
- host->cfg.ops = &arm_pl180_mmci_ops;
-
- /* TODO remove the duplicates */
- host->cfg.host_caps = host->caps;
- host->cfg.voltages = host->voltages;
- host->cfg.f_min = host->clock_min;
- host->cfg.f_max = host->clock_max;
- if (host->b_max != 0)
- host->cfg.b_max = host->b_max;
- else
- host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
-
- *mmc = mmc_create(&host->cfg, host);
- if (!*mmc)
- return -1;
- debug("registered mmc interface number is:%d\n",
- (*mmc)->block_dev.devnum);
-
- return 0;
-}
-#endif
-
-#ifdef CONFIG_DM_MMC
static void arm_pl180_mmc_init(struct pl180_mmc_host *host)
{
u32 sdi_u32;
@@ -477,7 +416,7 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
host->version2 = true;
break;
default:
- host->version2 = true;
+ host->version2 = false; /* ARM variant */
}
gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN);
@@ -561,4 +500,3 @@ U_BOOT_DRIVER(arm_pl180_mmc) = {
.priv_auto = sizeof(struct pl180_mmc_host),
.plat_auto = sizeof(struct arm_pl180_mmc_plat),
};
-#endif
diff --git a/drivers/mmc/cv1800b_sdhci.c b/drivers/mmc/cv1800b_sdhci.c
index 2275c537772..9af6b971984 100644
--- a/drivers/mmc/cv1800b_sdhci.c
+++ b/drivers/mmc/cv1800b_sdhci.c
@@ -42,7 +42,7 @@ static int cv1800b_execute_tuning(struct mmc *mmc, u8 opcode)
for (tap = 0; tap < TUNE_MAX_PHCODE; tap++) {
cv1800b_set_tap_delay(host, tap);
- if (mmc_send_tuning(host->mmc, opcode, NULL)) {
+ if (mmc_send_tuning(host->mmc, opcode)) {
current_size = 0;
} else {
current_size++;
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 400066fa99a..e1036641452 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -262,8 +262,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
if (get_timer(start) > timeout) {
- debug("%s: Timeout on data busy\n", __func__);
- return -ETIMEDOUT;
+ debug("%s: Timeout on data busy, continue anyway\n", __func__);
+ break;
}
}
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index d5066666698..d44dfa5d06f 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -1123,7 +1123,7 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
esdhc_write32(&regs->irqstaten, IRQSTATEN_BRR);
for (i = 0; i < MAX_TUNING_LOOP; i++) {
- mmc_send_tuning(mmc, opcode, NULL);
+ mmc_send_tuning(mmc, opcode);
mdelay(1);
val = esdhc_read32(&regs->autoc12err);
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 7c39c86c5e9..b74c0140020 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -882,7 +882,7 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
esdhc_write32(&regs->mixctrl, val);
/* We are using STD tuning, no need to check return value */
- mmc_send_tuning(mmc, opcode, NULL);
+ mmc_send_tuning(mmc, opcode);
ctrl = esdhc_read32(&regs->autoc12err);
if ((!(ctrl & MIX_CTRL_EXE_TUNE)) &&
diff --git a/drivers/mmc/hi6220_dw_mmc.c b/drivers/mmc/hi6220_dw_mmc.c
index 71962cd47e0..dc0210402bd 100644
--- a/drivers/mmc/hi6220_dw_mmc.c
+++ b/drivers/mmc/hi6220_dw_mmc.c
@@ -5,15 +5,24 @@
*/
#include <common.h>
+#include <clk.h>
#include <dm.h>
#include <dwmmc.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
+#include <reset.h>
#include <asm/global_data.h>
+#include <dm/device_compat.h>
DECLARE_GLOBAL_DATA_PTR;
+enum hi6220_dwmmc_clk_type {
+ HI6220_DWMMC_CLK_BIU,
+ HI6220_DWMMC_CLK_CIU,
+ HI6220_DWMMC_CLK_CNT,
+};
+
struct hi6220_dwmmc_plat {
struct mmc_config cfg;
struct mmc mmc;
@@ -21,18 +30,43 @@ struct hi6220_dwmmc_plat {
struct hi6220_dwmmc_priv_data {
struct dwmci_host host;
+ struct clk *clks[HI6220_DWMMC_CLK_CNT];
+ struct reset_ctl_bulk rsts;
};
struct hisi_mmc_data {
unsigned int clock;
bool use_fifo;
+ u32 fifoth_val;
};
static int hi6220_dwmmc_of_to_plat(struct udevice *dev)
{
struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
+ int ret;
+ if (CONFIG_IS_ENABLED(CLK) && CONFIG_IS_ENABLED(DM_RESET)) {
+ priv->clks[HI6220_DWMMC_CLK_BIU] = devm_clk_get(dev, "biu");
+ if (IS_ERR(priv->clks[HI6220_DWMMC_CLK_BIU])) {
+ ret = PTR_ERR(priv->clks[HI6220_DWMMC_CLK_BIU]);
+ dev_err(dev, "Failed to get BIU clock(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+
+ priv->clks[HI6220_DWMMC_CLK_CIU] = devm_clk_get(dev, "ciu");
+ if (IS_ERR(priv->clks[HI6220_DWMMC_CLK_CIU])) {
+ ret = PTR_ERR(priv->clks[HI6220_DWMMC_CLK_CIU]);
+ dev_err(dev, "Failed to get CIU clock(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+
+ ret = reset_get_bulk(dev, &priv->rsts);
+ if (ret) {
+ dev_err(dev, "Failed to get resets(ret = %d)", ret);
+ return log_msg_ret("rst", ret);
+ }
+ }
host->name = dev->name;
host->ioaddr = dev_read_addr_ptr(dev);
host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
@@ -56,16 +90,43 @@ static int hi6220_dwmmc_probe(struct udevice *dev)
struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
struct hisi_mmc_data *mmc_data;
+ int ret;
mmc_data = (struct hisi_mmc_data *)dev_get_driver_data(dev);
- /* Use default bus speed due to absence of clk driver */
host->bus_hz = mmc_data->clock;
+ if (CONFIG_IS_ENABLED(CLK) && CONFIG_IS_ENABLED(DM_RESET)) {
+ ret = clk_prepare_enable(priv->clks[HI6220_DWMMC_CLK_BIU]);
+ if (ret) {
+ dev_err(dev, "Failed to enable biu clock(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+
+ ret = clk_prepare_enable(priv->clks[HI6220_DWMMC_CLK_CIU]);
+ if (ret) {
+ dev_err(dev, "Failed to enable ciu clock(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+
+ ret = reset_deassert_bulk(&priv->rsts);
+ if (ret) {
+ dev_err(dev, "Failed to deassert resets(ret = %d).\n", ret);
+ return log_msg_ret("rst", ret);
+ }
+
+ host->bus_hz = clk_get_rate(priv->clks[HI6220_DWMMC_CLK_CIU]);
+ if (host->bus_hz <= 0) {
+ dev_err(dev, "Failed to get ciu clock rate(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+ }
+ dev_dbg(dev, "bus clock rate: %d.\n", host->bus_hz);
dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000);
host->mmc = &plat->mmc;
host->fifo_mode = mmc_data->use_fifo;
+ host->fifoth_val = mmc_data->fifoth_val;
host->mmc->priv = &priv->host;
upriv->mmc = host->mmc;
host->mmc->dev = dev;
@@ -95,13 +156,20 @@ static const struct hisi_mmc_data hi6220_mmc_data = {
.use_fifo = false,
};
+static const struct hisi_mmc_data hi3798mv2x_mmc_data = {
+ .clock = 50000000,
+ .use_fifo = false,
+ // FIFO depth is 256
+ .fifoth_val = MSIZE(4) | RX_WMARK(0x7f) | TX_WMARK(0x80),
+};
+
static const struct udevice_id hi6220_dwmmc_ids[] = {
{ .compatible = "hisilicon,hi6220-dw-mshc",
.data = (ulong)&hi6220_mmc_data },
{ .compatible = "hisilicon,hi3798cv200-dw-mshc",
.data = (ulong)&hi6220_mmc_data },
{ .compatible = "hisilicon,hi3798mv200-dw-mshc",
- .data = (ulong)&hi6220_mmc_data },
+ .data = (ulong)&hi3798mv2x_mmc_data },
{ .compatible = "hisilicon,hi3660-dw-mshc",
.data = (ulong)&hi3660_mmc_data },
{ }
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c
index fcf4f03d1e2..0825c0a2a83 100644
--- a/drivers/mmc/meson_gx_mmc.c
+++ b/drivers/mmc/meson_gx_mmc.c
@@ -288,7 +288,7 @@ static int meson_mmc_probe(struct udevice *dev)
mmc_set_clock(mmc, cfg->f_min, MMC_CLK_ENABLE);
-#ifdef CONFIG_MMC_PWRSEQ
+#if CONFIG_IS_ENABLED(MMC_PWRSEQ)
/* Enable power if needed */
ret = mmc_pwrseq_get_power(dev, cfg);
if (!ret) {
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 328456831dd..1e03901e9dc 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -124,7 +124,13 @@ static int dm_mmc_execute_tuning(struct udevice *dev, uint opcode)
int mmc_execute_tuning(struct mmc *mmc, uint opcode)
{
- return dm_mmc_execute_tuning(mmc->dev, opcode);
+ int ret;
+
+ mmc->tuning = true;
+ ret = dm_mmc_execute_tuning(mmc->dev, opcode);
+ mmc->tuning = false;
+
+ return ret;
}
#endif
@@ -494,10 +500,7 @@ static int mmc_blk_probe(struct udevice *dev)
if (ret) {
debug("Probing %s failed (err=%d)\n", dev->name, ret);
- if (CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) ||
- CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) ||
- CONFIG_IS_ENABLED(MMC_HS400_SUPPORT))
- mmc_deinit(mmc);
+ mmc_deinit(mmc);
return ret;
}
@@ -505,9 +508,6 @@ static int mmc_blk_probe(struct udevice *dev)
return 0;
}
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
static int mmc_blk_remove(struct udevice *dev)
{
struct udevice *mmc_dev = dev_get_parent(dev);
@@ -516,7 +516,6 @@ static int mmc_blk_remove(struct udevice *dev)
return mmc_deinit(mmc);
}
-#endif
static const struct blk_ops mmc_blk_ops = {
.read = mmc_bread,
@@ -532,12 +531,8 @@ U_BOOT_DRIVER(mmc_blk) = {
.id = UCLASS_BLK,
.ops = &mmc_blk_ops,
.probe = mmc_blk_probe,
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
.remove = mmc_blk_remove,
.flags = DM_FLAG_OS_PREPARE,
-#endif
};
#endif /* CONFIG_BLK */
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d96db7a0f83..7b068c71ff3 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -360,7 +360,7 @@ static const u8 tuning_blk_pattern_8bit[] = {
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
};
-int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error)
+int mmc_send_tuning(struct mmc *mmc, u32 opcode)
{
struct mmc_cmd cmd;
struct mmc_data data;
@@ -1570,13 +1570,20 @@ static int sd_read_ssr(struct mmc *mmc)
return 0;
}
#endif
-/* frequency bases */
-/* divided by 10 to be nice to platforms without floating point */
+/*
+ * TRAN_SPEED bits 0:2 encode the frequency unit:
+ * 0 = 100KHz, 1 = 1MHz, 2 = 10MHz, 3 = 100MHz, values 4 - 7 are reserved.
+ * The values in fbase[] are divided by 10 to avoid floats in multiplier[].
+ */
static const int fbase[] = {
10000,
100000,
1000000,
10000000,
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
};
/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
@@ -2027,9 +2034,9 @@ static int mmc_select_hs400(struct mmc *mmc)
mmc_set_clock(mmc, mmc->tran_speed, false);
/* execute tuning if needed */
- mmc->hs400_tuning = 1;
+ mmc->hs400_tuning = true;
err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
- mmc->hs400_tuning = 0;
+ mmc->hs400_tuning = false;
if (err) {
debug("tuning failed\n");
return err;
@@ -2250,6 +2257,16 @@ error:
return -ENOTSUPP;
}
+#else
+static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
+{
+ return 0;
+};
+
+static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
+{
+ return 0;
+};
#endif
#if CONFIG_IS_ENABLED(MMC_TINY)
@@ -2560,6 +2577,8 @@ static int mmc_startup(struct mmc *mmc)
mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
mmc->legacy_speed = freq * mult;
+ if (!mmc->legacy_speed)
+ log_debug("TRAN_SPEED: reserved value");
mmc_select_mode(mmc, MMC_LEGACY);
mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
@@ -3010,13 +3029,15 @@ int mmc_init(struct mmc *mmc)
return err;
}
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
int mmc_deinit(struct mmc *mmc)
{
u32 caps_filtered;
+ if (!CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) &&
+ !CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) &&
+ !CONFIG_IS_ENABLED(MMC_HS400_SUPPORT))
+ return 0;
+
if (!mmc->has_init)
return 0;
@@ -3034,7 +3055,6 @@ int mmc_deinit(struct mmc *mmc)
return mmc_select_mode_and_width(mmc, caps_filtered);
}
}
-#endif
int mmc_set_dsr(struct mmc *mmc, u16 val)
{
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
index 5a0c61daed5..296aaee7331 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -1131,7 +1131,7 @@ static int hs400_tune_response(struct udevice *dev, u32 opcode)
i << PAD_CMD_TUNE_RX_DLY3_S);
for (j = 0; j < 3; j++) {
- mmc_send_tuning(mmc, opcode, &cmd_err);
+ cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err) {
cmd_delay |= (1 << i);
} else {
@@ -1181,7 +1181,7 @@ static int msdc_tune_response(struct udevice *dev, u32 opcode)
i << MSDC_PAD_TUNE_CMDRDLY_S);
for (j = 0; j < 3; j++) {
- mmc_send_tuning(mmc, opcode, &cmd_err);
+ cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err) {
rise_delay |= (1 << i);
} else {
@@ -1203,7 +1203,7 @@ static int msdc_tune_response(struct udevice *dev, u32 opcode)
i << MSDC_PAD_TUNE_CMDRDLY_S);
for (j = 0; j < 3; j++) {
- mmc_send_tuning(mmc, opcode, &cmd_err);
+ cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err) {
fall_delay |= (1 << i);
} else {
@@ -1238,7 +1238,7 @@ skip_fall:
clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
i << MSDC_PAD_TUNE_CMDRRDLY_S);
- mmc_send_tuning(mmc, opcode, &cmd_err);
+ cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err)
internal_delay |= (1 << i);
}
@@ -1264,7 +1264,6 @@ static int msdc_tune_data(struct udevice *dev, u32 opcode)
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0, };
u8 final_delay, final_maxlen;
void __iomem *tune_reg = &host->base->pad_tune;
- int cmd_err;
int i, ret;
if (host->dev_comp->pad_tune0)
@@ -1277,10 +1276,10 @@ static int msdc_tune_data(struct udevice *dev, u32 opcode)
clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
i << MSDC_PAD_TUNE_DATRRDLY_S);
- ret = mmc_send_tuning(mmc, opcode, &cmd_err);
+ ret = mmc_send_tuning(mmc, opcode);
if (!ret) {
rise_delay |= (1 << i);
- } else if (cmd_err) {
+ } else {
/* in this case, retune response is needed */
ret = msdc_tune_response(dev, opcode);
if (ret)
@@ -1300,10 +1299,10 @@ static int msdc_tune_data(struct udevice *dev, u32 opcode)
clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
i << MSDC_PAD_TUNE_DATRRDLY_S);
- ret = mmc_send_tuning(mmc, opcode, &cmd_err);
+ ret = mmc_send_tuning(mmc, opcode);
if (!ret) {
fall_delay |= (1 << i);
- } else if (cmd_err) {
+ } else {
/* in this case, retune response is needed */
ret = msdc_tune_response(dev, opcode);
if (ret)
@@ -1362,7 +1361,7 @@ static int msdc_tune_together(struct udevice *dev, u32 opcode)
for (i = 0; i < PAD_DELAY_MAX; i++) {
msdc_set_cmd_delay(host, i);
msdc_set_data_delay(host, i);
- ret = mmc_send_tuning(mmc, opcode, NULL);
+ ret = mmc_send_tuning(mmc, opcode);
if (!ret)
rise_delay |= (1 << i);
}
@@ -1378,7 +1377,7 @@ static int msdc_tune_together(struct udevice *dev, u32 opcode)
for (i = 0; i < PAD_DELAY_MAX; i++) {
msdc_set_cmd_delay(host, i);
msdc_set_data_delay(host, i);
- ret = mmc_send_tuning(mmc, opcode, NULL);
+ ret = mmc_send_tuning(mmc, opcode);
if (!ret)
fall_delay |= (1 << i);
}
diff --git a/drivers/mmc/octeontx_hsmmc.c b/drivers/mmc/octeontx_hsmmc.c
index 4ee62df9d40..7f9c4f4d36d 100644
--- a/drivers/mmc/octeontx_hsmmc.c
+++ b/drivers/mmc/octeontx_hsmmc.c
@@ -1653,6 +1653,12 @@ static int octeontx_mmc_test_cmd(struct mmc *mmc, u32 opcode, int *statp)
return err;
}
+static int octeontx_mmc_send_tuning(struct mmc *mmc, u32 opcode, int *error)
+{
+ *error = 0;
+ return mmc_send_tuning(mmc, opcode);
+}
+
static int octeontx_mmc_test_get_ext_csd(struct mmc *mmc, u32 opcode,
int *statp)
{
@@ -2006,7 +2012,7 @@ struct adj adj[] = {
{ "CMD_IN", 48, octeontx_mmc_test_cmd, MMC_CMD_SEND_STATUS,
false, false, false, 2, },
/* { "CMD_OUT", 32, octeontx_mmc_test_cmd, MMC_CMD_SEND_STATUS, },*/
- { "DATA_IN(HS200)", 16, mmc_send_tuning,
+ { "DATA_IN(HS200)", 16, octeontx_mmc_send_tuning,
MMC_CMD_SEND_TUNING_BLOCK_HS200, false, true, false, 2, },
{ "DATA_IN", 16, octeontx_mmc_test_get_ext_csd, 0, false, false,
true, 2, },
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index a2595d19e7f..99f21b2c546 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -666,7 +666,7 @@ static int omap_hsmmc_execute_tuning(struct udevice *dev, uint opcode)
while (phase_delay <= MAX_PHASE_DELAY) {
omap_hsmmc_set_dll(mmc, phase_delay);
- cur_match = !mmc_send_tuning(mmc, opcode, NULL);
+ cur_match = !mmc_send_tuning(mmc, opcode);
if (cur_match) {
if (prev_match) {
@@ -731,7 +731,7 @@ static int omap_hsmmc_execute_tuning(struct udevice *dev, uint opcode)
*/
for (i = 3; i <= 10; i++) {
omap_hsmmc_set_dll(mmc, phase_delay + i);
- if (mmc_send_tuning(mmc, opcode, NULL)) {
+ if (mmc_send_tuning(mmc, opcode)) {
if (temperature < 10000)
phase_delay += i + 6;
else if (temperature < 20000)
@@ -749,7 +749,7 @@ static int omap_hsmmc_execute_tuning(struct udevice *dev, uint opcode)
for (i = 2; i >= -10; i--) {
omap_hsmmc_set_dll(mmc, phase_delay + i);
- if (mmc_send_tuning(mmc, opcode, NULL)) {
+ if (mmc_send_tuning(mmc, opcode)) {
if (temperature < 10000)
phase_delay += i + 12;
else if (temperature < 20000)
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 20b1e9277eb..23db2a75c44 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -568,8 +568,8 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode)
struct mmc *mmc = upriv->mmc;
unsigned int tap_num;
unsigned int taps = 0;
- int i, ret = 0;
- u32 caps;
+ int i, ret = 0, sret;
+ u32 caps, reg;
/* Only supported on Renesas RCar */
if (!(priv->caps & TMIO_SD_CAP_RCAR_UHS))
@@ -605,15 +605,15 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode)
caps = priv->caps;
priv->caps &= ~TMIO_SD_CAP_DMA_INTERNAL;
- ret = mmc_send_tuning(mmc, opcode, NULL);
+ ret = mmc_send_tuning(mmc, opcode);
priv->caps = caps;
if (ret == 0)
taps |= BIT(i);
- ret = renesas_sdhi_compare_scc_data(priv);
- if (ret == 0)
+ reg = renesas_sdhi_compare_scc_data(priv);
+ if (reg == 0)
priv->smpcmp |= BIT(i);
mdelay(1);
@@ -624,9 +624,9 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode)
* eMMC.
*/
if (ret && (opcode == MMC_CMD_SEND_TUNING_BLOCK_HS200)) {
- ret = mmc_send_stop_transmission(mmc, false);
- if (ret < 0)
- dev_dbg(dev, "Tuning abort fail (%d)\n", ret);
+ sret = mmc_send_stop_transmission(mmc, false);
+ if (sret < 0)
+ dev_dbg(dev, "Tuning abort fail (%d)\n", sret);
}
}
@@ -798,9 +798,12 @@ static int renesas_sdhi_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct tmio_sd_priv *priv = dev_get_priv(dev);
+ struct mmc *mmc = upriv->mmc;
- renesas_sdhi_check_scc_error(dev);
+ if (!mmc->tuning)
+ renesas_sdhi_check_scc_error(dev);
if (cmd->cmdidx == MMC_CMD_SEND_STATUS)
renesas_sdhi_adjust_hs400_mode_enable(priv);
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 72c820ee633..ad4529d6afa 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -145,7 +145,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
host->fifo_mode = priv->fifo_mode;
-#ifdef CONFIG_MMC_PWRSEQ
+#if CONFIG_IS_ENABLED(MMC_PWRSEQ)
/* Enable power if needed */
ret = mmc_pwrseq_get_power(dev, &plat->cfg);
if (!ret) {
diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c
index 327a05ad11d..c0a9f60b149 100644
--- a/drivers/mmc/sdhci-cadence.c
+++ b/drivers/mmc/sdhci-cadence.c
@@ -224,7 +224,7 @@ static int __maybe_unused sdhci_cdns_execute_tuning(struct udevice *dev,
for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) {
if (sdhci_cdns_set_tune_val(plat, i) ||
- mmc_send_tuning(mmc, opcode, NULL)) { /* bad */
+ mmc_send_tuning(mmc, opcode)) { /* bad */
cur_streak = 0;
} else { /* good */
cur_streak++;
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index 890c496b535..719c4830bc3 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -299,7 +299,13 @@ static int tmio_sd_dma_wait_for_irq(struct udevice *dev, u32 flag,
struct tmio_sd_priv *priv = dev_get_priv(dev);
long wait = 1000000 + 10 * blocks;
- while (!(tmio_sd_readl(priv, TMIO_SD_DMA_INFO1) & flag)) {
+ for (;;) {
+ if (tmio_sd_readl(priv, TMIO_SD_DMA_INFO1) & flag)
+ break;
+
+ if (tmio_sd_readl(priv, TMIO_SD_INFO1) & TMIO_SD_INFO1_CMP)
+ break;
+
if (wait-- < 0) {
dev_err(dev, "timeout during DMA\n");
return -ETIMEDOUT;