- Cleanup of fsl_esdhc driver together with arch/defconfig change
- Add quirk for APP_CMD retry
This commit is contained in:
Tom Rini
2020-01-16 13:20:51 -05:00
19 changed files with 66 additions and 166 deletions

View File

@@ -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

View File

@@ -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(&regs->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(&regs->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(&regs->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;

View File

@@ -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(&regs->sysctl);
if (enable)
value |= SYSCTL_CKEN;
else
value &= ~SYSCTL_CKEN;
esdhc_write32(&regs->sysctl, value);
time_out = 20;
value = PRSSTAT_SDSTB;
while (!(esdhc_read32(&regs->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(&regs->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

View File

@@ -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);