aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/core/mmc.c')
-rw-r--r--drivers/mmc/core/mmc.c93
1 files changed, 69 insertions, 24 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index c793fda27321..3a9a79ec4343 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1040,9 +1040,24 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
1040 return err; 1040 return err;
1041} 1041}
1042 1042
1043/* Caller must hold re-tuning */
1044static int mmc_switch_status(struct mmc_card *card)
1045{
1046 u32 status;
1047 int err;
1048
1049 err = mmc_send_status(card, &status);
1050 if (err)
1051 return err;
1052
1053 return mmc_switch_status_error(card->host, status);
1054}
1055
1043static int mmc_select_hs400(struct mmc_card *card) 1056static int mmc_select_hs400(struct mmc_card *card)
1044{ 1057{
1045 struct mmc_host *host = card->host; 1058 struct mmc_host *host = card->host;
1059 bool send_status = true;
1060 unsigned int max_dtr;
1046 int err = 0; 1061 int err = 0;
1047 u8 val; 1062 u8 val;
1048 1063
@@ -1053,25 +1068,36 @@ static int mmc_select_hs400(struct mmc_card *card)
1053 host->ios.bus_width == MMC_BUS_WIDTH_8)) 1068 host->ios.bus_width == MMC_BUS_WIDTH_8))
1054 return 0; 1069 return 0;
1055 1070
1056 /* 1071 if (host->caps & MMC_CAP_WAIT_WHILE_BUSY)
1057 * Before switching to dual data rate operation for HS400, 1072 send_status = false;
1058 * it is required to convert from HS200 mode to HS mode.
1059 */
1060 mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
1061 mmc_set_bus_speed(card);
1062 1073
1074 /* Reduce frequency to HS frequency */
1075 max_dtr = card->ext_csd.hs_max_dtr;
1076 mmc_set_clock(host, max_dtr);
1077
1078 /* Switch card to HS mode */
1063 val = EXT_CSD_TIMING_HS | 1079 val = EXT_CSD_TIMING_HS |
1064 card->drive_strength << EXT_CSD_DRV_STR_SHIFT; 1080 card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
1065 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1081 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1066 EXT_CSD_HS_TIMING, val, 1082 EXT_CSD_HS_TIMING, val,
1067 card->ext_csd.generic_cmd6_time, 1083 card->ext_csd.generic_cmd6_time,
1068 true, true, true); 1084 true, send_status, true);
1069 if (err) { 1085 if (err) {
1070 pr_err("%s: switch to high-speed from hs200 failed, err:%d\n", 1086 pr_err("%s: switch to high-speed from hs200 failed, err:%d\n",
1071 mmc_hostname(host), err); 1087 mmc_hostname(host), err);
1072 return err; 1088 return err;
1073 } 1089 }
1074 1090
1091 /* Set host controller to HS timing */
1092 mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
1093
1094 if (!send_status) {
1095 err = mmc_switch_status(card);
1096 if (err)
1097 goto out_err;
1098 }
1099
1100 /* Switch card to DDR */
1075 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1101 err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1076 EXT_CSD_BUS_WIDTH, 1102 EXT_CSD_BUS_WIDTH,
1077 EXT_CSD_DDR_BUS_WIDTH_8, 1103 EXT_CSD_DDR_BUS_WIDTH_8,
@@ -1082,22 +1108,35 @@ static int mmc_select_hs400(struct mmc_card *card)
1082 return err; 1108 return err;
1083 } 1109 }
1084 1110
1111 /* Switch card to HS400 */
1085 val = EXT_CSD_TIMING_HS400 | 1112 val = EXT_CSD_TIMING_HS400 |
1086 card->drive_strength << EXT_CSD_DRV_STR_SHIFT; 1113 card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
1087 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1114 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1088 EXT_CSD_HS_TIMING, val, 1115 EXT_CSD_HS_TIMING, val,
1089 card->ext_csd.generic_cmd6_time, 1116 card->ext_csd.generic_cmd6_time,
1090 true, true, true); 1117 true, send_status, true);
1091 if (err) { 1118 if (err) {
1092 pr_err("%s: switch to hs400 failed, err:%d\n", 1119 pr_err("%s: switch to hs400 failed, err:%d\n",
1093 mmc_hostname(host), err); 1120 mmc_hostname(host), err);
1094 return err; 1121 return err;
1095 } 1122 }
1096 1123
1124 /* Set host controller to HS400 timing and frequency */
1097 mmc_set_timing(host, MMC_TIMING_MMC_HS400); 1125 mmc_set_timing(host, MMC_TIMING_MMC_HS400);
1098 mmc_set_bus_speed(card); 1126 mmc_set_bus_speed(card);
1099 1127
1128 if (!send_status) {
1129 err = mmc_switch_status(card);
1130 if (err)
1131 goto out_err;
1132 }
1133
1100 return 0; 1134 return 0;
1135
1136out_err:
1137 pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
1138 __func__, err);
1139 return err;
1101} 1140}
1102 1141
1103int mmc_hs200_to_hs400(struct mmc_card *card) 1142int mmc_hs200_to_hs400(struct mmc_card *card)
@@ -1105,19 +1144,6 @@ int mmc_hs200_to_hs400(struct mmc_card *card)
1105 return mmc_select_hs400(card); 1144 return mmc_select_hs400(card);
1106} 1145}
1107 1146
1108/* Caller must hold re-tuning */
1109static int mmc_switch_status(struct mmc_card *card)
1110{
1111 u32 status;
1112 int err;
1113
1114 err = mmc_send_status(card, &status);
1115 if (err)
1116 return err;
1117
1118 return mmc_switch_status_error(card->host, status);
1119}
1120
1121int mmc_hs400_to_hs200(struct mmc_card *card) 1147int mmc_hs400_to_hs200(struct mmc_card *card)
1122{ 1148{
1123 struct mmc_host *host = card->host; 1149 struct mmc_host *host = card->host;
@@ -1219,6 +1245,8 @@ static void mmc_select_driver_type(struct mmc_card *card)
1219static int mmc_select_hs200(struct mmc_card *card) 1245static int mmc_select_hs200(struct mmc_card *card)
1220{ 1246{
1221 struct mmc_host *host = card->host; 1247 struct mmc_host *host = card->host;
1248 bool send_status = true;
1249 unsigned int old_timing;
1222 int err = -EINVAL; 1250 int err = -EINVAL;
1223 u8 val; 1251 u8 val;
1224 1252
@@ -1234,6 +1262,9 @@ static int mmc_select_hs200(struct mmc_card *card)
1234 1262
1235 mmc_select_driver_type(card); 1263 mmc_select_driver_type(card);
1236 1264
1265 if (host->caps & MMC_CAP_WAIT_WHILE_BUSY)
1266 send_status = false;
1267
1237 /* 1268 /*
1238 * Set the bus width(4 or 8) with host's support and 1269 * Set the bus width(4 or 8) with host's support and
1239 * switch to HS200 mode if bus width is set successfully. 1270 * switch to HS200 mode if bus width is set successfully.
@@ -1245,11 +1276,25 @@ static int mmc_select_hs200(struct mmc_card *card)
1245 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, 1276 err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
1246 EXT_CSD_HS_TIMING, val, 1277 EXT_CSD_HS_TIMING, val,
1247 card->ext_csd.generic_cmd6_time, 1278 card->ext_csd.generic_cmd6_time,
1248 true, true, true); 1279 true, send_status, true);
1249 if (!err) 1280 if (err)
1250 mmc_set_timing(host, MMC_TIMING_MMC_HS200); 1281 goto err;
1282 old_timing = host->ios.timing;
1283 mmc_set_timing(host, MMC_TIMING_MMC_HS200);
1284 if (!send_status) {
1285 err = mmc_switch_status(card);
1286 /*
1287 * mmc_select_timing() assumes timing has not changed if
1288 * it is a switch error.
1289 */
1290 if (err == -EBADMSG)
1291 mmc_set_timing(host, old_timing);
1292 }
1251 } 1293 }
1252err: 1294err:
1295 if (err)
1296 pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
1297 __func__, err);
1253 return err; 1298 return err;
1254} 1299}
1255 1300