Commit 01298da31d92ecc46cf9130d8cff68bc51698197

Authored by Jean-Jacques Hiblot
Committed by Jaehoon Chung
1 parent 04a2ea248f

mmc: Change mode when switching to a boot partition

Boot partitions do not support HS200. Changing to a lower performance mode
is required to access them.
mmc_select_mode_and_width() and sd_select_mode_and_width() are modified to
make it easier to call them outside of the initialization context.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
Reviewed-by: Simon Glass <sjg@chromium.org>

Showing 2 changed files with 55 additions and 18 deletions Side-by-side Diff

... ... @@ -32,6 +32,7 @@
32 32  
33 33 static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
34 34 static int mmc_power_cycle(struct mmc *mmc);
  35 +static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
35 36  
36 37 #if CONFIG_IS_ENABLED(MMC_TINY)
37 38 static struct mmc mmc_static;
38 39  
... ... @@ -792,10 +793,38 @@
792 793 return 0;
793 794 }
794 795  
  796 +static int mmc_boot_part_access_chk(struct mmc *mmc, unsigned int part_num)
  797 +{
  798 + int forbidden = 0;
  799 + bool change = false;
  800 +
  801 + if (part_num & PART_ACCESS_MASK)
  802 + forbidden = MMC_CAP(MMC_HS_200);
  803 +
  804 + if (MMC_CAP(mmc->selected_mode) & forbidden) {
  805 + debug("selected mode (%s) is forbidden for part %d\n",
  806 + mmc_mode_name(mmc->selected_mode), part_num);
  807 + change = true;
  808 + } else if (mmc->selected_mode != mmc->best_mode) {
  809 + debug("selected mode is not optimal\n");
  810 + change = true;
  811 + }
  812 +
  813 + if (change)
  814 + return mmc_select_mode_and_width(mmc,
  815 + mmc->card_caps & ~forbidden);
  816 +
  817 + return 0;
  818 +}
  819 +
795 820 int mmc_switch_part(struct mmc *mmc, unsigned int part_num)
796 821 {
797 822 int ret;
798 823  
  824 + ret = mmc_boot_part_access_chk(mmc, part_num);
  825 + if (ret)
  826 + return ret;
  827 +
799 828 ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
800 829 (mmc->part_config & ~PART_ACCESS_MASK)
801 830 | (part_num & PART_ACCESS_MASK));
... ... @@ -1438,7 +1467,7 @@
1438 1467 mwt++) \
1439 1468 if (caps & MMC_CAP(mwt->mode))
1440 1469  
1441   -static int sd_select_mode_and_width(struct mmc *mmc)
  1470 +static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
1442 1471 {
1443 1472 int err;
1444 1473 uint widths[] = {MMC_MODE_4BIT, MMC_MODE_1BIT};
1445 1474  
... ... @@ -1447,11 +1476,8 @@
1447 1476 uint caps;
1448 1477  
1449 1478  
1450   - err = sd_get_capabilities(mmc);
1451   - if (err)
1452   - return err;
1453 1479 /* Restrict card's capabilities by what the host can do */
1454   - caps = mmc->card_caps & (mmc->host_caps | MMC_MODE_1BIT);
  1480 + caps = card_caps & (mmc->host_caps | MMC_MODE_1BIT);
1455 1481  
1456 1482 if (!uhs_en)
1457 1483 caps &= ~UHS_CAPS;
1458 1484  
1459 1485  
... ... @@ -1588,18 +1614,14 @@
1588 1614 ecbv++) \
1589 1615 if ((ddr == ecbv->is_ddr) && (caps & ecbv->cap))
1590 1616  
1591   -static int mmc_select_mode_and_width(struct mmc *mmc)
  1617 +static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
1592 1618 {
1593 1619 int err;
1594 1620 const struct mode_width_tuning *mwt;
1595 1621 const struct ext_csd_bus_width *ecbw;
1596 1622  
1597   - err = mmc_get_capabilities(mmc);
1598   - if (err)
1599   - return err;
1600   -
1601 1623 /* Restrict card's capabilities by what the host can do */
1602   - mmc->card_caps &= (mmc->host_caps | MMC_MODE_1BIT);
  1624 + card_caps &= (mmc->host_caps | MMC_MODE_1BIT);
1603 1625  
1604 1626 /* Only version 4 of MMC supports wider bus widths */
1605 1627 if (mmc->version < MMC_VERSION_4)
... ... @@ -1610,8 +1632,10 @@
1610 1632 return -ENOTSUPP;
1611 1633 }
1612 1634  
1613   - for_each_mmc_mode_by_pref(mmc->card_caps, mwt) {
1614   - for_each_supported_width(mmc->card_caps & mwt->widths,
  1635 + mmc_set_clock(mmc, mmc->legacy_speed, false);
  1636 +
  1637 + for_each_mmc_mode_by_pref(card_caps, mwt) {
  1638 + for_each_supported_width(card_caps & mwt->widths,
1615 1639 mmc_is_mode_ddr(mwt->mode), ecbw) {
1616 1640 debug("trying mode %s width %d (at %d MHz)\n",
1617 1641 mmc_mode_name(mwt->mode),
1618 1642  
... ... @@ -2006,14 +2030,22 @@
2006 2030 if (err)
2007 2031 return err;
2008 2032  
2009   - if (IS_SD(mmc))
2010   - err = sd_select_mode_and_width(mmc);
2011   - else
2012   - err = mmc_select_mode_and_width(mmc);
  2033 + if (IS_SD(mmc)) {
  2034 + err = sd_get_capabilities(mmc);
  2035 + if (err)
  2036 + return err;
  2037 + err = sd_select_mode_and_width(mmc, mmc->card_caps);
  2038 + } else {
  2039 + err = mmc_get_capabilities(mmc);
  2040 + if (err)
  2041 + return err;
  2042 + mmc_select_mode_and_width(mmc, mmc->card_caps);
  2043 + }
2013 2044  
2014 2045 if (err)
2015 2046 return err;
2016 2047  
  2048 + mmc->best_mode = mmc->selected_mode;
2017 2049  
2018 2050 /* Fix the block length for DDR mode */
2019 2051 if (mmc->ddr_mode) {
... ... @@ -585,7 +585,12 @@
585 585 #endif
586 586 #endif
587 587 u8 *ext_csd;
588   - enum bus_mode selected_mode;
  588 + enum bus_mode selected_mode; /* mode currently used */
  589 + enum bus_mode best_mode; /* best mode is the supported mode with the
  590 + * highest bandwidth. It may not always be the
  591 + * operating mode due to limitations when
  592 + * accessing the boot partitions
  593 + */
589 594 };
590 595  
591 596 struct mmc_hwpart_conf {