Merge tag 'v3.3-rc4' into for-3.4 in order to resolve the conflict
[firefly-linux-kernel-4.4.55.git] / drivers / mmc / core / mmc.c
index d240427c12462dd545b233d6d6e75787e4b48abb..a48066344fa87316997b0bcca501d0842ea7e8a1 100644 (file)
@@ -286,6 +286,27 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
        }
        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;
@@ -348,13 +369,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
                                part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
                                mmc_part_add(card, part_size,
                                        EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx,
-                                       "boot%d", idx, true);
+                                       "boot%d", idx, true,
+                                       MMC_BLK_DATA_AREA_BOOT);
                        }
                }
        }
 
        card->ext_csd.raw_hc_erase_gap_size =
-               ext_csd[EXT_CSD_PARTITION_ATTRIBUTE];
+               ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
        card->ext_csd.raw_sec_trim_mult =
                ext_csd[EXT_CSD_SEC_TRIM_MULT];
        card->ext_csd.raw_sec_erase_mult =
@@ -435,7 +457,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
                                        hc_wp_grp_sz);
                                mmc_part_add(card, part_size << 19,
                                        EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
-                                       "gp%d", idx, false);
+                                       "gp%d", idx, false,
+                                       MMC_BLK_DATA_AREA_GP);
                        }
                }
                card->ext_csd.sec_trim_mult =
@@ -446,6 +469,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
                        ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
                card->ext_csd.trim_timeout = 300 *
                        ext_csd[EXT_CSD_TRIM_MULT];
+
+               /*
+                * Note that the call to mmc_part_add above defaults to read
+                * only. If this default assumption is changed, the call must
+                * take into account the value of boot_locked below.
+                */
+               card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP];
+               card->ext_csd.boot_ro_lockable = true;
        }
 
        if (card->ext_csd.rev >= 5) {
@@ -520,7 +551,7 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width)
                goto out;
 
        /* only compare read only fields */
-       err = (!(card->ext_csd.raw_partition_support ==
+       err = !((card->ext_csd.raw_partition_support ==
                        bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
                (card->ext_csd.raw_erased_mem_count ==
                        bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
@@ -689,6 +720,79 @@ static int mmc_select_powerclass(struct mmc_card *card,
        return err;
 }
 
+/*
+ * Selects the desired buswidth and switch to the HS200 mode
+ * if bus width set without error
+ */
+static int mmc_select_hs200(struct mmc_card *card)
+{
+       int idx, err = 0;
+       struct mmc_host *host;
+       static unsigned ext_csd_bits[] = {
+               EXT_CSD_BUS_WIDTH_4,
+               EXT_CSD_BUS_WIDTH_8,
+       };
+       static unsigned bus_widths[] = {
+               MMC_BUS_WIDTH_4,
+               MMC_BUS_WIDTH_8,
+       };
+
+       BUG_ON(!card);
+
+       host = card->host;
+
+       if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V &&
+           host->caps2 & MMC_CAP2_HS200_1_2V_SDR)
+               if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0))
+                       err = mmc_set_signal_voltage(host,
+                                                    MMC_SIGNAL_VOLTAGE_180, 0);
+
+       /* If fails try again during next card power cycle */
+       if (err)
+               goto err;
+
+       idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 1 : 0;
+
+       /*
+        * Unlike SD, MMC cards dont have a configuration register to notify
+        * supported bus width. So bus test command should be run to identify
+        * the supported bus width or compare the ext csd values of current
+        * bus width and ext csd values of 1 bit mode read earlier.
+        */
+       for (; idx >= 0; idx--) {
+
+               /*
+                * Host is capable of 8bit transfer, then switch
+                * the device to work in 8bit transfer mode. If the
+                * mmc switch command returns error then switch to
+                * 4bit transfer mode. On success set the corresponding
+                * bus width on the host.
+                */
+               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                                EXT_CSD_BUS_WIDTH,
+                                ext_csd_bits[idx],
+                                card->ext_csd.generic_cmd6_time);
+               if (err)
+                       continue;
+
+               mmc_set_bus_width(card->host, bus_widths[idx]);
+
+               if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
+                       err = mmc_compare_ext_csds(card, bus_widths[idx]);
+               else
+                       err = mmc_bus_test(card, bus_widths[idx]);
+               if (!err)
+                       break;
+       }
+
+       /* switch to HS200 mode if bus width set successfully */
+       if (!err)
+               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                                EXT_CSD_HS_TIMING, 2, 0);
+err:
+       return err;
+}
+
 /*
  * Handle the detection and initialisation of a card.
  *
@@ -895,11 +999,16 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
        /*
         * Activate high speed (if supported)
         */
-       if ((card->ext_csd.hs_max_dtr != 0) &&
-               (host->caps & MMC_CAP_MMC_HIGHSPEED)) {
-               err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-                                EXT_CSD_HS_TIMING, 1,
-                                card->ext_csd.generic_cmd6_time);
+       if (card->ext_csd.hs_max_dtr != 0) {
+               err = 0;
+               if (card->ext_csd.hs_max_dtr > 52000000 &&
+                   host->caps2 & MMC_CAP2_HS200)
+                       err = mmc_select_hs200(card);
+               else if (host->caps & MMC_CAP_MMC_HIGHSPEED)
+                       err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+                                        EXT_CSD_HS_TIMING, 1,
+                                        card->ext_csd.generic_cmd6_time);
+
                if (err && err != -EBADMSG)
                        goto free_card;
 
@@ -908,8 +1017,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                               mmc_hostname(card->host));
                        err = 0;
                } else {
-                       mmc_card_set_highspeed(card);
-                       mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+                       if (card->ext_csd.hs_max_dtr > 52000000 &&
+                           host->caps2 & MMC_CAP2_HS200) {
+                               mmc_card_set_hs200(card);
+                               mmc_set_timing(card->host,
+                                              MMC_TIMING_MMC_HS200);
+                       } else {
+                               mmc_card_set_highspeed(card);
+                               mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+                       }
                }
        }
 
@@ -934,7 +1050,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
         */
        max_dtr = (unsigned int)-1;
 
-       if (mmc_card_highspeed(card)) {
+       if (mmc_card_highspeed(card) || mmc_card_hs200(card)) {
                if (max_dtr > card->ext_csd.hs_max_dtr)
                        max_dtr = card->ext_csd.hs_max_dtr;
        } else if (max_dtr > card->csd.max_dtr) {
@@ -959,10 +1075,49 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                                ddr = MMC_1_2V_DDR_MODE;
        }
 
+       /*
+        * Indicate HS200 SDR mode (if supported).
+        */
+       if (mmc_card_hs200(card)) {
+               u32 ext_csd_bits;
+               u32 bus_width = card->host->ios.bus_width;
+
+               /*
+                * For devices supporting HS200 mode, the bus width has
+                * to be set before executing the tuning function. If
+                * set before tuning, then device will respond with CRC
+                * errors for responses on CMD line. So for HS200 the
+                * sequence will be
+                * 1. set bus width 4bit / 8 bit (1 bit not supported)
+                * 2. switch to HS200 mode
+                * 3. set the clock to > 52Mhz <=200MHz and
+                * 4. execute tuning for HS200
+                */
+               if ((host->caps2 & MMC_CAP2_HS200) &&
+                   card->host->ops->execute_tuning)
+                       err = card->host->ops->execute_tuning(card->host,
+                               MMC_SEND_TUNING_BLOCK_HS200);
+               if (err) {
+                       pr_warning("%s: tuning execution failed\n",
+                                  mmc_hostname(card->host));
+                       goto err;
+               }
+
+               ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
+                               EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
+               err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
+               if (err) {
+                       pr_err("%s: power class selection to bus width %d failed\n",
+                               mmc_hostname(card->host), 1 << bus_width);
+                       goto err;
+               }
+       }
+
        /*
         * Activate wide bus and DDR (if supported).
         */
-       if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
+       if (!mmc_card_hs200(card) &&
+           (card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
            (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
                static unsigned ext_csd_bits[][2] = {
                        { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
@@ -1048,7 +1203,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                         *
                         * WARNING: eMMC rules are NOT the same as SD DDR
                         */
-                       if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
+                       if (ddr == MMC_1_2V_DDR_MODE) {
                                err = mmc_set_signal_voltage(host,
                                        MMC_SIGNAL_VOLTAGE_120, 0);
                                if (err)
@@ -1067,14 +1222,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
        if ((host->caps2 & MMC_CAP2_CACHE_CTRL) &&
                        card->ext_csd.cache_size > 0) {
                err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-                               EXT_CSD_CACHE_CTRL, 1, 0);
+                               EXT_CSD_CACHE_CTRL, 1,
+                               card->ext_csd.generic_cmd6_time);
                if (err && err != -EBADMSG)
                        goto free_card;
 
                /*
                 * Only if no error, cache is turned on successfully.
                 */
-               card->ext_csd.cache_ctrl = err ? 0 : 1;
+               if (err) {
+                       pr_warning("%s: Cache is supported, "
+                                       "but failed to turn on (%d)\n",
+                                       mmc_hostname(card->host), err);
+                       card->ext_csd.cache_ctrl = 0;
+                       err = 0;
+               } else {
+                       card->ext_csd.cache_ctrl = 1;
+               }
        }
 
        if (!oldcard)
@@ -1104,6 +1268,14 @@ static void mmc_remove(struct mmc_host *host)
        host->card = NULL;
 }
 
+/*
+ * Card detection - card is alive.
+ */
+static int mmc_alive(struct mmc_host *host)
+{
+       return mmc_send_status(host->card, NULL);
+}
+
 /*
  * Card detection callback from host.
  */
@@ -1119,7 +1291,7 @@ static void mmc_detect(struct mmc_host *host)
        /*
         * Just check if our card has been removed.
         */
-       err = mmc_send_status(host->card, NULL);
+       err = _mmc_detect_card_removed(host);
 
        mmc_release_host(host);
 
@@ -1144,11 +1316,13 @@ static int mmc_suspend(struct mmc_host *host)
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
-       if (mmc_card_can_sleep(host))
+       if (mmc_card_can_sleep(host)) {
                err = mmc_card_sleep(host);
-       else if (!mmc_host_is_spi(host))
+               if (!err)
+                       mmc_card_set_sleep(host->card);
+       } else if (!mmc_host_is_spi(host))
                mmc_deselect_cards(host);
-       host->card->state &= ~MMC_STATE_HIGHSPEED;
+       host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
        mmc_release_host(host);
 
        return err;
@@ -1168,7 +1342,11 @@ static int mmc_resume(struct mmc_host *host)
        BUG_ON(!host->card);
 
        mmc_claim_host(host);
-       err = mmc_init_card(host, host->ocr, host->card);
+       if (mmc_card_is_sleep(host->card)) {
+               err = mmc_card_awake(host);
+               mmc_card_clr_sleep(host->card);
+       } else
+               err = mmc_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
 
        return err;
@@ -1178,7 +1356,8 @@ static int mmc_power_restore(struct mmc_host *host)
 {
        int ret;
 
-       host->card->state &= ~MMC_STATE_HIGHSPEED;
+       host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
+       mmc_card_clr_sleep(host->card);
        mmc_claim_host(host);
        ret = mmc_init_card(host, host->ocr, host->card);
        mmc_release_host(host);
@@ -1224,6 +1403,7 @@ static const struct mmc_bus_ops mmc_ops = {
        .suspend = NULL,
        .resume = NULL,
        .power_restore = mmc_power_restore,
+       .alive = mmc_alive,
 };
 
 static const struct mmc_bus_ops mmc_ops_unsafe = {
@@ -1234,6 +1414,7 @@ static const struct mmc_bus_ops mmc_ops_unsafe = {
        .suspend = mmc_suspend,
        .resume = mmc_resume,
        .power_restore = mmc_power_restore,
+       .alive = mmc_alive,
 };
 
 static void mmc_attach_bus_ops(struct mmc_host *host)