mmc: core: fix the decision of HS200/DDR card-type
authorSeungwon Jeon <tgih.jun@samsung.com>
Wed, 25 Apr 2012 07:17:37 +0000 (16:17 +0900)
committerMandar Padmawar <mpadmawar@nvidia.com>
Tue, 21 May 2013 09:59:59 +0000 (02:59 -0700)
Current implementation decides the card type exclusively. Even though
eMMC device can support both HS200 and DDR mode, card type will be
set only for HS200. If the host doesn't support HS200 but has DDR
capability, then DDR mode can't be selected.

Change-Id: Id2b9095f8ffe59c520850acd40681a9ef15c3ff9
Signed-off-by: Pavan Kunapuli <pkunapuli@nvidia.com>
Signed-off-by: Seungwon Jeon <tgih.jun@samsung.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
Reviewed-on: http://git-master/r/227757
(cherry picked from commit 084aa8cc074b0e95883934f82f5521d0cc5e0941)
Reviewed-on: http://git-master/r/230046
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Matt Wagner <mwagner@nvidia.com>
Tested-by: Matt Wagner <mwagner@nvidia.com>
drivers/mmc/core/mmc.c
include/linux/mmc/card.h
include/linux/mmc/mmc.h

index 0d6487d6fe6bc6508dc42b65f8263d96877220d7..88b45bbbc17e0a279998dd2d58fa0223c983a809 100644 (file)
@@ -237,6 +237,36 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
        return err;
 }
 
+static void mmc_select_card_type(struct mmc_card *card)
+{
+       struct mmc_host *host = card->host;
+       u8 card_type = card->ext_csd.raw_card_type & EXT_CSD_CARD_TYPE_MASK;
+       unsigned int caps = host->caps, caps2 = host->caps2;
+       unsigned int hs_max_dtr = 0;
+
+       if (card_type & EXT_CSD_CARD_TYPE_26)
+               hs_max_dtr = MMC_HIGH_26_MAX_DTR;
+
+       if (caps & MMC_CAP_MMC_HIGHSPEED &&
+                       card_type & EXT_CSD_CARD_TYPE_52)
+               hs_max_dtr = MMC_HIGH_52_MAX_DTR;
+
+       if ((caps & MMC_CAP_1_8V_DDR &&
+                       card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) ||
+           (caps & MMC_CAP_1_2V_DDR &&
+                       card_type & EXT_CSD_CARD_TYPE_DDR_1_2V))
+               hs_max_dtr = MMC_HIGH_DDR_MAX_DTR;
+
+       if ((caps2 & MMC_CAP2_HS200_1_8V_SDR &&
+                       card_type & EXT_CSD_CARD_TYPE_SDR_1_8V) ||
+           (caps2 & MMC_CAP2_HS200_1_2V_SDR &&
+                       card_type & EXT_CSD_CARD_TYPE_SDR_1_2V))
+               hs_max_dtr = MMC_HS200_MAX_DTR;
+
+       card->ext_csd.hs_max_dtr = hs_max_dtr;
+       card->ext_csd.card_type = card_type;
+}
+
 /*
  * Decode extended CSD.
  */
@@ -286,56 +316,9 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
                if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512)
                        mmc_card_set_blockaddr(card);
        }
+
        card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
-       switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
-       case EXT_CSD_CARD_TYPE_SDR_ALL:
-       case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V:
-       case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V:
-       case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52:
-               card->ext_csd.hs_max_dtr = 200000000;
-               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200;
-               break;
-       case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL:
-       case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V:
-       case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V:
-       case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52:
-               card->ext_csd.hs_max_dtr = 200000000;
-               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V;
-               break;
-       case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL:
-       case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V:
-       case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V:
-       case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52:
-               card->ext_csd.hs_max_dtr = 200000000;
-               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V;
-               break;
-       case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
-            EXT_CSD_CARD_TYPE_26:
-               card->ext_csd.hs_max_dtr = 52000000;
-               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52;
-               break;
-       case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 |
-            EXT_CSD_CARD_TYPE_26:
-               card->ext_csd.hs_max_dtr = 52000000;
-               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V;
-               break;
-       case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 |
-            EXT_CSD_CARD_TYPE_26:
-               card->ext_csd.hs_max_dtr = 52000000;
-               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V;
-               break;
-       case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
-               card->ext_csd.hs_max_dtr = 52000000;
-               break;
-       case EXT_CSD_CARD_TYPE_26:
-               card->ext_csd.hs_max_dtr = 26000000;
-               break;
-       default:
-               /* MMC v4 spec says this cannot happen */
-               pr_warning("%s: card is mmc v4 but doesn't "
-                       "support any high-speed modes.\n",
-                       mmc_hostname(card->host));
-       }
+       mmc_select_card_type(card);
 
        card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT];
        card->ext_csd.raw_erase_timeout_mult =
index c7d90bd3f3bfd86d0f8b5f253134931ae641422b..22d11242eb93602f1e888a8791bb2d05651f40bc 100644 (file)
@@ -62,6 +62,10 @@ struct mmc_ext_csd {
        unsigned int            generic_cmd6_time;      /* Units: 10ms */
        unsigned int            power_off_longtime;     /* Units: ms */
        unsigned int            hs_max_dtr;
+#define MMC_HIGH_26_MAX_DTR    26000000
+#define MMC_HIGH_52_MAX_DTR    52000000
+#define MMC_HIGH_DDR_MAX_DTR   52000000
+#define MMC_HS200_MAX_DTR      200000000
        unsigned int            sectors;
        unsigned int            card_type;
        unsigned int            hc_erase_size;          /* In sectors */
index af6ab2969bed753800fa87c40ae8f77499297d8e..3084d1cf312981d1a310fcbc146e1f4f8f8f2dee 100644 (file)
@@ -380,66 +380,6 @@ struct _mmc_csd {
 #define EXT_CSD_CARD_TYPE_SDR_1_2V     (1<<5)  /* Card can run at 200MHz */
                                                /* SDR mode @1.2V I/O */
 
-#define EXT_CSD_CARD_TYPE_SDR_200      (EXT_CSD_CARD_TYPE_SDR_1_8V | \
-                                        EXT_CSD_CARD_TYPE_SDR_1_2V)
-
-#define EXT_CSD_CARD_TYPE_SDR_ALL      (EXT_CSD_CARD_TYPE_SDR_200 | \
-                                        EXT_CSD_CARD_TYPE_52 | \
-                                        EXT_CSD_CARD_TYPE_26)
-
-#define        EXT_CSD_CARD_TYPE_SDR_1_2V_ALL  (EXT_CSD_CARD_TYPE_SDR_1_2V | \
-                                        EXT_CSD_CARD_TYPE_52 | \
-                                        EXT_CSD_CARD_TYPE_26)
-
-#define        EXT_CSD_CARD_TYPE_SDR_1_8V_ALL  (EXT_CSD_CARD_TYPE_SDR_1_8V | \
-                                        EXT_CSD_CARD_TYPE_52 | \
-                                        EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V    (EXT_CSD_CARD_TYPE_SDR_1_2V | \
-                                                EXT_CSD_CARD_TYPE_DDR_1_8V | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V    (EXT_CSD_CARD_TYPE_SDR_1_8V | \
-                                                EXT_CSD_CARD_TYPE_DDR_1_8V | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V    (EXT_CSD_CARD_TYPE_SDR_1_2V | \
-                                                EXT_CSD_CARD_TYPE_DDR_1_2V | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V    (EXT_CSD_CARD_TYPE_SDR_1_8V | \
-                                                EXT_CSD_CARD_TYPE_DDR_1_2V | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52      (EXT_CSD_CARD_TYPE_SDR_1_2V | \
-                                                EXT_CSD_CARD_TYPE_DDR_52 | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52      (EXT_CSD_CARD_TYPE_SDR_1_8V | \
-                                                EXT_CSD_CARD_TYPE_DDR_52 | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V     (EXT_CSD_CARD_TYPE_SDR_200 | \
-                                                EXT_CSD_CARD_TYPE_DDR_1_8V | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V     (EXT_CSD_CARD_TYPE_SDR_200 | \
-                                                EXT_CSD_CARD_TYPE_DDR_1_2V | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
-#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52       (EXT_CSD_CARD_TYPE_SDR_200 | \
-                                                EXT_CSD_CARD_TYPE_DDR_52 | \
-                                                EXT_CSD_CARD_TYPE_52 | \
-                                                EXT_CSD_CARD_TYPE_26)
-
 #define EXT_CSD_BUS_WIDTH_1    0       /* Card is in 1 bit mode */
 #define EXT_CSD_BUS_WIDTH_4    1       /* Card is in 4 bit mode */
 #define EXT_CSD_BUS_WIDTH_8    2       /* Card is in 8 bit mode */