diff options
-rw-r--r-- | drivers/mmc/mmc.c | 121 | ||||
-rw-r--r-- | include/linux/mmc/card.h | 8 | ||||
-rw-r--r-- | include/linux/mmc/protocol.h | 47 |
3 files changed, 171 insertions, 5 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 766bc54406e5..2d5b93000dee 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. | 4 | * Copyright (C) 2003-2004 Russell King, All Rights Reserved. |
5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. | 5 | * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. |
6 | * SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved. | 6 | * SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved. |
7 | * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -953,6 +954,114 @@ static void mmc_read_csds(struct mmc_host *host) | |||
953 | } | 954 | } |
954 | } | 955 | } |
955 | 956 | ||
957 | static void mmc_process_ext_csds(struct mmc_host *host) | ||
958 | { | ||
959 | int err; | ||
960 | struct mmc_card *card; | ||
961 | |||
962 | struct mmc_request mrq; | ||
963 | struct mmc_command cmd; | ||
964 | struct mmc_data data; | ||
965 | |||
966 | struct scatterlist sg; | ||
967 | |||
968 | /* | ||
969 | * As the ext_csd is so large and mostly unused, we don't store the | ||
970 | * raw block in mmc_card. | ||
971 | */ | ||
972 | u8 *ext_csd; | ||
973 | ext_csd = kmalloc(512, GFP_KERNEL); | ||
974 | if (!ext_csd) { | ||
975 | printk("%s: could not allocate a buffer to receive the ext_csd." | ||
976 | "mmc v4 cards will be treated as v3.\n", | ||
977 | mmc_hostname(host)); | ||
978 | return; | ||
979 | } | ||
980 | |||
981 | list_for_each_entry(card, &host->cards, node) { | ||
982 | if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) | ||
983 | continue; | ||
984 | if (mmc_card_sd(card)) | ||
985 | continue; | ||
986 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | ||
987 | continue; | ||
988 | |||
989 | err = mmc_select_card(host, card); | ||
990 | if (err != MMC_ERR_NONE) { | ||
991 | mmc_card_set_dead(card); | ||
992 | continue; | ||
993 | } | ||
994 | |||
995 | memset(&cmd, 0, sizeof(struct mmc_command)); | ||
996 | |||
997 | cmd.opcode = MMC_SEND_EXT_CSD; | ||
998 | cmd.arg = 0; | ||
999 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | ||
1000 | |||
1001 | memset(&data, 0, sizeof(struct mmc_data)); | ||
1002 | |||
1003 | mmc_set_data_timeout(&data, card, 0); | ||
1004 | |||
1005 | data.blksz = 512; | ||
1006 | data.blocks = 1; | ||
1007 | data.flags = MMC_DATA_READ; | ||
1008 | data.sg = &sg; | ||
1009 | data.sg_len = 1; | ||
1010 | |||
1011 | memset(&mrq, 0, sizeof(struct mmc_request)); | ||
1012 | |||
1013 | mrq.cmd = &cmd; | ||
1014 | mrq.data = &data; | ||
1015 | |||
1016 | sg_init_one(&sg, ext_csd, 512); | ||
1017 | |||
1018 | mmc_wait_for_req(host, &mrq); | ||
1019 | |||
1020 | if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { | ||
1021 | mmc_card_set_dead(card); | ||
1022 | continue; | ||
1023 | } | ||
1024 | |||
1025 | switch (ext_csd[EXT_CSD_CARD_TYPE]) { | ||
1026 | case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: | ||
1027 | card->ext_csd.hs_max_dtr = 52000000; | ||
1028 | break; | ||
1029 | case EXT_CSD_CARD_TYPE_26: | ||
1030 | card->ext_csd.hs_max_dtr = 26000000; | ||
1031 | break; | ||
1032 | default: | ||
1033 | /* MMC v4 spec says this cannot happen */ | ||
1034 | printk("%s: card is mmc v4 but doesn't support " | ||
1035 | "any high-speed modes.\n", | ||
1036 | mmc_hostname(card->host)); | ||
1037 | mmc_card_set_bad(card); | ||
1038 | continue; | ||
1039 | } | ||
1040 | |||
1041 | /* Activate highspeed support. */ | ||
1042 | cmd.opcode = MMC_SWITCH; | ||
1043 | cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | | ||
1044 | (EXT_CSD_HS_TIMING << 16) | | ||
1045 | (1 << 8) | | ||
1046 | EXT_CSD_CMD_SET_NORMAL; | ||
1047 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
1048 | |||
1049 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | ||
1050 | if (err != MMC_ERR_NONE) { | ||
1051 | printk("%s: failed to switch card to mmc v4 " | ||
1052 | "high-speed mode.\n", | ||
1053 | mmc_hostname(card->host)); | ||
1054 | continue; | ||
1055 | } | ||
1056 | |||
1057 | mmc_card_set_highspeed(card); | ||
1058 | } | ||
1059 | |||
1060 | kfree(ext_csd); | ||
1061 | |||
1062 | mmc_deselect_cards(host); | ||
1063 | } | ||
1064 | |||
956 | static void mmc_read_scrs(struct mmc_host *host) | 1065 | static void mmc_read_scrs(struct mmc_host *host) |
957 | { | 1066 | { |
958 | int err; | 1067 | int err; |
@@ -1031,8 +1140,14 @@ static unsigned int mmc_calculate_clock(struct mmc_host *host) | |||
1031 | unsigned int max_dtr = host->f_max; | 1140 | unsigned int max_dtr = host->f_max; |
1032 | 1141 | ||
1033 | list_for_each_entry(card, &host->cards, node) | 1142 | list_for_each_entry(card, &host->cards, node) |
1034 | if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr) | 1143 | if (!mmc_card_dead(card)) { |
1035 | max_dtr = card->csd.max_dtr; | 1144 | if (mmc_card_highspeed(card)) { |
1145 | if (max_dtr > card->ext_csd.hs_max_dtr) | ||
1146 | max_dtr = card->ext_csd.hs_max_dtr; | ||
1147 | } else if (max_dtr > card->csd.max_dtr) { | ||
1148 | max_dtr = card->csd.max_dtr; | ||
1149 | } | ||
1150 | } | ||
1036 | 1151 | ||
1037 | pr_debug("%s: selected %d.%03dMHz transfer rate\n", | 1152 | pr_debug("%s: selected %d.%03dMHz transfer rate\n", |
1038 | mmc_hostname(host), | 1153 | mmc_hostname(host), |
@@ -1152,6 +1267,8 @@ static void mmc_setup(struct mmc_host *host) | |||
1152 | 1267 | ||
1153 | if (host->mode == MMC_MODE_SD) | 1268 | if (host->mode == MMC_MODE_SD) |
1154 | mmc_read_scrs(host); | 1269 | mmc_read_scrs(host); |
1270 | else | ||
1271 | mmc_process_ext_csds(host); | ||
1155 | } | 1272 | } |
1156 | 1273 | ||
1157 | 1274 | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 991a37382a22..ce25256f80d5 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -39,6 +39,10 @@ struct mmc_csd { | |||
39 | write_misalign:1; | 39 | write_misalign:1; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct mmc_ext_csd { | ||
43 | unsigned int hs_max_dtr; | ||
44 | }; | ||
45 | |||
42 | struct sd_scr { | 46 | struct sd_scr { |
43 | unsigned char sda_vsn; | 47 | unsigned char sda_vsn; |
44 | unsigned char bus_widths; | 48 | unsigned char bus_widths; |
@@ -62,11 +66,13 @@ struct mmc_card { | |||
62 | #define MMC_STATE_BAD (1<<2) /* unrecognised device */ | 66 | #define MMC_STATE_BAD (1<<2) /* unrecognised device */ |
63 | #define MMC_STATE_SDCARD (1<<3) /* is an SD card */ | 67 | #define MMC_STATE_SDCARD (1<<3) /* is an SD card */ |
64 | #define MMC_STATE_READONLY (1<<4) /* card is read-only */ | 68 | #define MMC_STATE_READONLY (1<<4) /* card is read-only */ |
69 | #define MMC_STATE_HIGHSPEED (1<<5) /* card is in mmc4 highspeed mode */ | ||
65 | u32 raw_cid[4]; /* raw card CID */ | 70 | u32 raw_cid[4]; /* raw card CID */ |
66 | u32 raw_csd[4]; /* raw card CSD */ | 71 | u32 raw_csd[4]; /* raw card CSD */ |
67 | u32 raw_scr[2]; /* raw card SCR */ | 72 | u32 raw_scr[2]; /* raw card SCR */ |
68 | struct mmc_cid cid; /* card identification */ | 73 | struct mmc_cid cid; /* card identification */ |
69 | struct mmc_csd csd; /* card specific */ | 74 | struct mmc_csd csd; /* card specific */ |
75 | struct mmc_ext_csd ext_csd; /* mmc v4 extended card specific */ | ||
70 | struct sd_scr scr; /* extra SD information */ | 76 | struct sd_scr scr; /* extra SD information */ |
71 | }; | 77 | }; |
72 | 78 | ||
@@ -75,12 +81,14 @@ struct mmc_card { | |||
75 | #define mmc_card_bad(c) ((c)->state & MMC_STATE_BAD) | 81 | #define mmc_card_bad(c) ((c)->state & MMC_STATE_BAD) |
76 | #define mmc_card_sd(c) ((c)->state & MMC_STATE_SDCARD) | 82 | #define mmc_card_sd(c) ((c)->state & MMC_STATE_SDCARD) |
77 | #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) | 83 | #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) |
84 | #define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED) | ||
78 | 85 | ||
79 | #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) | 86 | #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) |
80 | #define mmc_card_set_dead(c) ((c)->state |= MMC_STATE_DEAD) | 87 | #define mmc_card_set_dead(c) ((c)->state |= MMC_STATE_DEAD) |
81 | #define mmc_card_set_bad(c) ((c)->state |= MMC_STATE_BAD) | 88 | #define mmc_card_set_bad(c) ((c)->state |= MMC_STATE_BAD) |
82 | #define mmc_card_set_sd(c) ((c)->state |= MMC_STATE_SDCARD) | 89 | #define mmc_card_set_sd(c) ((c)->state |= MMC_STATE_SDCARD) |
83 | #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) | 90 | #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) |
91 | #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED) | ||
84 | 92 | ||
85 | #define mmc_card_name(c) ((c)->cid.prod_name) | 93 | #define mmc_card_name(c) ((c)->cid.prod_name) |
86 | #define mmc_card_id(c) ((c)->dev.bus_id) | 94 | #define mmc_card_id(c) ((c)->dev.bus_id) |
diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h index 08dec8d9e703..311b6547f561 100644 --- a/include/linux/mmc/protocol.h +++ b/include/linux/mmc/protocol.h | |||
@@ -25,14 +25,16 @@ | |||
25 | #ifndef MMC_MMC_PROTOCOL_H | 25 | #ifndef MMC_MMC_PROTOCOL_H |
26 | #define MMC_MMC_PROTOCOL_H | 26 | #define MMC_MMC_PROTOCOL_H |
27 | 27 | ||
28 | /* Standard MMC commands (3.1) type argument response */ | 28 | /* Standard MMC commands (4.1) type argument response */ |
29 | /* class 1 */ | 29 | /* class 1 */ |
30 | #define MMC_GO_IDLE_STATE 0 /* bc */ | 30 | #define MMC_GO_IDLE_STATE 0 /* bc */ |
31 | #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ | 31 | #define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */ |
32 | #define MMC_ALL_SEND_CID 2 /* bcr R2 */ | 32 | #define MMC_ALL_SEND_CID 2 /* bcr R2 */ |
33 | #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ | 33 | #define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */ |
34 | #define MMC_SET_DSR 4 /* bc [31:16] RCA */ | 34 | #define MMC_SET_DSR 4 /* bc [31:16] RCA */ |
35 | #define MMC_SWITCH 6 /* ac [31:0] See below R1b */ | ||
35 | #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ | 36 | #define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */ |
37 | #define MMC_SEND_EXT_CSD 8 /* adtc R1 */ | ||
36 | #define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ | 38 | #define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */ |
37 | #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ | 39 | #define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */ |
38 | #define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ | 40 | #define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */ |
@@ -88,6 +90,17 @@ | |||
88 | #define SD_APP_SEND_SCR 51 /* adtc R1 */ | 90 | #define SD_APP_SEND_SCR 51 /* adtc R1 */ |
89 | 91 | ||
90 | /* | 92 | /* |
93 | * MMC_SWITCH argument format: | ||
94 | * | ||
95 | * [31:26] Always 0 | ||
96 | * [25:24] Access Mode | ||
97 | * [23:16] Location of target Byte in EXT_CSD | ||
98 | * [15:08] Value Byte | ||
99 | * [07:03] Always 0 | ||
100 | * [02:00] Command Set | ||
101 | */ | ||
102 | |||
103 | /* | ||
91 | MMC status in R1 | 104 | MMC status in R1 |
92 | Type | 105 | Type |
93 | e : error bit | 106 | e : error bit |
@@ -230,13 +243,41 @@ struct _mmc_csd { | |||
230 | 243 | ||
231 | #define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ | 244 | #define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */ |
232 | #define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ | 245 | #define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */ |
233 | #define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 */ | 246 | #define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */ |
247 | #define CSD_STRUCT_EXT_CSD 3 /* Version is coded in CSD_STRUCTURE in EXT_CSD */ | ||
234 | 248 | ||
235 | #define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */ | 249 | #define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */ |
236 | #define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */ | 250 | #define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */ |
237 | #define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ | 251 | #define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */ |
238 | #define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */ | 252 | #define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 - 3.2 - 3.31 */ |
253 | #define CSD_SPEC_VER_4 4 /* Implements system specification 4.0 - 4.1 */ | ||
254 | |||
255 | /* | ||
256 | * EXT_CSD fields | ||
257 | */ | ||
258 | |||
259 | #define EXT_CSD_HS_TIMING 185 /* R/W */ | ||
260 | #define EXT_CSD_CARD_TYPE 196 /* RO */ | ||
261 | |||
262 | /* | ||
263 | * EXT_CSD field definitions | ||
264 | */ | ||
265 | |||
266 | #define EXT_CSD_CMD_SET_NORMAL (1<<0) | ||
267 | #define EXT_CSD_CMD_SET_SECURE (1<<1) | ||
268 | #define EXT_CSD_CMD_SET_CPSECURE (1<<2) | ||
269 | |||
270 | #define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ | ||
271 | #define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ | ||
272 | |||
273 | /* | ||
274 | * MMC_SWITCH access modes | ||
275 | */ | ||
239 | 276 | ||
277 | #define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ | ||
278 | #define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */ | ||
279 | #define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */ | ||
280 | #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ | ||
240 | 281 | ||
241 | /* | 282 | /* |
242 | * SD bus widths | 283 | * SD bus widths |