Merge tag 'u-boot-imx-master-20240415' of https://gitlab.denx.de/u-boot/custodians/u-boot-imx
CI:
https://source.denx.de/u-boot/custodians/u-boot-imx/-/pipelines/20348
- Update the imx_rgpio2p to only access one address as per the
dt-schema.
- Remove unused imx9_cpu.c file.
- Only use the LPUART ipg clk for i.MX7ULP.
- Use the correct anatop base for accessing the PLL clocks on i.MX93.
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 1008232..6b6a162 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -90,6 +90,14 @@
imply FPGA_SOCFPGA
imply SPL_USE_TINY_PRINTF
+config SOCFPGA_ARRIA10_ALWAYS_REPROGRAM
+ bool "Always reprogram Arria 10 FPGA"
+ depends on TARGET_SOCFPGA_ARRIA10
+ help
+ Arria 10 FPGA is only programmed during the cold boot.
+ This option forces the FPGA to be reprogrammed every reboot,
+ allowing to change the bitstream and apply it with warm reboot.
+
config TARGET_SOCFPGA_CYCLONE5
bool
select TARGET_SOCFPGA_GEN5
diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c
index 9edbbf4..3981d2d 100644
--- a/arch/arm/mach-socfpga/spl_a10.c
+++ b/arch/arm/mach-socfpga/spl_a10.c
@@ -122,7 +122,10 @@
arch_early_init_r();
/* If the full FPGA is already loaded, ie.from EPCQ, config fpga pins */
- if (is_fpgamgr_user_mode()) {
+ if ((IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) &&
+ is_regular_boot_valid()) ||
+ (!IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) &&
+ is_fpgamgr_user_mode())) {
ret = config_pins(gd->fdt_blob, "shared");
if (ret)
return;
@@ -130,7 +133,8 @@
ret = config_pins(gd->fdt_blob, "fpga");
if (ret)
return;
- } else if (!is_fpgamgr_early_user_mode()) {
+ } else if (IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) ||
+ !is_fpgamgr_early_user_mode()) {
/* Program IOSSM(early IO release) or full FPGA */
fpgamgr_program(buf, FPGA_BUFSIZ, 0);
diff --git a/configs/socfpga_chameleonv3_defconfig b/configs/socfpga_chameleonv3_defconfig
index 6ea61ca..7506aa8 100644
--- a/configs/socfpga_chameleonv3_defconfig
+++ b/configs/socfpga_chameleonv3_defconfig
@@ -7,6 +7,7 @@
CONFIG_SPL_TEXT_BASE=0xFFE00000
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_TARGET_SOCFPGA_CHAMELEONV3=y
+CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM=y
CONFIG_SPL_FS_FAT=y
CONFIG_FIT=y
CONFIG_SPL_FIT=y
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9e82990..e53d52c 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -91,4 +91,4 @@
obj-$(CONFIG_ESM_K3) += k3_esm.o
obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
obj-$(CONFIG_SL28CPLD) += sl28cpld.o
-obj-$(CONFIG_SPL_SOCFPGA_SEC_REG) += socfpga_dtreg.o
+obj-$(CONFIG_SPL_SOCFPGA_DT_REG) += socfpga_dtreg.o
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index f7fe6d1..06e32e7 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -20,11 +20,19 @@
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 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 @@
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 @@
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 @@
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 @@
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 3374321..72c3fb6 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -11,7 +11,7 @@
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 05595bd..2139fea 100644
--- a/drivers/mmc/am654_sdhci.c
+++ b/drivers/mmc/am654_sdhci.c
@@ -390,7 +390,7 @@
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 5cf5502..2666b65 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 mmc_config cfg;
struct mmc mmc;
};
-#endif
static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
{
@@ -355,68 +353,9 @@
writel(sdi_clkcr, &host->base->clock);
udelay(CLK_CHANGE_DELAY);
- 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 @@
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 @@
.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 2275c53..9af6b97 100644
--- a/drivers/mmc/cv1800b_sdhci.c
+++ b/drivers/mmc/cv1800b_sdhci.c
@@ -42,7 +42,7 @@
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 400066f..e103664 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -262,8 +262,8 @@
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 d506666..d44dfa5 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -1123,7 +1123,7 @@
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 7c39c86..b74c014 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -882,7 +882,7 @@
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 71962cd..dc02104 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_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 @@
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 @@
.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 fcf4f03..0825c0a 100644
--- a/drivers/mmc/meson_gx_mmc.c
+++ b/drivers/mmc/meson_gx_mmc.c
@@ -288,7 +288,7 @@
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 3284568..1e03901 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -124,7 +124,13 @@
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 @@
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 @@
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 @@
return mmc_deinit(mmc);
}
-#endif
static const struct blk_ops mmc_blk_ops = {
.read = mmc_bread,
@@ -532,12 +531,8 @@
.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 d96db7a..7b068c7 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -360,7 +360,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 5a0c61d..296aaee 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -1131,7 +1131,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 4ee62df..7f9c4f4 100644
--- a/drivers/mmc/octeontx_hsmmc.c
+++ b/drivers/mmc/octeontx_hsmmc.c
@@ -1653,6 +1653,12 @@
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 @@
{ "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 a2595d1..99f21b2 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -666,7 +666,7 @@
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 @@
*/
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 @@
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 20b1e92..23db2a7 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -568,8 +568,8 @@
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 @@
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 @@
* 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 @@
#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 72c820e..ad4529d 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -145,7 +145,7 @@
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 327a05a..c0a9f60 100644
--- a/drivers/mmc/sdhci-cadence.c
+++ b/drivers/mmc/sdhci-cadence.c
@@ -224,7 +224,7 @@
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 890c496..719c483 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -299,7 +299,13 @@
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;
diff --git a/include/mmc.h b/include/mmc.h
index 1022db3..4b8327f 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -590,7 +590,7 @@
uint f_max;
uint b_max;
unsigned char part_type;
-#ifdef CONFIG_MMC_PWRSEQ
+#if CONFIG_IS_ENABLED(MMC_PWRSEQ)
struct udevice *pwr_dev;
#endif
};
@@ -736,7 +736,8 @@
* accessing the boot partitions
*/
u32 quirks;
- u8 hs400_tuning;
+ bool tuning:1;
+ bool hs400_tuning:1;
enum bus_mode user_speed_mode; /* input speed mode from user */
};
@@ -795,7 +796,7 @@
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);
+int mmc_send_tuning(struct mmc *mmc, u32 opcode);
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data);
int mmc_deinit(struct mmc *mmc);
@@ -808,7 +809,7 @@
*/
int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg);
-#ifdef CONFIG_MMC_PWRSEQ
+#if CONFIG_IS_ENABLED(MMC_PWRSEQ)
/**
* mmc_pwrseq_get_power() - get a power device from device tree
*