Skip to content

Commit 8b2bb0a

Browse files
Dong Aishengcjb
authored andcommitted
mmc: esdhc-imx: clearing SDHCI_CTRL_EXEC_TUNING should not affect other bits
Current code will clear all turning related bits like ESDHC_STD_TUNING_EN and ESDHC_MIX_CTRL_FBCLK_SEL when clear SDHCI_CTRL_EXEC_TUNING. This may cause the card which has already passed the turning to become unwork since the turning status lost. We observed this failure when enable runtime pm. BTW, imx needs to enable ESDHC_MIX_CTRL_FBCLK_SEL bit for turned clock. The FBCLK_SEL will be cleared when SDHCI_CTRL_TUNED_CLK is cleared and SDHCI_CTRL_EXEC_TUNING is not set. This is used in case we change to another normal card from a UHS card in the same slot. FBCLK_SEL is not needed for normal card. After that, SDHCI_CTRL_EXEC_TUNING will only affect ESDHC_MIX_CTRL_EXE_TUNE. Clearing it does not affect the turned card to remain working on UHS mode. Signed-off-by: Dong Aisheng <[email protected]> Acked-by: Ulf Hansson <[email protected]> Signed-off-by: Chris Ball <[email protected]>
1 parent d131a71 commit 8b2bb0a

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

drivers/mmc/host/sdhci-esdhc-imx.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -439,24 +439,20 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
439439
} else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
440440
u32 v = readl(host->ioaddr + SDHCI_ACMD12_ERR);
441441
u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
442-
new_val = readl(host->ioaddr + ESDHC_TUNING_CTRL);
442+
if (val & SDHCI_CTRL_TUNED_CLK) {
443+
v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
444+
} else {
445+
v &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
446+
m &= ~ESDHC_MIX_CTRL_FBCLK_SEL;
447+
}
448+
443449
if (val & SDHCI_CTRL_EXEC_TUNING) {
444-
new_val |= ESDHC_STD_TUNING_EN |
445-
ESDHC_TUNING_START_TAP;
446450
v |= ESDHC_MIX_CTRL_EXE_TUNE;
447451
m |= ESDHC_MIX_CTRL_FBCLK_SEL;
448452
} else {
449-
new_val &= ~ESDHC_STD_TUNING_EN;
450453
v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
451-
m &= ~ESDHC_MIX_CTRL_FBCLK_SEL;
452454
}
453455

454-
if (val & SDHCI_CTRL_TUNED_CLK)
455-
v |= ESDHC_MIX_CTRL_SMPCLK_SEL;
456-
else
457-
v &= ~ESDHC_MIX_CTRL_SMPCLK_SEL;
458-
459-
writel(new_val, host->ioaddr + ESDHC_TUNING_CTRL);
460456
writel(v, host->ioaddr + SDHCI_ACMD12_ERR);
461457
writel(m, host->ioaddr + ESDHC_MIX_CTRL);
462458
}
@@ -1038,6 +1034,12 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
10381034
if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
10391035
sdhci_esdhc_ops.platform_execute_tuning =
10401036
esdhc_executing_tuning;
1037+
1038+
if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING)
1039+
writel(readl(host->ioaddr + ESDHC_TUNING_CTRL) |
1040+
ESDHC_STD_TUNING_EN | ESDHC_TUNING_START_TAP,
1041+
host->ioaddr + ESDHC_TUNING_CTRL);
1042+
10411043
boarddata = &imx_data->boarddata;
10421044
if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
10431045
if (!host->mmc->parent->platform_data) {

0 commit comments

Comments
 (0)