aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2020-06-24 09:05:35 -0400
committerTom Rini <trini@konsulko.com>2020-06-24 09:05:35 -0400
commit922c6d5d0090e51fdd5bb75795c3384a18f5d2b6 (patch)
tree434b45e0a8a458884dbb0119da404808a2f4f488 /drivers
parent331c7438104149655a5fe96ed4a3d29b00d422de (diff)
parentf12341a9529540113f01989149bbbeb68662a829 (diff)
downloadu-boot-922c6d5d0090e51fdd5bb75795c3384a18f5d2b6.zip
u-boot-922c6d5d0090e51fdd5bb75795c3384a18f5d2b6.tar.gz
u-boot-922c6d5d0090e51fdd5bb75795c3384a18f5d2b6.tar.bz2
Merge tag 'mmc-2020-6-24' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmc
- Fix fsl_esdhc_imx tunning mask - Disable CMD CRC for normal tuning for fsl_esdhc_imx - Retry CM1 until emmc ready - Fix sdhci HISPD handling - Cache-aligned extcsd reading
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/fsl_esdhc_imx.c22
-rw-r--r--drivers/mmc/mmc.c9
-rw-r--r--drivers/mmc/sdhci.c25
3 files changed, 39 insertions, 17 deletions
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index f42e018..5b61eeb 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -907,19 +907,9 @@ static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
ctrl = readl(&regs->autoc12err);
if ((!(ctrl & MIX_CTRL_EXE_TUNE)) &&
(ctrl & MIX_CTRL_SMPCLK_SEL)) {
- /*
- * need to wait some time, make sure sd/mmc fininsh
- * send out tuning data, otherwise, the sd/mmc can't
- * response to any command when the card still out
- * put the tuning data.
- */
- mdelay(1);
ret = 0;
break;
}
-
- /* Add 1ms delay for SD and eMMC */
- mdelay(1);
}
writel(irqstaten, &regs->irqstaten);
@@ -1267,6 +1257,18 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv,
val |= priv->tuning_start_tap;
val &= ~ESDHC_TUNING_STEP_MASK;
val |= (priv->tuning_step) << ESDHC_TUNING_STEP_SHIFT;
+
+ /* Disable the CMD CRC check for tuning, if not, need to
+ * add some delay after every tuning command, because
+ * hardware standard tuning logic will directly go to next
+ * step once it detect the CMD CRC error, will not wait for
+ * the card side to finally send out the tuning data, trigger
+ * the buffer read ready interrupt immediately. If usdhc send
+ * the next tuning command some eMMC card will stuck, can't
+ * response, block the tuning procedure or the first command
+ * after the whole tuning procedure always can't get any response.
+ */
+ val |= ESDHC_TUNING_CMD_CRC_CHECK_DISABLE;
writel(val, &regs->tuning_ctrl);
}
}
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 620bb93..725a367 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -669,12 +669,15 @@ static int mmc_send_op_cond_iter(struct mmc *mmc, int use_arg)
static int mmc_send_op_cond(struct mmc *mmc)
{
int err, i;
+ int timeout = 1000;
+ uint start;
/* Some cards seem to need this */
mmc_go_idle(mmc);
+ start = get_timer(0);
/* Asking to the card its capabilities */
- for (i = 0; i < 2; i++) {
+ for (i = 0; ; i++) {
err = mmc_send_op_cond_iter(mmc, i != 0);
if (err)
return err;
@@ -682,6 +685,10 @@ static int mmc_send_op_cond(struct mmc *mmc)
/* exit if not busy (flag seems to be inverted) */
if (mmc->ocr & OCR_BUSY)
break;
+
+ if (get_timer(start) > timeout)
+ return -ETIMEDOUT;
+ udelay(100);
}
mmc->op_cond_pending = 1;
return 0;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 92cc843..f4eb655 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -567,6 +567,7 @@ static int sdhci_set_ios(struct mmc *mmc)
#endif
u32 ctrl;
struct sdhci_host *host = mmc->priv;
+ bool no_hispd_bit = false;
if (host->ops && host->ops->set_control_reg)
host->ops->set_control_reg(host);
@@ -594,14 +595,26 @@ static int sdhci_set_ios(struct mmc *mmc)
ctrl &= ~SDHCI_CTRL_4BITBUS;
}
- if (mmc->clock > 26000000)
- ctrl |= SDHCI_CTRL_HISPD;
- else
- ctrl &= ~SDHCI_CTRL_HISPD;
-
if ((host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) ||
- (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE))
+ (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE)) {
ctrl &= ~SDHCI_CTRL_HISPD;
+ no_hispd_bit = true;
+ }
+
+ if (!no_hispd_bit) {
+ if (mmc->selected_mode == MMC_HS ||
+ mmc->selected_mode == SD_HS ||
+ mmc->selected_mode == MMC_DDR_52 ||
+ mmc->selected_mode == MMC_HS_200 ||
+ mmc->selected_mode == MMC_HS_400 ||
+ mmc->selected_mode == UHS_SDR25 ||
+ mmc->selected_mode == UHS_SDR50 ||
+ mmc->selected_mode == UHS_SDR104 ||
+ mmc->selected_mode == UHS_DDR50)
+ ctrl |= SDHCI_CTRL_HISPD;
+ else
+ ctrl &= ~SDHCI_CTRL_HISPD;
+ }
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);