Commit 556cfdee9db3857db723e1b961d3acdb1db7a6a4

Authored by Peng Fan
Committed by Ye Li
1 parent a5bb0b38e6

MLK-18149-1 mmc: add HS400 support

Add HS400 support.
Selecting HS400 needs first select HS199 according to spec, so use
a dedicated function for HS400.
Add HS400 related macros.
Remove the restriction of only using the low 6 bits of
EXT_CSD_CARD_TYPE, using all the 8 bits.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Jean-Jacques Hiblot <jjhiblot@ti.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Simon Glass <sjg@chromium.org>
Cc: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Bin Meng <bmeng.cn@gmail.com>

Showing 3 changed files with 127 additions and 25 deletions Side-by-side Diff

... ... @@ -104,6 +104,13 @@
104 104 cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus
105 105 frequency can go up to 208MHz (SDR104)
106 106  
  107 +config MMC_HS400_SUPPORT
  108 + bool "enable HS400 support"
  109 + select MMC_HS200_SUPPORT
  110 + help
  111 + The HS400 mode is support by some eMMC. The bus frequency is up to
  112 + 200MHz. This mode requires tuning the IO.
  113 +
107 114 config MMC_HS200_SUPPORT
108 115 bool "enable HS200 support"
109 116 help
... ... @@ -169,6 +169,7 @@
169 169 [MMC_HS_52] = "MMC High Speed (52MHz)",
170 170 [MMC_DDR_52] = "MMC DDR52 (52MHz)",
171 171 [MMC_HS_200] = "HS200 (200MHz)",
  172 + [MMC_HS_400] = "HS400 (200MHz)",
172 173 };
173 174  
174 175 if (mode >= MMC_MODES_END)
... ... @@ -193,6 +194,7 @@
193 194 [UHS_DDR50] = 50000000,
194 195 [UHS_SDR104] = 208000000,
195 196 [MMC_HS_200] = 200000000,
  197 + [MMC_HS_400] = 200000000,
196 198 };
197 199  
198 200 if (mode == MMC_LEGACY)
... ... @@ -791,6 +793,11 @@
791 793 speed_bits = EXT_CSD_TIMING_HS200;
792 794 break;
793 795 #endif
  796 +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
  797 + case MMC_HS_400:
  798 + speed_bits = EXT_CSD_TIMING_HS400;
  799 + break;
  800 +#endif
794 801 case MMC_LEGACY:
795 802 speed_bits = EXT_CSD_TIMING_LEGACY;
796 803 break;
... ... @@ -837,7 +844,7 @@
837 844  
838 845 mmc->card_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
839 846  
840   - cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x3f;
  847 + cardtype = ext_csd[EXT_CSD_CARD_TYPE];
841 848 mmc->cardtype = cardtype;
842 849  
843 850 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
... ... @@ -846,6 +853,12 @@
846 853 mmc->card_caps |= MMC_MODE_HS200;
847 854 }
848 855 #endif
  856 +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
  857 + if (cardtype & (EXT_CSD_CARD_TYPE_HS400_1_2V |
  858 + EXT_CSD_CARD_TYPE_HS400_1_8V)) {
  859 + mmc->card_caps |= MMC_MODE_HS400;
  860 + }
  861 +#endif
849 862 if (cardtype & EXT_CSD_CARD_TYPE_52) {
850 863 if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
851 864 mmc->card_caps |= MMC_MODE_DDR_52MHz;
... ... @@ -1748,6 +1761,12 @@
1748 1761 u32 card_mask = 0;
1749 1762  
1750 1763 switch (mode) {
  1764 + case MMC_HS_400:
  1765 + if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS400_1_8V)
  1766 + card_mask |= MMC_SIGNAL_VOLTAGE_180;
  1767 + if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS400_1_2V)
  1768 + card_mask |= MMC_SIGNAL_VOLTAGE_120;
  1769 + break;
1751 1770 case MMC_HS_200:
1752 1771 if (mmc->cardtype & EXT_CSD_CARD_TYPE_HS200_1_8V)
1753 1772 card_mask |= MMC_SIGNAL_VOLTAGE_180;
... ... @@ -1787,6 +1806,13 @@
1787 1806 #endif
1788 1807  
1789 1808 static const struct mode_width_tuning mmc_modes_by_pref[] = {
  1809 +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
  1810 + {
  1811 + .mode = MMC_HS_400,
  1812 + .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
  1813 + .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
  1814 + },
  1815 +#endif
1790 1816 #if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
1791 1817 {
1792 1818 .mode = MMC_HS_200,
... ... @@ -1830,6 +1856,54 @@
1830 1856 {MMC_MODE_1BIT, false, EXT_CSD_BUS_WIDTH_1},
1831 1857 };
1832 1858  
  1859 +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
  1860 +static int mmc_select_hs400(struct mmc *mmc)
  1861 +{
  1862 + int err;
  1863 +
  1864 + /* Set timing to HS200 for tuning */
  1865 + err = mmc_set_card_speed(mmc, MMC_HS_200);
  1866 + if (err)
  1867 + return err;
  1868 +
  1869 + /* configure the bus mode (host) */
  1870 + mmc_select_mode(mmc, MMC_HS_200);
  1871 + mmc_set_clock(mmc, mmc->tran_speed, false);
  1872 +
  1873 + /* execute tuning if needed */
  1874 + err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
  1875 + if (err) {
  1876 + debug("tuning failed\n");
  1877 + return err;
  1878 + }
  1879 +
  1880 + /* Set back to HS */
  1881 + mmc_set_card_speed(mmc, MMC_HS);
  1882 + mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
  1883 +
  1884 + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
  1885 + EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_FLAG);
  1886 + if (err)
  1887 + return err;
  1888 +
  1889 + err = mmc_set_card_speed(mmc, MMC_HS_400);
  1890 + if (err)
  1891 + return err;
  1892 +
  1893 + mmc_select_mode(mmc, MMC_HS_400);
  1894 + err = mmc_set_clock(mmc, mmc->tran_speed, false);
  1895 + if (err)
  1896 + return err;
  1897 +
  1898 + return 0;
  1899 +}
  1900 +#else
  1901 +static int mmc_select_hs400(struct mmc *mmc)
  1902 +{
  1903 + return -ENOTSUPP;
  1904 +}
  1905 +#endif
  1906 +
1833 1907 #define for_each_supported_width(caps, ddr, ecbv) \
1834 1908 for (ecbv = ext_csd_bus_width;\
1835 1909 ecbv < ext_csd_bus_width + ARRAY_SIZE(ext_csd_bus_width);\
1836 1910  
1837 1911  
1838 1912  
1839 1913  
1840 1914  
... ... @@ -1883,37 +1957,46 @@
1883 1957 goto error;
1884 1958 mmc_set_bus_width(mmc, bus_width(ecbw->cap));
1885 1959  
1886   - /* configure the bus speed (card) */
1887   - err = mmc_set_card_speed(mmc, mwt->mode);
1888   - if (err)
1889   - goto error;
1890   -
1891   - /*
1892   - * configure the bus width AND the ddr mode (card)
1893   - * The host side will be taken care of in the next step
1894   - */
1895   - if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
1896   - err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
1897   - EXT_CSD_BUS_WIDTH,
1898   - ecbw->ext_csd_bits);
  1960 + if (mwt->mode == MMC_HS_400) {
  1961 + err = mmc_select_hs400(mmc);
1899 1962 if (err)
1900 1963 goto error;
1901   - }
  1964 + } else {
  1965 + /* configure the bus speed (card) */
  1966 + err = mmc_set_card_speed(mmc, mwt->mode);
  1967 + if (err)
  1968 + goto error;
1902 1969  
1903   - /* configure the bus mode (host) */
1904   - mmc_select_mode(mmc, mwt->mode);
1905   - mmc_set_clock(mmc, mmc->tran_speed, false);
  1970 + /*
  1971 + * configure the bus width AND the ddr mode
  1972 + * (card). The host side will be taken care
  1973 + * of in the next step
  1974 + */
  1975 + if (ecbw->ext_csd_bits & EXT_CSD_DDR_FLAG) {
  1976 + err = mmc_switch(mmc,
  1977 + EXT_CSD_CMD_SET_NORMAL,
  1978 + EXT_CSD_BUS_WIDTH,
  1979 + ecbw->ext_csd_bits);
  1980 + if (err)
  1981 + goto error;
  1982 + }
  1983 +
  1984 + /* configure the bus mode (host) */
  1985 + mmc_select_mode(mmc, mwt->mode);
  1986 + mmc_set_clock(mmc, mmc->tran_speed, false);
1906 1987 #ifdef MMC_SUPPORTS_TUNING
1907 1988  
1908   - /* execute tuning if needed */
1909   - if (mwt->tuning) {
1910   - err = mmc_execute_tuning(mmc, mwt->tuning);
1911   - if (err) {
1912   - pr_debug("tuning failed\n");
1913   - goto error;
  1989 + /* execute tuning if needed */
  1990 + if (mwt->tuning) {
  1991 + err = mmc_execute_tuning(mmc,
  1992 + mwt->tuning);
  1993 + if (err) {
  1994 + pr_debug("tuning failed\n");
  1995 + goto error;
  1996 + }
1914 1997 }
1915   - }
1916 1998 #endif
  1999 + }
1917 2000  
1918 2001 /* do a transfer to check the configuration */
1919 2002 err = mmc_read_and_compare_ext_csd(mmc);
... ... @@ -65,6 +65,7 @@
65 65 #define MMC_MODE_HS_52MHz MMC_CAP(MMC_HS_52)
66 66 #define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52)
67 67 #define MMC_MODE_HS200 MMC_CAP(MMC_HS_200)
  68 +#define MMC_MODE_HS400 MMC_CAP(MMC_HS_400)
68 69  
69 70 #define MMC_MODE_8BIT BIT(30)
70 71 #define MMC_MODE_4BIT BIT(29)
... ... @@ -250,6 +251,11 @@
250 251 #define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
251 252 EXT_CSD_CARD_TYPE_HS200_1_2V)
252 253  
  254 +#define EXT_CSD_CARD_TYPE_HS400_1_8V BIT(6)
  255 +#define EXT_CSD_CARD_TYPE_HS400_1_2V BIT(7)
  256 +#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
  257 + EXT_CSD_CARD_TYPE_HS400_1_2V)
  258 +
253 259 #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
254 260 #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
255 261 #define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
... ... @@ -260,6 +266,7 @@
260 266 #define EXT_CSD_TIMING_LEGACY 0 /* no high speed */
261 267 #define EXT_CSD_TIMING_HS 1 /* HS */
262 268 #define EXT_CSD_TIMING_HS200 2 /* HS200 */
  269 +#define EXT_CSD_TIMING_HS400 3 /* HS400 */
263 270  
264 271 #define EXT_CSD_BOOT_ACK_ENABLE (1 << 6)
265 272 #define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3)
... ... @@ -520,6 +527,7 @@
520 527 UHS_DDR50,
521 528 UHS_SDR104,
522 529 MMC_HS_200,
  530 + MMC_HS_400,
523 531 MMC_MODES_END
524 532 };
525 533  
... ... @@ -532,6 +540,10 @@
532 540 return true;
533 541 #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
534 542 else if (mode == UHS_DDR50)
  543 + return true;
  544 +#endif
  545 +#if CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
  546 + else if (mode == MMC_HS_400)
535 547 return true;
536 548 #endif
537 549 else