aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Jacques Hiblot2017-04-20 10:54:25 -0500
committerJean-Jacques Hiblot2017-07-13 03:03:57 -0500
commit586dca26fb8865145f40c48baa33d83b950eb86a (patch)
treeec93b3d8891c7c140ff64315110a28a29f862bbf
parent91370262d74b14b41de8492f23decc0dc6076b1f (diff)
downloadu-boot-586dca26fb8865145f40c48baa33d83b950eb86a.tar.gz
u-boot-586dca26fb8865145f40c48baa33d83b950eb86a.tar.xz
u-boot-586dca26fb8865145f40c48baa33d83b950eb86a.zip
drivers: mmc: fall back to lower performance modes if HS200 or DDR52 fail during the initialization
commit e14ac74b66e3 ("drivers: mmc: fall back to lower performance modes if HS200 or DDR52 fail during the initialization") branch ti-u-boot-2017.01 If the initialization fails when trying to use HS200 or DDR52, then remove the failing capability for the capabilities supported by the host and restart the whole initialization process. Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com>
-rw-r--r--drivers/mmc/mmc.c50
-rw-r--r--include/mmc.h1
2 files changed, 32 insertions, 19 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 0670b16a2e..82a023190b 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -386,7 +386,7 @@ static int mmc_go_idle(struct mmc *mmc)
386 386
387static int mmc_host_uhs(struct mmc *mmc) 387static int mmc_host_uhs(struct mmc *mmc)
388{ 388{
389 return mmc->cfg->host_caps & 389 return mmc->host_ok_caps &
390 (MMC_MODE_UHS_SDR12 | MMC_MODE_UHS_SDR25 | 390 (MMC_MODE_UHS_SDR12 | MMC_MODE_UHS_SDR25 |
391 MMC_MODE_UHS_SDR50 | MMC_MODE_UHS_SDR104 | 391 MMC_MODE_UHS_SDR50 | MMC_MODE_UHS_SDR104 |
392 MMC_MODE_UHS_DDR50); 392 MMC_MODE_UHS_DDR50);
@@ -663,7 +663,7 @@ static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
663 663
664static void mmc_select_card_type(struct mmc *mmc, char card_type) 664static void mmc_select_card_type(struct mmc *mmc, char card_type)
665{ 665{
666 u32 caps = mmc->cfg->host_caps; 666 u32 caps = mmc->host_ok_caps;
667 uint hs_max_dtr = mmc->tran_speed; 667 uint hs_max_dtr = mmc->tran_speed;
668 668
669 if (caps & MMC_MODE_HS && 669 if (caps & MMC_MODE_HS &&
@@ -1094,7 +1094,7 @@ static int mmc_app_set_bus_width(struct mmc *mmc, int width)
1094 1094
1095static void sd_update_bus_speed_mode(struct mmc *mmc) 1095static void sd_update_bus_speed_mode(struct mmc *mmc)
1096{ 1096{
1097 u32 caps = mmc->cfg->host_caps; 1097 u32 caps = mmc->host_ok_caps;
1098 /* 1098 /*
1099 * If the host doesn't support any of the UHS-I modes, fallback on 1099 * If the host doesn't support any of the UHS-I modes, fallback on
1100 * default speed. 1100 * default speed.
@@ -1238,8 +1238,8 @@ static int mmc_sd_switch_hs(struct mmc *mmc)
1238 * This can avoid furthur problem when the card runs in different 1238 * This can avoid furthur problem when the card runs in different
1239 * mode between the host. 1239 * mode between the host.
1240 */ 1240 */
1241 if (!((mmc->cfg->host_caps & MMC_MODE_HS_52MHz) && 1241 if (!((mmc->host_ok_caps & MMC_MODE_HS_52MHz) &&
1242 (mmc->cfg->host_caps & MMC_MODE_HS))) 1242 (mmc->host_ok_caps & MMC_MODE_HS)))
1243 return -EINVAL; 1243 return -EINVAL;
1244 1244
1245 if (!(mmc->card_caps & MMC_MODE_HS)) 1245 if (!(mmc->card_caps & MMC_MODE_HS))
@@ -1350,7 +1350,7 @@ retry_scr:
1350 mmc->card_caps |= MMC_MODE_HS; 1350 mmc->card_caps |= MMC_MODE_HS;
1351 1351
1352 /* Restrict card's capabilities by what the host can do */ 1352 /* Restrict card's capabilities by what the host can do */
1353 mmc->card_caps &= mmc->cfg->host_caps; 1353 mmc->card_caps &= mmc->host_ok_caps;
1354 1354
1355 if (mmc->ocr & OCR_S18R) { 1355 if (mmc->ocr & OCR_S18R) {
1356 mmc_sd_init_uhs_card(mmc); 1356 mmc_sd_init_uhs_card(mmc);
@@ -1513,16 +1513,15 @@ static int mmc_select_bus_width(struct mmc *mmc)
1513 MMC_BUS_WIDTH_8, 1513 MMC_BUS_WIDTH_8,
1514 MMC_BUS_WIDTH_4, 1514 MMC_BUS_WIDTH_4,
1515 }; 1515 };
1516 const struct mmc_config *cfg = mmc->cfg;
1517 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); 1516 ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
1518 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN); 1517 ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
1519 unsigned idx = 0, bus_width = 0; 1518 unsigned idx = 0, bus_width = 0;
1520 int err = 0; 1519 int err = 0;
1521 1520
1522 if (!(cfg->host_caps & (MMC_MODE_8BIT | MMC_MODE_4BIT))) 1521 if (!(mmc->host_ok_caps & (MMC_MODE_8BIT | MMC_MODE_4BIT)))
1523 return 0; 1522 return 0;
1524 1523
1525 idx = (cfg->host_caps & MMC_MODE_8BIT) ? 0 : 1; 1524 idx = (mmc->host_ok_caps & MMC_MODE_8BIT) ? 0 : 1;
1526 1525
1527 err = mmc_send_ext_csd(mmc, ext_csd); 1526 err = mmc_send_ext_csd(mmc, ext_csd);
1528 if (err) 1527 if (err)
@@ -1887,16 +1886,22 @@ static int mmc_startup(struct mmc *mmc)
1887 if (mmc->timing == MMC_TIMING_MMC_HS200) { 1886 if (mmc->timing == MMC_TIMING_MMC_HS200) {
1888 err = mmc->cfg->ops->execute_tuning(mmc, 1887 err = mmc->cfg->ops->execute_tuning(mmc,
1889 MMC_SEND_TUNING_BLOCK_HS200); 1888 MMC_SEND_TUNING_BLOCK_HS200);
1890 if (err) 1889 if (err) {
1891 return err; 1890 printf("Tuning failed, dropping HS200 mode.\n");
1891 mmc->host_ok_caps &= ~MMC_MODE_HS200;
1892 return -EAGAIN;
1893 }
1892 } else if (mmc->timing == MMC_TIMING_MMC_HS) { 1894 } else if (mmc->timing == MMC_TIMING_MMC_HS) {
1893 err = mmc_select_bus_width(mmc); 1895 err = mmc_select_bus_width(mmc);
1894 if (err) 1896 if (err)
1895 return err; 1897 return err;
1896 1898
1897 err = mmc_select_hs_ddr(mmc); 1899 err = mmc_select_hs_ddr(mmc);
1898 if (err) 1900 if (err) {
1899 return err; 1901 printf("dropping DDR52 mode.\n");
1902 mmc->host_ok_caps &= ~MMC_MODE_DDR_52MHz;
1903 return -EAGAIN;
1904 }
1900 } 1905 }
1901 } 1906 }
1902 1907
@@ -2161,19 +2166,26 @@ static int mmc_complete_init(struct mmc *mmc)
2161int mmc_init(struct mmc *mmc) 2166int mmc_init(struct mmc *mmc)
2162{ 2167{
2163 int err = 0; 2168 int err = 0;
2164 unsigned start; 2169 int retries = 0;
2170 __maybe_unused unsigned start;
2165 2171
2166 if (mmc->has_init) 2172 if (mmc->has_init)
2167 return 0; 2173 return 0;
2168 2174
2175 mmc->host_ok_caps = mmc->cfg->host_caps;
2169 start = get_timer(0); 2176 start = get_timer(0);
2170 2177
2171 if (!mmc->init_in_progress) 2178 do {
2172 err = mmc_start_init(mmc); 2179 retries++;
2180 if (!mmc->init_in_progress)
2181 err = mmc_start_init(mmc);
2173 2182
2174 if (!err) 2183 if (!err)
2175 err = mmc_complete_init(mmc); 2184 err = mmc_complete_init(mmc);
2176 debug("%s: %d, time %lu\n", __func__, err, get_timer(start)); 2185 } while (err == -EAGAIN);
2186
2187 debug("%s: %d, time %lu (retries %d)\n", __func__, err,
2188 get_timer(start), retries - 1);
2177 return err; 2189 return err;
2178} 2190}
2179 2191
diff --git a/include/mmc.h b/include/mmc.h
index 8cdad5a800..c7aeb74b49 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -450,6 +450,7 @@ struct mmc {
450 struct blk_desc block_dev; 450 struct blk_desc block_dev;
451 char op_cond_pending; /* 1 if we are waiting on an op_cond command */ 451 char op_cond_pending; /* 1 if we are waiting on an op_cond command */
452 char init_in_progress; /* 1 if we have done mmc_start_init() */ 452 char init_in_progress; /* 1 if we have done mmc_start_init() */
453 uint host_ok_caps; /* host caps that are not yet proven wrong */
453 char preinit; /* start init as early as possible */ 454 char preinit; /* start init as early as possible */
454 int ddr_mode; 455 int ddr_mode;
455 unsigned int sd_bus_speed; 456 unsigned int sd_bus_speed;