Commit 556cfdee9db3857db723e1b961d3acdb1db7a6a4
Committed by
Ye Li
1 parent
a5bb0b38e6
Exists in
smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga
and in
5 other branches
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
drivers/mmc/Kconfig
... | ... | @@ -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 |
drivers/mmc/mmc.c
... | ... | @@ -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); |
include/mmc.h
... | ... | @@ -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 |