For we don't know mmc bus width from reading registers, the only way
to check is to test.

Current compare offset is:
EXT_CSD_PARTITIONING_SUPPORT
EXT_CSD_ERASE_GROUP_DEF
EXT_CSD_REV
EXT_CSD_HC_ERASE_GRP_SIZE
EXT_CSD_SEC_CNT

Signed-off-by: Lei Wen <lei...@marvell.com>
---
Changelog:
V2: change all magic number for ext_csd to macro definition

 drivers/mmc/mmc.c |   45 ++++++++++++++++++++++++++-------------------
 1 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 1d75940..ea19d27 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -631,8 +631,6 @@ int mmc_change_freq(struct mmc *mmc)
        if (mmc->version < MMC_VERSION_4)
                return 0;
 
-       mmc->card_caps |= MMC_MODE_4BIT;
-
        err = mmc_send_ext_csd(mmc, ext_csd);
 
        if (err)
@@ -856,11 +854,11 @@ void mmc_set_bus_width(struct mmc *mmc, uint width)
 
 int mmc_startup(struct mmc *mmc)
 {
-       int err;
+       int err, width;
        uint mult, freq;
        u64 cmult, csize, capacity;
        struct mmc_cmd cmd;
-       char ext_csd[512];
+       char ext_csd[512], test_csd[512];
        int timeout = 1000;
 
 #ifdef CONFIG_MMC_SPI_CRC_ON
@@ -1080,26 +1078,35 @@ int mmc_startup(struct mmc *mmc)
                else
                        mmc_set_clock(mmc, 25000000);
        } else {
-               if (mmc->card_caps & MMC_MODE_4BIT) {
+               for (width = EXT_CSD_BUS_WIDTH_8; width >= 0; width--) {
                        /* Set the card to use 4 bit*/
                        err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
-                                       EXT_CSD_BUS_WIDTH,
-                                       EXT_CSD_BUS_WIDTH_4);
-
-                       if (err)
-                               return err;
-
-                       mmc_set_bus_width(mmc, 4);
-               } else if (mmc->card_caps & MMC_MODE_8BIT) {
-                       /* Set the card to use 8 bit*/
-                       err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
-                                       EXT_CSD_BUS_WIDTH,
-                                       EXT_CSD_BUS_WIDTH_8);
+                                       EXT_CSD_BUS_WIDTH, width);
 
                        if (err)
-                               return err;
+                               continue;
 
-                       mmc_set_bus_width(mmc, 8);
+                       if (!width) {
+                               mmc_set_bus_width(mmc, 1);
+                               break;
+                       } else
+                               mmc_set_bus_width(mmc, 4 * width);
+
+                       err = mmc_send_ext_csd(mmc, test_csd);
+                       if (!err && ext_csd[EXT_CSD_PARTITIONING_SUPPORT] \
+                                   == test_csd[EXT_CSD_PARTITIONING_SUPPORT]
+                                && ext_csd[EXT_CSD_ERASE_GROUP_DEF] \
+                                   == test_csd[EXT_CSD_ERASE_GROUP_DEF] \
+                                && ext_csd[EXT_CSD_REV] \
+                                   == test_csd[EXT_CSD_REV]
+                                && ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] \
+                                   == test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
+                                && memcmp(&ext_csd[EXT_CSD_SEC_CNT], \
+                                       &test_csd[EXT_CSD_SEC_CNT], 4) == 0) {
+
+                               mmc->card_caps |= width;
+                               break;
+                       }
                }
 
                if (mmc->card_caps & MMC_MODE_HS) {
-- 
1.7.0.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to