Commit f99c2efe5672d7355a632dcae3551ffadea1163a

Authored by Jean-Jacques Hiblot
Committed by Jaehoon Chung
1 parent d8e3d42089

mmc: make UHS and HS200 optional

Supporting USH and HS200 increases the code size as it brings in IO voltage
control, tuning and fatter data structures.
Use Kconfig configuration to select which of those features should be
built in.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>

Showing 4 changed files with 135 additions and 5 deletions Side-by-side Diff

... ... @@ -51,6 +51,52 @@
51 51 are enabled by default, other may require additionnal flags or are
52 52 enabled by the host driver.
53 53  
  54 +config MMC_IO_VOLTAGE
  55 + bool "Support IO voltage configuration"
  56 + help
  57 + IO voltage configuration allows selecting the voltage level of the IO
  58 + lines (not the level of main supply). This is required for UHS
  59 + support. For eMMC this not mandatory, but not enabling this option may
  60 + prevent the driver of using the faster modes.
  61 +
  62 +config SPL_MMC_IO_VOLTAGE
  63 + bool "Support IO voltage configuration in SPL"
  64 + default n
  65 + help
  66 + IO voltage configuration allows selecting the voltage level of the IO
  67 + lines (not the level of main supply). This is required for UHS
  68 + support. For eMMC this not mandatory, but not enabling this option may
  69 + prevent the driver of using the faster modes.
  70 +
  71 +config MMC_UHS_SUPPORT
  72 + bool "enable UHS support"
  73 + depends on MMC_IO_VOLTAGE
  74 + help
  75 + The Ultra High Speed (UHS) bus is available on some SDHC and SDXC
  76 + cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus
  77 + frequency can go up to 208MHz (SDR104)
  78 +
  79 +config SPL_MMC_UHS_SUPPORT
  80 + bool "enable UHS support in SPL"
  81 + depends on SPL_MMC_IO_VOLTAGE
  82 + help
  83 + The Ultra High Speed (UHS) bus is available on some SDHC and SDXC
  84 + cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus
  85 + frequency can go up to 208MHz (SDR104)
  86 +
  87 +config MMC_HS200_SUPPORT
  88 + bool "enable HS200 support"
  89 + help
  90 + The HS200 mode is support by some eMMC. The bus frequency is up to
  91 + 200MHz. This mode requires tuning the IO.
  92 +
  93 +
  94 +config SPL_MMC_HS200_SUPPORT
  95 + bool "enable HS200 support in SPL"
  96 + help
  97 + The HS200 mode is support by some eMMC. The bus frequency is up to
  98 + 200MHz. This mode requires tuning the IO.
  99 +
54 100 config MMC_VERBOSE
55 101 bool "Output more information about the MMC"
56 102 default y
drivers/mmc/mmc-uclass.c
... ... @@ -63,6 +63,7 @@
63 63 dm_mmc_send_init_stream(mmc->dev);
64 64 }
65 65  
  66 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
66 67 int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout)
67 68 {
68 69 struct dm_mmc_ops *ops = mmc_get_ops(dev);
... ... @@ -76,6 +77,7 @@
76 77 {
77 78 return dm_mmc_wait_dat0(mmc->dev, state, timeout);
78 79 }
  80 +#endif
79 81  
80 82 int dm_mmc_get_wp(struct udevice *dev)
81 83 {
... ... @@ -105,6 +107,7 @@
105 107 return dm_mmc_get_cd(mmc->dev);
106 108 }
107 109  
  110 +#ifdef MMC_SUPPORTS_TUNING
108 111 int dm_mmc_execute_tuning(struct udevice *dev, uint opcode)
109 112 {
110 113 struct dm_mmc_ops *ops = mmc_get_ops(dev);
... ... @@ -118,6 +121,7 @@
118 121 {
119 122 return dm_mmc_execute_tuning(mmc->dev, opcode);
120 123 }
  124 +#endif
121 125  
122 126 int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
123 127 {
... ... @@ -59,10 +59,12 @@
59 59  
60 60 #if !CONFIG_IS_ENABLED(DM_MMC)
61 61  
  62 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
62 63 static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
63 64 {
64 65 return -ENOSYS;
65 66 }
  67 +#endif
66 68  
67 69 __weak int board_mmc_getwp(struct mmc *mmc)
68 70 {
69 71  
70 72  
71 73  
72 74  
... ... @@ -190,14 +192,20 @@
190 192 [SD_LEGACY] = 25000000,
191 193 [MMC_HS] = 26000000,
192 194 [SD_HS] = 50000000,
  195 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
193 196 [UHS_SDR12] = 25000000,
194 197 [UHS_SDR25] = 50000000,
195 198 [UHS_SDR50] = 100000000,
196   - [UHS_SDR104] = 208000000,
197 199 [UHS_DDR50] = 50000000,
  200 +#ifdef MMC_SUPPORTS_TUNING
  201 + [UHS_SDR104] = 208000000,
  202 +#endif
  203 +#endif
198 204 [MMC_HS_52] = 52000000,
199 205 [MMC_DDR_52] = 52000000,
  206 +#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
200 207 [MMC_HS_200] = 200000000,
  208 +#endif
201 209 };
202 210  
203 211 if (mode == MMC_LEGACY)
... ... @@ -308,6 +316,7 @@
308 316 return err;
309 317 }
310 318  
  319 +#ifdef MMC_SUPPORTS_TUNING
311 320 static const u8 tuning_blk_pattern_4bit[] = {
312 321 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
313 322 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
... ... @@ -375,6 +384,7 @@
375 384  
376 385 return 0;
377 386 }
  387 +#endif
378 388  
379 389 static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
380 390 lbaint_t blkcnt)
... ... @@ -495,6 +505,7 @@
495 505 return 0;
496 506 }
497 507  
  508 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
498 509 static int mmc_switch_voltage(struct mmc *mmc, int signal_voltage)
499 510 {
500 511 struct mmc_cmd cmd;
... ... @@ -554,6 +565,7 @@
554 565  
555 566 return 0;
556 567 }
  568 +#endif
557 569  
558 570 static int sd_send_op_cond(struct mmc *mmc, bool uhs_en)
559 571 {
560 572  
... ... @@ -620,12 +632,14 @@
620 632  
621 633 mmc->ocr = cmd.response[0];
622 634  
  635 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
623 636 if (uhs_en && !(mmc_host_is_spi(mmc)) && (cmd.response[0] & 0x41000000)
624 637 == 0x41000000) {
625 638 err = mmc_switch_voltage(mmc, MMC_SIGNAL_VOLTAGE_180);
626 639 if (err)
627 640 return err;
628 641 }
  642 +#endif
629 643  
630 644 mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
631 645 mmc->rca = 0;
... ... @@ -880,6 +894,7 @@
880 894 return 0;
881 895 }
882 896  
  897 +#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
883 898 static int mmc_boot_part_access_chk(struct mmc *mmc, unsigned int part_num)
884 899 {
885 900 int forbidden = 0;
... ... @@ -903,6 +918,13 @@
903 918  
904 919 return 0;
905 920 }
  921 +#else
  922 +static inline int mmc_boot_part_access_chk(struct mmc *mmc,
  923 + unsigned int part_num)
  924 +{
  925 + return 0;
  926 +}
  927 +#endif
906 928  
907 929 int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
908 930 {
909 931  
... ... @@ -1169,7 +1191,9 @@
1169 1191 ALLOC_CACHE_ALIGN_BUFFER(__be32, switch_status, 16);
1170 1192 struct mmc_data data;
1171 1193 int timeout;
  1194 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1172 1195 u32 sd3_bus_mode;
  1196 +#endif
1173 1197  
1174 1198 mmc->card_caps = MMC_MODE_1BIT | MMC_CAP(SD_LEGACY);
1175 1199  
... ... @@ -1251,6 +1275,7 @@
1251 1275 if (__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED)
1252 1276 mmc->card_caps |= MMC_CAP(SD_HS);
1253 1277  
  1278 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1254 1279 /* Version before 3.0 don't support UHS modes */
1255 1280 if (mmc->version < SD_VERSION_3)
1256 1281 return 0;
... ... @@ -1266,6 +1291,7 @@
1266 1291 mmc->card_caps |= MMC_CAP(UHS_SDR12);
1267 1292 if (sd3_bus_mode & SD_MODE_UHS_DDR50)
1268 1293 mmc->card_caps |= MMC_CAP(UHS_DDR50);
  1294 +#endif
1269 1295  
1270 1296 return 0;
1271 1297 }
1272 1298  
... ... @@ -1438,10 +1464,12 @@
1438 1464 }
1439 1465  
1440 1466 #if !CONFIG_IS_ENABLED(DM_MMC)
  1467 +#ifdef MMC_SUPPORTS_TUNING
1441 1468 static int mmc_execute_tuning(struct mmc *mmc, uint opcode)
1442 1469 {
1443 1470 return -ENOTSUPP;
1444 1471 }
  1472 +#endif
1445 1473  
1446 1474 static void mmc_send_init_stream(struct mmc *mmc)
1447 1475 {
1448 1476  
1449 1477  
... ... @@ -1507,9 +1535,12 @@
1507 1535 struct mode_width_tuning {
1508 1536 enum bus_mode mode;
1509 1537 uint widths;
  1538 +#ifdef MMC_SUPPORTS_TUNING
1510 1539 uint tuning;
  1540 +#endif
1511 1541 };
1512 1542  
  1543 +#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
1513 1544 int mmc_voltage_to_mv(enum mmc_voltage voltage)
1514 1545 {
1515 1546 switch (voltage) {
1516 1547  
1517 1548  
... ... @@ -1535,13 +1566,22 @@
1535 1566  
1536 1567 return err;
1537 1568 }
  1569 +#else
  1570 +static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage)
  1571 +{
  1572 + return 0;
  1573 +}
  1574 +#endif
1538 1575  
1539 1576 static const struct mode_width_tuning sd_modes_by_pref[] = {
  1577 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
  1578 +#ifdef MMC_SUPPORTS_TUNING
1540 1579 {
1541 1580 .mode = UHS_SDR104,
1542 1581 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1543 1582 .tuning = MMC_CMD_SEND_TUNING_BLOCK
1544 1583 },
  1584 +#endif
1545 1585 {
1546 1586 .mode = UHS_SDR50,
1547 1587 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1548 1588  
1549 1589  
... ... @@ -1554,14 +1594,17 @@
1554 1594 .mode = UHS_SDR25,
1555 1595 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1556 1596 },
  1597 +#endif
1557 1598 {
1558 1599 .mode = SD_HS,
1559 1600 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1560 1601 },
  1602 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1561 1603 {
1562 1604 .mode = UHS_SDR12,
1563 1605 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1564 1606 },
  1607 +#endif
1565 1608 {
1566 1609 .mode = SD_LEGACY,
1567 1610 .widths = MMC_MODE_4BIT | MMC_MODE_1BIT,
1568 1611  
... ... @@ -1579,7 +1622,11 @@
1579 1622 int err;
1580 1623 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1581 1624 const struct mode_width_tuning *mwt;
  1625 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
1582 1626 bool uhs_en = (mmc->ocr & OCR_S18R) ? true : false;
  1627 +#else
  1628 + bool uhs_en = false;
  1629 +#endif
1583 1630 uint caps;
1584 1631  
1585 1632 #ifdef DEBUG
... ... @@ -1618,6 +1665,7 @@
1618 1665 mmc_select_mode(mmc, mwt->mode);
1619 1666 mmc_set_clock(mmc, mmc->tran_speed, false);
1620 1667  
  1668 +#ifdef MMC_SUPPORTS_TUNING
1621 1669 /* execute tuning if needed */
1622 1670 if (mwt->tuning && !mmc_host_is_spi(mmc)) {
1623 1671 err = mmc_execute_tuning(mmc,
... ... @@ -1627,6 +1675,7 @@
1627 1675 goto error;
1628 1676 }
1629 1677 }
  1678 +#endif
1630 1679  
1631 1680 err = sd_read_ssr(mmc);
1632 1681 if (!err)
... ... @@ -1680,6 +1729,7 @@
1680 1729 return -EBADMSG;
1681 1730 }
1682 1731  
  1732 +#if CONFIG_IS_ENABLED(MMC_IO_VOLTAGE)
1683 1733 static int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
1684 1734 uint32_t allowed_mask)
1685 1735 {
1686 1736  
1687 1737  
... ... @@ -1716,13 +1766,22 @@
1716 1766  
1717 1767 return -ENOTSUPP;
1718 1768 }
  1769 +#else
  1770 +static inline int mmc_set_lowest_voltage(struct mmc *mmc, enum bus_mode mode,
  1771 + uint32_t allowed_mask)
  1772 +{
  1773 + return 0;
  1774 +}
  1775 +#endif
1719 1776  
1720 1777 static const struct mode_width_tuning mmc_modes_by_pref[] = {
  1778 +#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
1721 1779 {
1722 1780 .mode = MMC_HS_200,
1723 1781 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
1724 1782 .tuning = MMC_CMD_SEND_TUNING_BLOCK_HS200
1725 1783 },
  1784 +#endif
1726 1785 {
1727 1786 .mode = MMC_DDR_52,
1728 1787 .widths = MMC_MODE_8BIT | MMC_MODE_4BIT,
... ... @@ -1832,6 +1891,7 @@
1832 1891 /* configure the bus mode (host) */
1833 1892 mmc_select_mode(mmc, mwt->mode);
1834 1893 mmc_set_clock(mmc, mmc->tran_speed, false);
  1894 +#ifdef MMC_SUPPORTS_TUNING
1835 1895  
1836 1896 /* execute tuning if needed */
1837 1897 if (mwt->tuning) {
... ... @@ -1841,6 +1901,7 @@
1841 1901 goto error;
1842 1902 }
1843 1903 }
  1904 +#endif
1844 1905  
1845 1906 /* do a transfer to check the configuration */
1846 1907 err = mmc_read_and_compare_ext_csd(mmc);
... ... @@ -15,6 +15,13 @@
15 15 #include <linux/compiler.h>
16 16 #include <part.h>
17 17  
  18 +#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
  19 +#define MMC_SUPPORTS_TUNING
  20 +#endif
  21 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
  22 +#define MMC_SUPPORTS_TUNING
  23 +#endif
  24 +
18 25 /* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */
19 26 #define SD_VERSION_SD (1U << 31)
20 27 #define MMC_VERSION_MMC (1U << 30)
... ... @@ -425,6 +432,7 @@
425 432 */
426 433 int (*get_wp)(struct udevice *dev);
427 434  
  435 +#ifdef MMC_SUPPORTS_TUNING
428 436 /**
429 437 * execute_tuning() - Start the tuning process
430 438 *
431 439  
... ... @@ -433,7 +441,9 @@
433 441 * @return 0 if OK, -ve on error
434 442 */
435 443 int (*execute_tuning)(struct udevice *dev, uint opcode);
  444 +#endif
436 445  
  446 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
437 447 /**
438 448 * wait_dat0() - wait until dat0 is in the target state
439 449 * (CLK must be running during the wait)
... ... @@ -444,6 +454,7 @@
444 454 * @return 0 if dat0 is in the target state, -ve on error
445 455 */
446 456 int (*wait_dat0)(struct udevice *dev, int state, int timeout);
  457 +#endif
447 458 };
448 459  
449 460 #define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops)
450 461  
451 462  
... ... @@ -500,13 +511,13 @@
500 511 SD_LEGACY,
501 512 MMC_HS,
502 513 SD_HS,
  514 + MMC_HS_52,
  515 + MMC_DDR_52,
503 516 UHS_SDR12,
504 517 UHS_SDR25,
505 518 UHS_SDR50,
506   - UHS_SDR104,
507 519 UHS_DDR50,
508   - MMC_HS_52,
509   - MMC_DDR_52,
  520 + UHS_SDR104,
510 521 MMC_HS_200,
511 522 MMC_MODES_END
512 523 };
513 524  
... ... @@ -516,8 +527,12 @@
516 527  
517 528 static inline bool mmc_is_mode_ddr(enum bus_mode mode)
518 529 {
519   - if ((mode == MMC_DDR_52) || (mode == UHS_DDR50))
  530 + if (mode == MMC_DDR_52)
520 531 return true;
  532 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
  533 + else if (mode == UHS_DDR50)
  534 + return true;
  535 +#endif
521 536 else
522 537 return false;
523 538 }
524 539  
... ... @@ -528,7 +543,11 @@
528 543  
529 544 static inline bool supports_uhs(uint caps)
530 545 {
  546 +#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
531 547 return (caps & UHS_CAPS) ? true : false;
  548 +#else
  549 + return false;
  550 +#endif
532 551 }
533 552  
534 553 /*