Skip to content

Commit 541a95e

Browse files
Haibo Chenstorulf
authored andcommitted
mmc: sdhci-esdhc-imx: optimize the manual tuing logic to get the best timing
Current manual tuning logic only get the first pass window, but this pass window maybe not the best pass window. Now find all the pass window, and chose the largest pass window, and use the average value of this largest pass window to get the best timing. Signed-off-by: Haibo Chen <haibo.chen@nxp.com> Acked-by: Adrian Hunter <adrian.hunter@intel.com> Link: https://lore.kernel.org/r/20230831032647.3128702-1-haibo.chen@nxp.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
1 parent a5b5006 commit 541a95e

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

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

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,32 +1154,52 @@ static void esdhc_post_tuning(struct sdhci_host *host)
11541154
writel(reg, host->ioaddr + ESDHC_MIX_CTRL);
11551155
}
11561156

1157+
/*
1158+
* find the largest pass window, and use the average delay of this
1159+
* largest window to get the best timing.
1160+
*/
11571161
static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
11581162
{
11591163
int min, max, avg, ret;
1164+
int win_length, target_min, target_max, target_win_length;
11601165

1161-
/* find the mininum delay first which can pass tuning */
11621166
min = ESDHC_TUNE_CTRL_MIN;
1163-
while (min < ESDHC_TUNE_CTRL_MAX) {
1164-
esdhc_prepare_tuning(host, min);
1165-
if (!mmc_send_tuning(host->mmc, opcode, NULL))
1166-
break;
1167-
min += ESDHC_TUNE_CTRL_STEP;
1168-
}
1169-
1170-
/* find the maxinum delay which can not pass tuning */
1171-
max = min + ESDHC_TUNE_CTRL_STEP;
1167+
max = ESDHC_TUNE_CTRL_MIN;
1168+
target_win_length = 0;
11721169
while (max < ESDHC_TUNE_CTRL_MAX) {
1173-
esdhc_prepare_tuning(host, max);
1174-
if (mmc_send_tuning(host->mmc, opcode, NULL)) {
1175-
max -= ESDHC_TUNE_CTRL_STEP;
1176-
break;
1170+
/* find the mininum delay first which can pass tuning */
1171+
while (min < ESDHC_TUNE_CTRL_MAX) {
1172+
esdhc_prepare_tuning(host, min);
1173+
if (!mmc_send_tuning(host->mmc, opcode, NULL))
1174+
break;
1175+
min += ESDHC_TUNE_CTRL_STEP;
11771176
}
1178-
max += ESDHC_TUNE_CTRL_STEP;
1177+
1178+
/* find the maxinum delay which can not pass tuning */
1179+
max = min + ESDHC_TUNE_CTRL_STEP;
1180+
while (max < ESDHC_TUNE_CTRL_MAX) {
1181+
esdhc_prepare_tuning(host, max);
1182+
if (mmc_send_tuning(host->mmc, opcode, NULL)) {
1183+
max -= ESDHC_TUNE_CTRL_STEP;
1184+
break;
1185+
}
1186+
max += ESDHC_TUNE_CTRL_STEP;
1187+
}
1188+
1189+
win_length = max - min + 1;
1190+
/* get the largest pass window */
1191+
if (win_length > target_win_length) {
1192+
target_win_length = win_length;
1193+
target_min = min;
1194+
target_max = max;
1195+
}
1196+
1197+
/* continue to find the next pass window */
1198+
min = max + ESDHC_TUNE_CTRL_STEP;
11791199
}
11801200

11811201
/* use average delay to get the best timing */
1182-
avg = (min + max) / 2;
1202+
avg = (target_min + target_max) / 2;
11831203
esdhc_prepare_tuning(host, avg);
11841204
ret = mmc_send_tuning(host->mmc, opcode, NULL);
11851205
esdhc_post_tuning(host);

0 commit comments

Comments
 (0)