|
94 | 94 |
|
95 | 95 | #define ESDHC_VEND_SPEC2 0xc8
|
96 | 96 | #define ESDHC_VEND_SPEC2_EN_BUSY_IRQ (1 << 8)
|
| 97 | +#define ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN (1 << 4) |
| 98 | +#define ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN (0 << 4) |
| 99 | +#define ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN (2 << 4) |
| 100 | +#define ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN (1 << 6) |
| 101 | +#define ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK (7 << 4) |
97 | 102 |
|
98 | 103 | #define ESDHC_TUNING_CTRL 0xcc
|
99 | 104 | #define ESDHC_STD_TUNING_EN (1 << 24)
|
|
114 | 119 | #define ESDHC_CTRL_4BITBUS (0x1 << 1)
|
115 | 120 | #define ESDHC_CTRL_8BITBUS (0x2 << 1)
|
116 | 121 | #define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
|
| 122 | +#define USDHC_GET_BUSWIDTH(c) (c & ESDHC_CTRL_BUSWIDTH_MASK) |
117 | 123 |
|
118 | 124 | /*
|
119 | 125 | * There is an INT DMA ERR mismatch between eSDHC and STD SDHC SPEC:
|
@@ -407,6 +413,30 @@ static inline void esdhc_wait_for_card_clock_gate_off(struct sdhci_host *host)
|
407 | 413 | dev_warn(mmc_dev(host->mmc), "%s: card clock still not gate off in 100us!.\n", __func__);
|
408 | 414 | }
|
409 | 415 |
|
| 416 | +/* Enable the auto tuning circuit to check the CMD line and BUS line */ |
| 417 | +static inline void usdhc_auto_tuning_mode_sel(struct sdhci_host *host) |
| 418 | +{ |
| 419 | + u32 buswidth, auto_tune_buswidth; |
| 420 | + |
| 421 | + buswidth = USDHC_GET_BUSWIDTH(readl(host->ioaddr + SDHCI_HOST_CONTROL)); |
| 422 | + |
| 423 | + switch (buswidth) { |
| 424 | + case ESDHC_CTRL_8BITBUS: |
| 425 | + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_8BIT_EN; |
| 426 | + break; |
| 427 | + case ESDHC_CTRL_4BITBUS: |
| 428 | + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_4BIT_EN; |
| 429 | + break; |
| 430 | + default: /* 1BITBUS */ |
| 431 | + auto_tune_buswidth = ESDHC_VEND_SPEC2_AUTO_TUNE_1BIT_EN; |
| 432 | + break; |
| 433 | + } |
| 434 | + |
| 435 | + esdhc_clrset_le(host, ESDHC_VEND_SPEC2_AUTO_TUNE_MODE_MASK, |
| 436 | + auto_tune_buswidth | ESDHC_VEND_SPEC2_AUTO_TUNE_CMD_EN, |
| 437 | + ESDHC_VEND_SPEC2); |
| 438 | +} |
| 439 | + |
410 | 440 | static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
|
411 | 441 | {
|
412 | 442 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
@@ -643,6 +673,7 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
|
643 | 673 | v |= ESDHC_MIX_CTRL_EXE_TUNE;
|
644 | 674 | m |= ESDHC_MIX_CTRL_FBCLK_SEL;
|
645 | 675 | m |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
|
| 676 | + usdhc_auto_tuning_mode_sel(host); |
646 | 677 | } else {
|
647 | 678 | v &= ~ESDHC_MIX_CTRL_EXE_TUNE;
|
648 | 679 | }
|
@@ -1012,6 +1043,8 @@ static void esdhc_post_tuning(struct sdhci_host *host)
|
1012 | 1043 | {
|
1013 | 1044 | u32 reg;
|
1014 | 1045 |
|
| 1046 | + usdhc_auto_tuning_mode_sel(host); |
| 1047 | + |
1015 | 1048 | reg = readl(host->ioaddr + ESDHC_MIX_CTRL);
|
1016 | 1049 | reg &= ~ESDHC_MIX_CTRL_EXE_TUNE;
|
1017 | 1050 | reg |= ESDHC_MIX_CTRL_AUTO_TUNE_EN;
|
|
0 commit comments