Skip to content

Commit 47e9e10

Browse files
yangbolu1991storulf
authored andcommitted
mmc: sdhci-of-esdhc: exit HS400 properly before setting any speed mode
The eSDHC HS400 timing requires many specific registers setting, unlike other speed modes which need to set only host controller 2 register. When driver needs to downgrade HS400 mode to other speed mode, the controller have to exit HS400 timing properly first. This patch is to support the procedure of HS400 exiting at the beginning of esdhc_set_uhs_signaling. Signed-off-by: Yangbo Lu <[email protected]> Acked-by: Adrian Hunter <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]>
1 parent 16d18d8 commit 47e9e10

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,40 @@ static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
11351135
static void esdhc_set_uhs_signaling(struct sdhci_host *host,
11361136
unsigned int timing)
11371137
{
1138+
u32 val;
1139+
1140+
/*
1141+
* There are specific registers setting for HS400 mode.
1142+
* Clean all of them if controller is in HS400 mode to
1143+
* exit HS400 mode before re-setting any speed mode.
1144+
*/
1145+
val = sdhci_readl(host, ESDHC_TBCTL);
1146+
if (val & ESDHC_HS400_MODE) {
1147+
val = sdhci_readl(host, ESDHC_SDTIMNGCTL);
1148+
val &= ~ESDHC_FLW_CTL_BG;
1149+
sdhci_writel(host, val, ESDHC_SDTIMNGCTL);
1150+
1151+
val = sdhci_readl(host, ESDHC_SDCLKCTL);
1152+
val &= ~ESDHC_CMD_CLK_CTL;
1153+
sdhci_writel(host, val, ESDHC_SDCLKCTL);
1154+
1155+
esdhc_clock_enable(host, false);
1156+
val = sdhci_readl(host, ESDHC_TBCTL);
1157+
val &= ~ESDHC_HS400_MODE;
1158+
sdhci_writel(host, val, ESDHC_TBCTL);
1159+
esdhc_clock_enable(host, true);
1160+
1161+
val = sdhci_readl(host, ESDHC_DLLCFG0);
1162+
val &= ~(ESDHC_DLL_ENABLE | ESDHC_DLL_FREQ_SEL);
1163+
sdhci_writel(host, val, ESDHC_DLLCFG0);
1164+
1165+
val = sdhci_readl(host, ESDHC_TBCTL);
1166+
val &= ~ESDHC_HS400_WNDW_ADJUST;
1167+
sdhci_writel(host, val, ESDHC_TBCTL);
1168+
1169+
esdhc_tuning_block_enable(host, false);
1170+
}
1171+
11381172
if (timing == MMC_TIMING_MMC_HS400)
11391173
esdhc_tuning_block_enable(host, true);
11401174
else

0 commit comments

Comments
 (0)