diff options
author | Tom Rini | 2024-04-15 07:38:51 -0600 |
---|---|---|
committer | Tom Rini | 2024-04-15 07:38:51 -0600 |
commit | db972665794f38c7bf224d69f6a6206a4083d85d (patch) | |
tree | 414ce1b69f602096c093719fed5302c8cf0fb94a /drivers | |
parent | d736d9f2126e014e92cd3efaa82d4b1520c6c25b (diff) | |
parent | 3657ef738ad6aa2c32c569e7ae67a5557343f7d0 (diff) |
Merge https://source.denx.de/u-boot/custodians/u-boot-mmc
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/Kconfig | 23 | ||||
-rw-r--r-- | drivers/mmc/Makefile | 2 | ||||
-rw-r--r-- | drivers/mmc/am654_sdhci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/arm_pl180_mmci.c | 66 | ||||
-rw-r--r-- | drivers/mmc/cv1800b_sdhci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/dw_mmc.c | 4 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc_imx.c | 2 | ||||
-rw-r--r-- | drivers/mmc/hi6220_dw_mmc.c | 72 | ||||
-rw-r--r-- | drivers/mmc/meson_gx_mmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/mmc-uclass.c | 21 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 38 | ||||
-rw-r--r-- | drivers/mmc/mtk-sd.c | 21 | ||||
-rw-r--r-- | drivers/mmc/octeontx_hsmmc.c | 8 | ||||
-rw-r--r-- | drivers/mmc/omap_hsmmc.c | 6 | ||||
-rw-r--r-- | drivers/mmc/renesas-sdhi.c | 21 | ||||
-rw-r--r-- | drivers/mmc/rockchip_dw_mmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/sdhci-cadence.c | 2 | ||||
-rw-r--r-- | drivers/mmc/tmio-common.c | 8 |
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(®s->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(®s->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(®s->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(®s->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; |