aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Ossman <drzeus@drzeus.cx>2006-11-08 17:03:10 -0500
committerPierre Ossman <drzeus@drzeus.cx>2006-12-01 12:53:37 -0500
commit7ccd266e676a3f0c6f8f897f58b684cac3dd1650 (patch)
treeaba8632fc523c5c663a56876ce67c580ce8d38eb
parent73778120c4088a0a7b59c4c378904f7a230b4820 (diff)
mmc: Support for high speed SD cards
Modern SD cards support a clock speed of 50 MHz. Make sure we test for this capability and do the song and dance required to activate it. Activating high speed support actually modifies the TRAN_SPEED field of the CSD. But as the spec says that the cards must report 50 MHz, we might as well skip re-reading the CSD. Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/mmc.c122
-rw-r--r--include/linux/mmc/card.h7
-rw-r--r--include/linux/mmc/protocol.h22
3 files changed, 146 insertions, 5 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 82b7643c1654..9d190022a490 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1157,6 +1157,116 @@ static void mmc_read_scrs(struct mmc_host *host)
1157 mmc_deselect_cards(host); 1157 mmc_deselect_cards(host);
1158} 1158}
1159 1159
1160static void mmc_read_switch_caps(struct mmc_host *host)
1161{
1162 int err;
1163 struct mmc_card *card;
1164 struct mmc_request mrq;
1165 struct mmc_command cmd;
1166 struct mmc_data data;
1167 unsigned char *status;
1168 struct scatterlist sg;
1169
1170 status = kmalloc(64, GFP_KERNEL);
1171 if (!status) {
1172 printk(KERN_WARNING "%s: Unable to allocate buffer for "
1173 "reading switch capabilities.\n",
1174 mmc_hostname(host));
1175 return;
1176 }
1177
1178 list_for_each_entry(card, &host->cards, node) {
1179 if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
1180 continue;
1181 if (!mmc_card_sd(card))
1182 continue;
1183 if (card->scr.sda_vsn < SCR_SPEC_VER_1)
1184 continue;
1185
1186 err = mmc_select_card(host, card);
1187 if (err != MMC_ERR_NONE) {
1188 mmc_card_set_dead(card);
1189 continue;
1190 }
1191
1192 memset(&cmd, 0, sizeof(struct mmc_command));
1193
1194 cmd.opcode = SD_SWITCH;
1195 cmd.arg = 0x00FFFFF1;
1196 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
1197
1198 memset(&data, 0, sizeof(struct mmc_data));
1199
1200 mmc_set_data_timeout(&data, card, 0);
1201
1202 data.blksz = 64;
1203 data.blocks = 1;
1204 data.flags = MMC_DATA_READ;
1205 data.sg = &sg;
1206 data.sg_len = 1;
1207
1208 memset(&mrq, 0, sizeof(struct mmc_request));
1209
1210 mrq.cmd = &cmd;
1211 mrq.data = &data;
1212
1213 sg_init_one(&sg, status, 64);
1214
1215 mmc_wait_for_req(host, &mrq);
1216
1217 if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
1218 mmc_card_set_dead(card);
1219 continue;
1220 }
1221
1222 if (status[13] & 0x02)
1223 card->sw_caps.hs_max_dtr = 50000000;
1224
1225 memset(&cmd, 0, sizeof(struct mmc_command));
1226
1227 cmd.opcode = SD_SWITCH;
1228 cmd.arg = 0x80FFFFF1;
1229 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
1230
1231 memset(&data, 0, sizeof(struct mmc_data));
1232
1233 mmc_set_data_timeout(&data, card, 0);
1234
1235 data.blksz = 64;
1236 data.blocks = 1;
1237 data.flags = MMC_DATA_READ;
1238 data.sg = &sg;
1239 data.sg_len = 1;
1240
1241 memset(&mrq, 0, sizeof(struct mmc_request));
1242
1243 mrq.cmd = &cmd;
1244 mrq.data = &data;
1245
1246 sg_init_one(&sg, status, 64);
1247
1248 mmc_wait_for_req(host, &mrq);
1249
1250 if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
1251 mmc_card_set_dead(card);
1252 continue;
1253 }
1254
1255 if ((status[16] & 0xF) != 1) {
1256 printk(KERN_WARNING "%s: Problem switching card "
1257 "into high-speed mode!\n",
1258 mmc_hostname(host));
1259 continue;
1260 }
1261
1262 mmc_card_set_highspeed(card);
1263 }
1264
1265 kfree(status);
1266
1267 mmc_deselect_cards(host);
1268}
1269
1160static unsigned int mmc_calculate_clock(struct mmc_host *host) 1270static unsigned int mmc_calculate_clock(struct mmc_host *host)
1161{ 1271{
1162 struct mmc_card *card; 1272 struct mmc_card *card;
@@ -1164,9 +1274,12 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host)
1164 1274
1165 list_for_each_entry(card, &host->cards, node) 1275 list_for_each_entry(card, &host->cards, node)
1166 if (!mmc_card_dead(card)) { 1276 if (!mmc_card_dead(card)) {
1167 if (mmc_card_highspeed(card)) { 1277 if (mmc_card_highspeed(card) && mmc_card_sd(card)) {
1278 if (max_dtr > card->sw_caps.hs_max_dtr)
1279 max_dtr = card->sw_caps.hs_max_dtr;
1280 } else if (mmc_card_highspeed(card) && !mmc_card_sd(card)) {
1168 if (max_dtr > card->ext_csd.hs_max_dtr) 1281 if (max_dtr > card->ext_csd.hs_max_dtr)
1169 max_dtr = card->ext_csd.hs_max_dtr; 1282 max_dtr = card->ext_csd.hs_max_dtr;
1170 } else if (max_dtr > card->csd.max_dtr) { 1283 } else if (max_dtr > card->csd.max_dtr) {
1171 max_dtr = card->csd.max_dtr; 1284 max_dtr = card->csd.max_dtr;
1172 } 1285 }
@@ -1288,9 +1401,10 @@ static void mmc_setup(struct mmc_host *host)
1288 1401
1289 mmc_read_csds(host); 1402 mmc_read_csds(host);
1290 1403
1291 if (host->mode == MMC_MODE_SD) 1404 if (host->mode == MMC_MODE_SD) {
1292 mmc_read_scrs(host); 1405 mmc_read_scrs(host);
1293 else 1406 mmc_read_switch_caps(host);
1407 } else
1294 mmc_process_ext_csds(host); 1408 mmc_process_ext_csds(host);
1295} 1409}
1296 1410
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index ce25256f80d5..d0e6a5497614 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -50,6 +50,10 @@ struct sd_scr {
50#define SD_SCR_BUS_WIDTH_4 (1<<2) 50#define SD_SCR_BUS_WIDTH_4 (1<<2)
51}; 51};
52 52
53struct sd_switch_caps {
54 unsigned int hs_max_dtr;
55};
56
53struct mmc_host; 57struct mmc_host;
54 58
55/* 59/*
@@ -66,7 +70,7 @@ struct mmc_card {
66#define MMC_STATE_BAD (1<<2) /* unrecognised device */ 70#define MMC_STATE_BAD (1<<2) /* unrecognised device */
67#define MMC_STATE_SDCARD (1<<3) /* is an SD card */ 71#define MMC_STATE_SDCARD (1<<3) /* is an SD card */
68#define MMC_STATE_READONLY (1<<4) /* card is read-only */ 72#define MMC_STATE_READONLY (1<<4) /* card is read-only */
69#define MMC_STATE_HIGHSPEED (1<<5) /* card is in mmc4 highspeed mode */ 73#define MMC_STATE_HIGHSPEED (1<<5) /* card is in high speed mode */
70 u32 raw_cid[4]; /* raw card CID */ 74 u32 raw_cid[4]; /* raw card CID */
71 u32 raw_csd[4]; /* raw card CSD */ 75 u32 raw_csd[4]; /* raw card CSD */
72 u32 raw_scr[2]; /* raw card SCR */ 76 u32 raw_scr[2]; /* raw card SCR */
@@ -74,6 +78,7 @@ struct mmc_card {
74 struct mmc_csd csd; /* card specific */ 78 struct mmc_csd csd; /* card specific */
75 struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */ 79 struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */
76 struct sd_scr scr; /* extra SD information */ 80 struct sd_scr scr; /* extra SD information */
81 struct sd_switch_caps sw_caps; /* switch (CMD6) caps */
77}; 82};
78 83
79#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) 84#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h
index 45c51fd85786..2dce60c43f4b 100644
--- a/include/linux/mmc/protocol.h
+++ b/include/linux/mmc/protocol.h
@@ -82,6 +82,7 @@
82 /* class 8 */ 82 /* class 8 */
83/* This is basically the same command as for MMC with some quirks. */ 83/* This is basically the same command as for MMC with some quirks. */
84#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ 84#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
85#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
85 86
86 /* Application commands */ 87 /* Application commands */
87#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ 88#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
@@ -101,6 +102,19 @@
101 */ 102 */
102 103
103/* 104/*
105 * SD_SWITCH argument format:
106 *
107 * [31] Check (0) or switch (1)
108 * [30:24] Reserved (0)
109 * [23:20] Function group 6
110 * [19:16] Function group 5
111 * [15:12] Function group 4
112 * [11:8] Function group 3
113 * [7:4] Function group 2
114 * [3:0] Function group 1
115 */
116
117/*
104 MMC status in R1 118 MMC status in R1
105 Type 119 Type
106 e : error bit 120 e : error bit
@@ -285,6 +299,14 @@ struct _mmc_csd {
285#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ 299#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
286 300
287/* 301/*
302 * SCR field definitions
303 */
304
305#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
306#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
307#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */
308
309/*
288 * SD bus widths 310 * SD bus widths
289 */ 311 */
290#define SD_BUS_WIDTH_1 0 312#define SD_BUS_WIDTH_1 0