|
@@ -512,6 +512,64 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int sd_set_current_limit(struct mmc_card *card, u8 *status)
|
|
|
+{
|
|
|
+ int current_limit = 0;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Current limit switch is only defined for SDR50, SDR104, and DDR50
|
|
|
+ * bus speed modes. For other bus speed modes, we set the default
|
|
|
+ * current limit of 200mA.
|
|
|
+ */
|
|
|
+ if ((card->sd_bus_speed == UHS_SDR50_BUS_SPEED) ||
|
|
|
+ (card->sd_bus_speed == UHS_SDR104_BUS_SPEED) ||
|
|
|
+ (card->sd_bus_speed == UHS_DDR50_BUS_SPEED)) {
|
|
|
+ if (card->host->caps & MMC_CAP_MAX_CURRENT_800) {
|
|
|
+ if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_800;
|
|
|
+ else if (card->sw_caps.sd3_curr_limit &
|
|
|
+ SD_MAX_CURRENT_600)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_600;
|
|
|
+ else if (card->sw_caps.sd3_curr_limit &
|
|
|
+ SD_MAX_CURRENT_400)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_400;
|
|
|
+ else if (card->sw_caps.sd3_curr_limit &
|
|
|
+ SD_MAX_CURRENT_200)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_200;
|
|
|
+ } else if (card->host->caps & MMC_CAP_MAX_CURRENT_600) {
|
|
|
+ if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_600;
|
|
|
+ else if (card->sw_caps.sd3_curr_limit &
|
|
|
+ SD_MAX_CURRENT_400)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_400;
|
|
|
+ else if (card->sw_caps.sd3_curr_limit &
|
|
|
+ SD_MAX_CURRENT_200)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_200;
|
|
|
+ } else if (card->host->caps & MMC_CAP_MAX_CURRENT_400) {
|
|
|
+ if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_400;
|
|
|
+ else if (card->sw_caps.sd3_curr_limit &
|
|
|
+ SD_MAX_CURRENT_200)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_200;
|
|
|
+ } else if (card->host->caps & MMC_CAP_MAX_CURRENT_200) {
|
|
|
+ if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_200;
|
|
|
+ }
|
|
|
+ } else
|
|
|
+ current_limit = SD_SET_CURRENT_LIMIT_200;
|
|
|
+
|
|
|
+ err = mmc_sd_switch(card, 1, 3, current_limit, status);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ if (((status[15] >> 4) & 0x0F) != current_limit)
|
|
|
+ printk(KERN_WARNING "%s: Problem setting current limit!\n",
|
|
|
+ mmc_hostname(card->host));
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* UHS-I specific initialization procedure
|
|
|
*/
|
|
@@ -550,6 +608,11 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
|
|
|
|
|
|
/* Set bus speed mode of the card */
|
|
|
err = sd_set_bus_speed_mode(card, status);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ /* Set current limit for the card */
|
|
|
+ err = sd_set_current_limit(card, status);
|
|
|
|
|
|
out:
|
|
|
kfree(status);
|