Merge tag 'mmc-1-16-2020' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmc
- Cleanup of fsl_esdhc driver together with arch/defconfig change - Add quirk for APP_CMD retry
This commit is contained in:
@@ -79,7 +79,7 @@ config MMC_QUIRKS
|
||||
help
|
||||
Some cards and hosts may sometimes behave unexpectedly (quirks).
|
||||
This option enable workarounds to handle those quirks. Some of them
|
||||
are enabled by default, other may require additionnal flags or are
|
||||
are enabled by default, other may require additional flags or are
|
||||
enabled by the host driver.
|
||||
|
||||
config MMC_HW_PARTITIONING
|
||||
@@ -711,19 +711,10 @@ endif
|
||||
|
||||
config FSL_ESDHC
|
||||
bool "Freescale/NXP eSDHC controller support"
|
||||
select FSL_ESDHC_USE_PERIPHERAL_CLK if MMC_HS200_SUPPORT || MMC_UHS_SUPPORT
|
||||
help
|
||||
This selects support for the eSDHC (Enhanced Secure Digital Host
|
||||
Controller) found on numerous Freescale/NXP SoCs.
|
||||
|
||||
config FSL_ESDHC_USE_PERIPHERAL_CLK
|
||||
bool "enable ESDHC peripheral clock support"
|
||||
depends on FSL_ESDHC
|
||||
help
|
||||
eSDHC supports two reference clocks (platform clock and peripheral clock).
|
||||
Peripheral clock which could provide higher clock frequency is required to
|
||||
be used for tuning of SD UHS mode and eMMC HS200/HS400 modes.
|
||||
|
||||
config FSL_ESDHC_IMX
|
||||
bool "Freescale/NXP i.MX eSDHC controller support"
|
||||
help
|
||||
|
||||
@@ -81,6 +81,7 @@ struct fsl_esdhc_plat {
|
||||
struct fsl_esdhc_priv {
|
||||
struct fsl_esdhc *esdhc_regs;
|
||||
unsigned int sdhc_clk;
|
||||
bool is_sdhc_per_clk;
|
||||
unsigned int clock;
|
||||
#if !CONFIG_IS_ENABLED(DM_MMC)
|
||||
struct mmc *mmc;
|
||||
@@ -523,7 +524,6 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
|
||||
esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
|
||||
static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable)
|
||||
{
|
||||
struct fsl_esdhc *regs = priv->esdhc_regs;
|
||||
@@ -550,18 +550,18 @@ static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable)
|
||||
mdelay(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
|
||||
{
|
||||
struct fsl_esdhc *regs = priv->esdhc_regs;
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
|
||||
/* Select to use peripheral clock */
|
||||
esdhc_clock_control(priv, false);
|
||||
esdhc_setbits32(®s->esdhcctl, ESDHCCTL_PCS);
|
||||
esdhc_clock_control(priv, true);
|
||||
#endif
|
||||
if (priv->is_sdhc_per_clk) {
|
||||
/* Select to use peripheral clock */
|
||||
esdhc_clock_control(priv, false);
|
||||
esdhc_setbits32(®s->esdhcctl, ESDHCCTL_PCS);
|
||||
esdhc_clock_control(priv, true);
|
||||
}
|
||||
|
||||
/* Set the clock speed */
|
||||
if (priv->clock != mmc->clock)
|
||||
set_sysctl(priv, mmc, mmc->clock);
|
||||
@@ -716,17 +716,8 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd)
|
||||
if (esdhc_status_fixup(blob, compat))
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
|
||||
do_fixup_by_compat_u32(blob, compat, "peripheral-frequency",
|
||||
gd->arch.sdhc_clk, 1);
|
||||
#else
|
||||
do_fixup_by_compat_u32(blob, compat, "clock-frequency",
|
||||
gd->arch.sdhc_clk, 1);
|
||||
#endif
|
||||
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
|
||||
do_fixup_by_compat_u32(blob, compat, "adapter-type",
|
||||
(u32)(gd->arch.sdhc_adapter), 1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -788,6 +779,8 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
|
||||
|
||||
priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base);
|
||||
priv->sdhc_clk = cfg->sdhc_clk;
|
||||
if (gd->arch.sdhc_per_clk)
|
||||
priv->is_sdhc_per_clk = true;
|
||||
|
||||
mmc_cfg = &plat->cfg;
|
||||
|
||||
@@ -826,7 +819,11 @@ int fsl_esdhc_mmc_init(bd_t *bis)
|
||||
|
||||
cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
|
||||
cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
|
||||
cfg->sdhc_clk = gd->arch.sdhc_clk;
|
||||
/* Prefer peripheral clock which provides higher frequency. */
|
||||
if (gd->arch.sdhc_per_clk)
|
||||
cfg->sdhc_clk = gd->arch.sdhc_per_clk;
|
||||
else
|
||||
cfg->sdhc_clk = gd->arch.sdhc_clk;
|
||||
return fsl_esdhc_initialize(bis, cfg);
|
||||
}
|
||||
#else /* DM_MMC */
|
||||
@@ -848,7 +845,13 @@ static int fsl_esdhc_probe(struct udevice *dev)
|
||||
#endif
|
||||
priv->dev = dev;
|
||||
|
||||
priv->sdhc_clk = gd->arch.sdhc_clk;
|
||||
if (gd->arch.sdhc_per_clk) {
|
||||
priv->sdhc_clk = gd->arch.sdhc_per_clk;
|
||||
priv->is_sdhc_per_clk = true;
|
||||
} else {
|
||||
priv->sdhc_clk = gd->arch.sdhc_clk;
|
||||
}
|
||||
|
||||
if (priv->sdhc_clk <= 0) {
|
||||
dev_err(dev, "Unable to get clk for %s\n", dev->name);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -661,35 +661,6 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
|
||||
priv->clock = clock;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
|
||||
static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable)
|
||||
{
|
||||
struct fsl_esdhc *regs = priv->esdhc_regs;
|
||||
u32 value;
|
||||
u32 time_out;
|
||||
|
||||
value = esdhc_read32(®s->sysctl);
|
||||
|
||||
if (enable)
|
||||
value |= SYSCTL_CKEN;
|
||||
else
|
||||
value &= ~SYSCTL_CKEN;
|
||||
|
||||
esdhc_write32(®s->sysctl, value);
|
||||
|
||||
time_out = 20;
|
||||
value = PRSSTAT_SDSTB;
|
||||
while (!(esdhc_read32(®s->prsstat) & value)) {
|
||||
if (time_out == 0) {
|
||||
printf("fsl_esdhc: Internal clock never stabilised.\n");
|
||||
break;
|
||||
}
|
||||
time_out--;
|
||||
mdelay(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MMC_SUPPORTS_TUNING
|
||||
static int esdhc_change_pinstate(struct udevice *dev)
|
||||
{
|
||||
@@ -961,12 +932,6 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
|
||||
int ret __maybe_unused;
|
||||
u32 clock;
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
|
||||
/* Select to use peripheral clock */
|
||||
esdhc_clock_control(priv, false);
|
||||
esdhc_setbits32(®s->scr, ESDHCCTL_PCS);
|
||||
esdhc_clock_control(priv, true);
|
||||
#endif
|
||||
/* Set the clock speed */
|
||||
clock = mmc->clock;
|
||||
if (clock < mmc->cfg->f_min)
|
||||
@@ -1394,13 +1359,8 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd)
|
||||
if (esdhc_status_fixup(blob, compat))
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
|
||||
do_fixup_by_compat_u32(blob, compat, "peripheral-frequency",
|
||||
gd->arch.sdhc_clk, 1);
|
||||
#else
|
||||
do_fixup_by_compat_u32(blob, compat, "clock-frequency",
|
||||
gd->arch.sdhc_clk, 1);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1444,6 +1444,20 @@ static int sd_read_ssr(struct mmc *mmc)
|
||||
cmd.cmdarg = mmc->rca << 16;
|
||||
|
||||
err = mmc_send_cmd(mmc, &cmd, NULL);
|
||||
#ifdef CONFIG_MMC_QUIRKS
|
||||
if (err && (mmc->quirks & MMC_QUIRK_RETRY_APP_CMD)) {
|
||||
int retries = 4;
|
||||
/*
|
||||
* It has been seen that APP_CMD may fail on the first
|
||||
* attempt, let's try a few more times
|
||||
*/
|
||||
do {
|
||||
err = mmc_send_cmd(mmc, &cmd, NULL);
|
||||
if (!err)
|
||||
break;
|
||||
} while (retries--);
|
||||
}
|
||||
#endif
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -2755,7 +2769,8 @@ int mmc_get_op_cond(struct mmc *mmc)
|
||||
|
||||
#ifdef CONFIG_MMC_QUIRKS
|
||||
mmc->quirks = MMC_QUIRK_RETRY_SET_BLOCKLEN |
|
||||
MMC_QUIRK_RETRY_SEND_CID;
|
||||
MMC_QUIRK_RETRY_SEND_CID |
|
||||
MMC_QUIRK_RETRY_APP_CMD;
|
||||
#endif
|
||||
|
||||
err = mmc_power_cycle(mmc);
|
||||
|
||||
Reference in New Issue
Block a user