Skip to content

Commit 6888e68

Browse files
Andy-ld Lugregkh
authored andcommitted
mmc: mtk-sd: Fix register settings for hs400(es) mode
commit 3e68abf upstream. For hs400(es) mode, the 'hs400-ds-delay' is typically configured in the dts. However, some projects may only define 'mediatek,hs400-ds-dly3', which can lead to initialization failures in hs400es mode. CMD13 reported response crc error in the mmc_switch_status() just after switching to hs400es mode. [ 1.914038][ T82] mmc0: mmc_select_hs400es failed, error -84 [ 1.914954][ T82] mmc0: error -84 whilst initialising MMC card Currently, the hs400_ds_dly3 value is set within the tuning function. This means that the PAD_DS_DLY3 field is not configured before tuning process, which is the reason for the above-mentioned CMD13 response crc error. Move the PAD_DS_DLY3 field configuration into msdc_prepare_hs400_tuning(), and add a value check of hs400_ds_delay to prevent overwriting by zero when the 'hs400-ds-delay' is not set in the dts. In addition, since hs400(es) only tune the PAD_DS_DLY1, the PAD_DS_DLY2_SEL bit should be cleared to bypass it. Fixes: c4ac38c ("mmc: mtk-sd: Add HS400 online tuning support") Signed-off-by: Andy-ld Lu <[email protected]> Reviewed-by: AngeloGioacchino Del Regno <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ulf Hansson <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 4e5a36a commit 6888e68

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

drivers/mmc/host/mtk-sd.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@
262262
#define MSDC_PAD_TUNE_CMD_SEL BIT(21) /* RW */
263263

264264
#define PAD_DS_TUNE_DLY_SEL BIT(0) /* RW */
265+
#define PAD_DS_TUNE_DLY2_SEL BIT(1) /* RW */
265266
#define PAD_DS_TUNE_DLY1 GENMASK(6, 2) /* RW */
266267
#define PAD_DS_TUNE_DLY2 GENMASK(11, 7) /* RW */
267268
#define PAD_DS_TUNE_DLY3 GENMASK(16, 12) /* RW */
@@ -307,6 +308,7 @@
307308

308309
/* EMMC50_PAD_DS_TUNE mask */
309310
#define PAD_DS_DLY_SEL BIT(16) /* RW */
311+
#define PAD_DS_DLY2_SEL BIT(15) /* RW */
310312
#define PAD_DS_DLY1 GENMASK(14, 10) /* RW */
311313
#define PAD_DS_DLY3 GENMASK(4, 0) /* RW */
312314

@@ -2293,13 +2295,23 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
22932295
static int msdc_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios)
22942296
{
22952297
struct msdc_host *host = mmc_priv(mmc);
2298+
22962299
host->hs400_mode = true;
22972300

2298-
if (host->top_base)
2299-
writel(host->hs400_ds_delay,
2300-
host->top_base + EMMC50_PAD_DS_TUNE);
2301-
else
2302-
writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
2301+
if (host->top_base) {
2302+
if (host->hs400_ds_dly3)
2303+
sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE,
2304+
PAD_DS_DLY3, host->hs400_ds_dly3);
2305+
if (host->hs400_ds_delay)
2306+
writel(host->hs400_ds_delay,
2307+
host->top_base + EMMC50_PAD_DS_TUNE);
2308+
} else {
2309+
if (host->hs400_ds_dly3)
2310+
sdr_set_field(host->base + PAD_DS_TUNE,
2311+
PAD_DS_TUNE_DLY3, host->hs400_ds_dly3);
2312+
if (host->hs400_ds_delay)
2313+
writel(host->hs400_ds_delay, host->base + PAD_DS_TUNE);
2314+
}
23032315
/* hs400 mode must set it to 0 */
23042316
sdr_clr_bits(host->base + MSDC_PATCH_BIT2, MSDC_PATCH_BIT2_CFGCRCSTS);
23052317
/* to improve read performance, set outstanding to 2 */
@@ -2319,14 +2331,11 @@ static int msdc_execute_hs400_tuning(struct mmc_host *mmc, struct mmc_card *card
23192331
if (host->top_base) {
23202332
sdr_set_bits(host->top_base + EMMC50_PAD_DS_TUNE,
23212333
PAD_DS_DLY_SEL);
2322-
if (host->hs400_ds_dly3)
2323-
sdr_set_field(host->top_base + EMMC50_PAD_DS_TUNE,
2324-
PAD_DS_DLY3, host->hs400_ds_dly3);
2334+
sdr_clr_bits(host->top_base + EMMC50_PAD_DS_TUNE,
2335+
PAD_DS_DLY2_SEL);
23252336
} else {
23262337
sdr_set_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY_SEL);
2327-
if (host->hs400_ds_dly3)
2328-
sdr_set_field(host->base + PAD_DS_TUNE,
2329-
PAD_DS_TUNE_DLY3, host->hs400_ds_dly3);
2338+
sdr_clr_bits(host->base + PAD_DS_TUNE, PAD_DS_TUNE_DLY2_SEL);
23302339
}
23312340

23322341
host->hs400_tuning = true;

0 commit comments

Comments
 (0)