blob: 2ab4185270f65687c09a6f3b04e8fb3f2f3dedb2 [file] [log] [blame]
Johan RUDHOLMa8bfde72012-02-12 11:46:44 -05001/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public
4 * License v2 as published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 * General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public
12 * License along with this program; if not, write to the
13 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
14 * Boston, MA 021110-1307, USA.
15 */
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <sys/ioctl.h>
21#include <sys/types.h>
22#include <dirent.h>
23#include <sys/stat.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <libgen.h>
27#include <limits.h>
Johan RUDHOLMa8bfde72012-02-12 11:46:44 -050028#include <ctype.h>
29
30#include "mmc.h"
31#include "mmc_cmds.h"
32
33int read_extcsd(int fd, __u8 *ext_csd)
34{
35 int ret = 0;
36 struct mmc_ioc_cmd idata;
37 memset(&idata, 0, sizeof(idata));
38 memset(ext_csd, 0, sizeof(__u8) * 512);
39 idata.write_flag = 0;
40 idata.opcode = MMC_SEND_EXT_CSD;
41 idata.arg = 0;
42 idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
43 idata.blksz = 512;
44 idata.blocks = 1;
45 mmc_ioc_cmd_set_data(idata, ext_csd);
46
47 ret = ioctl(fd, MMC_IOC_CMD, &idata);
48 if (ret)
49 perror("ioctl");
50
51 return ret;
52}
53
54int write_extcsd_value(int fd, __u8 index, __u8 value)
55{
56 int ret = 0;
57 struct mmc_ioc_cmd idata;
58
59 memset(&idata, 0, sizeof(idata));
60 idata.write_flag = 1;
61 idata.opcode = MMC_SWITCH;
62 idata.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
63 (index << 16) |
64 (value << 8) |
65 EXT_CSD_CMD_SET_NORMAL;
66 idata.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
67
68 ret = ioctl(fd, MMC_IOC_CMD, &idata);
69 if (ret)
70 perror("ioctl");
71
72 return ret;
73}
74
Chris Ballb9c7a172012-02-20 12:34:25 -050075void print_writeprotect_status(__u8 *ext_csd)
76{
77 __u8 reg;
78 __u8 ext_csd_rev = ext_csd[192];
79
80 /* A43: reserved [174:0] */
81 if (ext_csd_rev >= 5) {
82 printf("Boot write protection status registers"
83 " [BOOT_WP_STATUS]: 0x%02x\n", ext_csd[174]);
84
85 reg = ext_csd[EXT_CSD_BOOT_WP];
86 printf("Boot Area Write protection [BOOT_WP]: 0x%02x\n", reg);
87 printf(" Power ro locking: ");
88 if (reg & EXT_CSD_BOOT_WP_B_PWR_WP_DIS)
89 printf("not possible\n");
90 else
91 printf("possible\n");
92
93 printf(" Permanent ro locking: ");
94 if (reg & EXT_CSD_BOOT_WP_B_PERM_WP_DIS)
95 printf("not possible\n");
96 else
97 printf("possible\n");
98
99 printf(" ro lock status: ");
100 if (reg & EXT_CSD_BOOT_WP_B_PWR_WP_EN)
101 printf("locked until next power on\n");
102 else if (reg & EXT_CSD_BOOT_WP_B_PERM_WP_EN)
103 printf("locked permanently\n");
104 else
105 printf("not locked\n");
106 }
107}
108
109int do_writeprotect_get(int nargs, char **argv)
110{
111 __u8 ext_csd[512];
112 int fd, ret;
113 char *device;
114
115 CHECK(nargs != 2, "Usage: mmc </path/to/mmcblkX>\n", exit(1));
116
117 device = argv[1];
118
119 fd = open(device, O_RDWR);
120 if (fd < 0) {
121 perror("open");
122 exit(1);
123 }
124
125 ret = read_extcsd(fd, ext_csd);
126 if (ret) {
127 fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
128 exit(1);
129 }
130
131 print_writeprotect_status(ext_csd);
132
133 return ret;
134}
135
136int do_writeprotect_set(int nargs, char **argv)
137{
138 __u8 ext_csd[512], value;
139 int fd, ret;
140 char *device;
141
142 CHECK(nargs != 2, "Usage: mmc </path/to/mmcblkX>\n", exit(1));
143
144 device = argv[1];
145
146 fd = open(device, O_RDWR);
147 if (fd < 0) {
148 perror("open");
149 exit(1);
150 }
151
152 ret = read_extcsd(fd, ext_csd);
153 if (ret) {
154 fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
155 exit(1);
156 }
157
158 value = ext_csd[EXT_CSD_BOOT_WP] |
159 EXT_CSD_BOOT_WP_B_PWR_WP_EN;
160 ret = write_extcsd_value(fd, EXT_CSD_BOOT_WP, value);
161 if (ret) {
162 fprintf(stderr, "Could not write 0x%02x to "
163 "EXT_CSD[%d] in %s\n",
164 value, EXT_CSD_BOOT_WP, device);
165 exit(1);
166 }
167
168 return ret;
169}
170
Giuseppe CAVALLARO7bd13202012-04-19 10:58:37 +0200171int do_write_boot_en(int nargs, char **argv)
172{
173 __u8 ext_csd[512];
174 __u8 value = 0;
175 int fd, ret;
176 char *device;
177 int boot_area, send_ack;
178
179 CHECK(nargs != 4, "Usage: mmc bootpart enable <partition_number> "
180 "<send_ack> </path/to/mmcblkX>\n", exit(1));
181
182 /*
183 * If <send_ack> is 1, the device will send acknowledgment
184 * pattern "010" to the host when boot operation begins.
185 * If <send_ack> is 0, it won't.
186 */
187 boot_area = strtol(argv[1], NULL, 10);
188 send_ack = strtol(argv[2], NULL, 10);
189 device = argv[3];
190
191 fd = open(device, O_RDWR);
192 if (fd < 0) {
193 perror("open");
194 exit(1);
195 }
196
197 ret = read_extcsd(fd, ext_csd);
198 if (ret) {
199 fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
200 exit(1);
201 }
202
203 value = ext_csd[EXT_CSD_PART_CONFIG];
204
205 switch (boot_area) {
206 case EXT_CSD_PART_CONFIG_ACC_BOOT0:
207 value |= (1 << 3);
208 value &= ~(3 << 4);
209 break;
210 case EXT_CSD_PART_CONFIG_ACC_BOOT1:
211 value |= (1 << 4);
212 value &= ~(1 << 3);
213 value &= ~(1 << 5);
214 break;
215 case EXT_CSD_PART_CONFIG_ACC_USER_AREA:
216 value |= (boot_area << 3);
217 break;
218 default:
219 fprintf(stderr, "Cannot enable the boot area\n");
220 exit(1);
221 }
222 if (send_ack)
223 value |= EXT_CSD_PART_CONFIG_ACC_ACK;
224 else
225 value &= ~EXT_CSD_PART_CONFIG_ACC_ACK;
226
227 ret = write_extcsd_value(fd, EXT_CSD_PART_CONFIG, value);
228 if (ret) {
229 fprintf(stderr, "Could not write 0x%02x to "
230 "EXT_CSD[%d] in %s\n",
231 value, EXT_CSD_PART_CONFIG, device);
232 exit(1);
233 }
234 return ret;
235}
236
237
Johan RUDHOLMa8bfde72012-02-12 11:46:44 -0500238int do_read_extcsd(int nargs, char **argv)
239{
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100240 __u8 ext_csd[512], ext_csd_rev, reg;
Johan RUDHOLMa8bfde72012-02-12 11:46:44 -0500241 int fd, ret;
242 char *device;
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100243 const char *str;
Johan RUDHOLMa8bfde72012-02-12 11:46:44 -0500244
245 CHECK(nargs != 2, "Usage: mmc </path/to/mmcblkX>\n", exit(1));
246
247 device = argv[1];
248
249 fd = open(device, O_RDWR);
250 if (fd < 0) {
251 perror("open");
252 exit(1);
253 }
254
255 ret = read_extcsd(fd, ext_csd);
256 if (ret) {
257 fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
258 exit(1);
259 }
260
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100261 ext_csd_rev = ext_csd[192];
262
263 switch (ext_csd_rev) {
264 case 6:
265 str = "4.5";
266 break;
267 case 5:
268 str = "4.41";
269 break;
270 case 3:
271 str = "4.3";
272 break;
273 case 2:
274 str = "4.2";
275 break;
276 case 1:
277 str = "4.1";
278 break;
279 case 0:
280 str = "4.0";
281 break;
282 default:
283 goto out_free;
284 }
285 printf("=============================================\n");
286 printf(" Extended CSD rev 1.%d (MMC %s)\n", ext_csd_rev, str);
287 printf("=============================================\n\n");
288
289 if (ext_csd_rev < 3)
290 goto out_free; /* No ext_csd */
291
292 /* Parse the Extended CSD registers.
293 * Reserved bit should be read as "0" in case of spec older
294 * than A441.
295 */
296 reg = ext_csd[EXT_CSD_S_CMD_SET];
297 printf("Card Supported Command sets [S_CMD_SET: 0x%02x]\n", reg);
298 if (!reg)
Chris Ballb9c7a172012-02-20 12:34:25 -0500299 printf(" - Standard MMC command sets\n");
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100300
301 reg = ext_csd[EXT_CSD_HPI_FEATURE];
302 printf("HPI Features [HPI_FEATURE: 0x%02x]: ", reg);
303 if (reg & EXT_CSD_HPI_SUPP) {
304 if (reg & EXT_CSD_HPI_IMPL)
Chris Ballb9c7a172012-02-20 12:34:25 -0500305 printf("implementation based on CMD12\n");
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100306 else
307 printf("implementation based on CMD13\n");
308 }
309
310 printf("Background operations support [BKOPS_SUPPORT: 0x%02x]\n",
311 ext_csd[502]);
312
313 if (ext_csd_rev >= 6) {
314 printf("Max Packet Read Cmd [MAX_PACKED_READS: 0x%02x]\n",
315 ext_csd[501]);
316 printf("Max Packet Write Cmd [MAX_PACKED_WRITES: 0x%02x]\n",
317 ext_csd[500]);
318 printf("Data TAG support [DATA_TAG_SUPPORT: 0x%02x]\n",
319 ext_csd[499]);
320
321 printf("Data TAG Unit Size [TAG_UNIT_SIZE: 0x%02x]\n",
322 ext_csd[498]);
323 printf("Tag Resources Size [TAG_RES_SIZE: 0x%02x]\n",
324 ext_csd[497]);
325 printf("Context Management Capabilities"
326 " [CONTEXT_CAPABILITIES: 0x%02x]\n", ext_csd[496]);
327 printf("Large Unit Size [LARGE_UNIT_SIZE_M1: 0x%02x]\n",
328 ext_csd[495]);
329 printf("Extended partition attribute support"
330 " [EXT_SUPPORT: 0x%02x]\n", ext_csd[494]);
331 printf("Generic CMD6 Timer [GENERIC_CMD6_TIME: 0x%02x]\n",
332 ext_csd[248]);
333 printf("Power off notification [POWER_OFF_LONG_TIME: 0x%02x]\n",
334 ext_csd[247]);
335 printf("Cache Size [CACHE_SIZE] is %d KiB\n",
336 ext_csd[249] << 0 | (ext_csd[250] << 8) |
337 (ext_csd[251] << 16) | (ext_csd[252] << 24));
338 }
339
340 /* A441: Reserved [501:247]
341 A43: reserved [246:229] */
342 if (ext_csd_rev >= 5) {
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100343 printf("Background operations status"
Chris Ballb9c7a172012-02-20 12:34:25 -0500344 " [BKOPS_STATUS: 0x%02x]\n", ext_csd[246]);
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100345
346 /* CORRECTLY_PRG_SECTORS_NUM [245:242] TODO */
347
348 printf("1st Initialisation Time after programmed sector"
349 " [INI_TIMEOUT_AP: 0x%02x]\n", ext_csd[241]);
350
351 /* A441: reserved [240] */
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100352 printf("Power class for 52MHz, DDR at 3.6V"
353 " [PWR_CL_DDR_52_360: 0x%02x]\n", ext_csd[239]);
354 printf("Power class for 52MHz, DDR at 1.95V"
355 " [PWR_CL_DDR_52_195: 0x%02x]\n", ext_csd[238]);
356
357 /* A441: reserved [237-236] */
358
359 if (ext_csd_rev >= 6) {
360 printf("Power class for 200MHz at 3.6V"
361 " [PWR_CL_200_360: 0x%02x]\n", ext_csd[237]);
362 printf("Power class for 200MHz, at 1.95V"
363 " [PWR_CL_200_195: 0x%02x]\n", ext_csd[236]);
364 }
Chris Ballb9c7a172012-02-20 12:34:25 -0500365 printf("Minimum Performance for 8bit at 52MHz in DDR mode:\n");
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100366 printf(" [MIN_PERF_DDR_W_8_52: 0x%02x]\n", ext_csd[235]);
367 printf(" [MIN_PERF_DDR_R_8_52: 0x%02x]\n", ext_csd[234]);
368 /* A441: reserved [233] */
369 printf("TRIM Multiplier [TRIM_MULT: 0x%02x]\n", ext_csd[232]);
370 printf("Secure Feature support [SEC_FEATURE_SUPPORT: 0x%02x]\n",
371 ext_csd[231]);
372 }
373 if (ext_csd_rev == 5) { /* Obsolete in 4.5 */
374 printf("Secure Erase Multiplier [SEC_ERASE_MULT: 0x%02x]\n",
375 ext_csd[230]);
376 printf("Secure TRIM Multiplier [SEC_TRIM_MULT: 0x%02x]\n",
377 ext_csd[229]);
378 }
379 reg = ext_csd[EXT_CSD_BOOT_INFO];
380 printf("Boot Information [BOOT_INFO: 0x%02x]\n", reg);
381 if (reg & EXT_CSD_BOOT_INFO_ALT)
382 printf(" Device supports alternative boot method\n");
383 if (reg & EXT_CSD_BOOT_INFO_DDR_DDR)
384 printf(" Device supports dual data rate during boot\n");
385 if (reg & EXT_CSD_BOOT_INFO_HS_MODE)
386 printf(" Device supports high speed timing during boot\n");
387
388 /* A441/A43: reserved [227] */
389 printf("Boot partition size [BOOT_SIZE_MULTI: 0x%02x]\n", ext_csd[226]);
390 printf("Access size [ACC_SIZE: 0x%02x]\n", ext_csd[225]);
391 printf("High-capacity erase unit size [HC_ERASE_GRP_SIZE: 0x%02x]\n",
392 ext_csd[224]);
393 printf("High-capacity erase timeout [ERASE_TIMEOUT_MULT: 0x%02x]\n",
394 ext_csd[223]);
395 printf("Reliable write sector count [REL_WR_SEC_C: 0x%02x]\n",
396 ext_csd[222]);
397 printf("High-capacity W protect group size [HC_WP_GRP_SIZE: 0x%02x]\n",
398 ext_csd[221]);
399 printf("Sleep current (VCC) [S_C_VCC: 0x%02x]\n", ext_csd[220]);
400 printf("Sleep current (VCCQ) [S_C_VCCQ: 0x%02x]\n", ext_csd[219]);
401 /* A441/A43: reserved [218] */
402 printf("Sleep/awake timeout [S_A_TIMEOUT: 0x%02x]\n", ext_csd[217]);
403 /* A441/A43: reserved [216] */
404 printf("Sector Count [SEC_COUNT: 0x%08x]\n", (ext_csd[215] << 24) |
405 (ext_csd[214] << 16) | (ext_csd[213] << 8) |
406 ext_csd[212]);
407 /* A441/A43: reserved [211] */
408 printf("Minimum Write Performance for 8bit:\n");
409 printf(" [MIN_PERF_W_8_52: 0x%02x]\n", ext_csd[210]);
410 printf(" [MIN_PERF_R_8_52: 0x%02x]\n", ext_csd[209]);
411 printf(" [MIN_PERF_W_8_26_4_52: 0x%02x]\n", ext_csd[208]);
412 printf(" [MIN_PERF_R_8_26_4_52: 0x%02x]\n", ext_csd[207]);
413 printf("Minimum Write Performance for 4bit:\n");
414 printf(" [MIN_PERF_W_4_26: 0x%02x]\n", ext_csd[206]);
415 printf(" [MIN_PERF_R_4_26: 0x%02x]\n", ext_csd[205]);
416 /* A441/A43: reserved [204] */
417 printf("Power classes registers:\n");
418 printf(" [PWR_CL_26_360: 0x%02x]\n", ext_csd[203]);
419 printf(" [PWR_CL_52_360: 0x%02x]\n", ext_csd[202]);
420 printf(" [PWR_CL_26_195: 0x%02x]\n", ext_csd[201]);
421 printf(" [PWR_CL_52_195: 0x%02x]\n", ext_csd[200]);
422
423 /* A43: reserved [199:198] */
424 if (ext_csd_rev >= 5) {
425 printf("Partition switching timing "
426 "[PARTITION_SWITCH_TIME: 0x%02x]\n", ext_csd[199]);
427 printf("Out-of-interrupt busy timing"
428 " [OUT_OF_INTERRUPT_TIME: 0x%02x]\n", ext_csd[198]);
429 }
430
431 /* A441/A43: reserved [197] [195] [193] [190] [188]
432 * [186] [184] [182] [180] [176] */
433
434 if (ext_csd_rev >= 6)
435 printf("I/O Driver Strength [DRIVER_STRENGTH: 0x%02x]\n",
436 ext_csd[197]);
437
438 printf("Card Type [CARD_TYPE: 0x%02x]\n", ext_csd[196]);
439 /* DEVICE_TYPE in A45 */
440 switch (reg) {
441 case 5:
442 printf("HS200 Single Data Rate eMMC @200MHz 1.2VI/O\n");
443 break;
444 case 4:
445 printf("HS200 Single Data Rate eMMC @200MHz 1.8VI/O\n");
446 break;
447 case 3:
448 printf("HS Dual Data Rate eMMC @52MHz 1.2VI/O\n");
449
450 break;
451 case 2:
452 printf("HS Dual Data Rate eMMC @52MHz 1.8V or 3VI/O\n");
453 break;
454 case 1:
455 printf("HS eMMC @52MHz - at rated device voltage(s)\n");
456 break;
457 case 0:
458 printf("HS eMMC @26MHz - at rated device voltage(s)\n");
459 break;
460 }
461 printf("CSD structure version [CSD_STRUCTURE: 0x%02x]\n", ext_csd[194]);
462 /* ext_csd_rev = ext_csd[192] (already done!!!) */
463 printf("Command set [CMD_SET: 0x%02x]\n", ext_csd[191]);
464 printf("Command set revision [CMD_SET_REV: 0x%02x]\n", ext_csd[189]);
465 printf("Power class [POWER_CLASS: 0x%02x]\n", ext_csd[187]);
466 printf("High-speed interface timing [HS_TIMING: 0x%02x]\n",
467 ext_csd[185]);
468 /* bus_width: ext_csd[183] not readable */
469 printf("Erased memory content [ERASED_MEM_CONT: 0x%02x]\n",
470 ext_csd[181]);
471 reg = ext_csd[EXT_CSD_BOOT_CFG];
472 printf("Boot configuration bytes [PARTITION_CONFIG: 0x%02x]\n", reg);
473 switch (reg & EXT_CSD_BOOT_CFG_EN) {
474 case 0x0:
475 printf(" Not boot enable\n");
476 break;
477 case 0x1:
478 printf(" Boot Partition 1 enabled\n");
479 break;
480 case 0x2:
481 printf(" Boot Partition 2 enabled\n");
482 break;
483 case 0x7:
484 printf(" User Area Enabled for boot\n");
485 break;
486 }
487 switch (reg & EXT_CSD_BOOT_CFG_ACC) {
488 case 0x0:
489 printf(" No access to boot partition\n");
490 break;
491 case 0x1:
492 printf(" R/W Boot Partition 1\n");
493 break;
494 case 0x2:
495 printf(" R/W Boot Partition 2\n");
496 break;
497 default:
498 printf(" Access to General Purpuse partition %d\n",
499 (reg & EXT_CSD_BOOT_CFG_ACC) - 3);
500 break;
501 }
502
503 printf("Boot config protection [BOOT_CONFIG_PROT: 0x%02x]\n",
504 ext_csd[178]);
505 printf("Boot bus Conditions [BOOT_BUS_CONDITIONS: 0x%02x]\n",
506 ext_csd[177]);
507 printf("High-density erase group definition"
508 " [ERASE_GROUP_DEF: 0x%02x]\n", ext_csd[175]);
509
Chris Ballb9c7a172012-02-20 12:34:25 -0500510 print_writeprotect_status(ext_csd);
511
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100512 if (ext_csd_rev >= 5) {
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100513 /* A441]: reserved [172] */
514 printf("User area write protection register"
515 " [USER_WP]: 0x%02x\n", ext_csd[171]);
516 /* A441]: reserved [170] */
517 printf("FW configuration [FW_CONFIG]: 0x%02x\n", ext_csd[169]);
518 printf("RPMB Size [RPMB_SIZE_MULT]: 0x%02x\n", ext_csd[168]);
519 printf("Write reliability setting register"
520 " [WR_REL_SET]: 0x%02x\n", ext_csd[167]);
521 printf("Write reliability parameter register"
522 " [WR_REL_PARAM]: 0x%02x\n", ext_csd[166]);
523 /* sanitize_start ext_csd[165]]: not readable
524 * bkops_start ext_csd[164]]: only writable */
525 printf("Enable background operations handshake"
526 " [BKOPS_EN]: 0x%02x\n", ext_csd[163]);
527 printf("H/W reset function"
528 " [RST_N_FUNCTION]: 0x%02x\n", ext_csd[162]);
529 printf("HPI management [HPI_MGMT]: 0x%02x\n", ext_csd[161]);
530 reg = ext_csd[160];
531 printf("Partitioning Support [PARTITIONING_SUPPORT]: 0x%02x\n",
532 reg);
533 if (reg & 0x1)
534 printf(" Device support partitioning feature\n");
535 else
536 printf(" Device NOT support partitioning feature\n");
537 if (reg & 0x2)
538 printf(" Device can have enhanced tech.\n");
539 else
540 printf(" Device cannot have enhanced tech.\n");
541
542 printf("Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x%06x\n",
543 (ext_csd[159] << 16) | (ext_csd[158] << 8) |
544 ext_csd[157]);
545 printf("Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x%02x\n",
546 ext_csd[156]);
547 printf("Partitioning Setting"
548 " [PARTITION_SETTING_COMPLETED]: 0x%02x\n",
549 ext_csd[155]);
550 printf("General Purpose Partition Size\n"
551 " [GP_SIZE_MULT_4]: 0x%06x\n", (ext_csd[154] << 16) |
552 (ext_csd[153] << 8) | ext_csd[152]);
553 printf(" [GP_SIZE_MULT_3]: 0x%06x\n", (ext_csd[151] << 16) |
554 (ext_csd[150] << 8) | ext_csd[149]);
555 printf(" [GP_SIZE_MULT_2]: 0x%06x\n", (ext_csd[148] << 16) |
556 (ext_csd[147] << 8) | ext_csd[146]);
557 printf(" [GP_SIZE_MULT_1]: 0x%06x\n", (ext_csd[145] << 16) |
558 (ext_csd[144] << 8) | ext_csd[143]);
559
560 printf("Enhanced User Data Area Size"
561 " [ENH_SIZE_MULT]: 0x%06x\n", (ext_csd[142] << 16) |
562 (ext_csd[141] << 8) | ext_csd[140]);
563 printf("Enhanced User Data Start Address"
564 " [ENH_START_ADDR]: 0x%06x\n", (ext_csd[139] << 16) |
565 (ext_csd[138] << 8) | ext_csd[137]);
566
567 /* A441]: reserved [135] */
568 printf("Bad Block Management mode"
569 " [SEC_BAD_BLK_MGMNT]: 0x%02x\n", ext_csd[134]);
570 /* A441: reserved [133:0] */
571 }
572 /* B45 */
573 if (ext_csd_rev >= 6) {
574 int j;
575 /* tcase_support ext_csd[132] not readable */
576 printf("Periodic Wake-up [PERIODIC_WAKEUP]: 0x%02x\n",
577 ext_csd[131]);
578 printf("Program CID/CSD in DDR mode support"
579 " [PROGRAM_CID_CSD_DDR_SUPPORT]: 0x%02x\n",
580 ext_csd[130]);
581
582 for (j = 127; j >= 64; j--)
583 printf("Vendor Specific Fields"
584 " [VENDOR_SPECIFIC_FIELD[%d]]: 0x%02x\n",
585 j, ext_csd[j]);
586
587 printf("Native sector size [NATIVE_SECTOR_SIZE]: 0x%02x\n",
588 ext_csd[63]);
589 printf("Sector size emulation [USE_NATIVE_SECTOR]: 0x%02x\n",
590 ext_csd[62]);
591 printf("Sector size [DATA_SECTOR_SIZE]: 0x%02x\n", ext_csd[61]);
592 printf("1st initialization after disabling sector"
593 " size emulation [INI_TIMEOUT_EMU]: 0x%02x\n",
594 ext_csd[60]);
595 printf("Class 6 commands control [CLASS_6_CTRL]: 0x%02x\n",
596 ext_csd[59]);
597 printf("Number of addressed group to be Released"
598 "[DYNCAP_NEEDED]: 0x%02x\n", ext_csd[58]);
599 printf("Exception events control"
600 " [EXCEPTION_EVENTS_CTRL]: 0x%04x\n",
601 (ext_csd[57] << 8) | ext_csd[56]);
602 printf("Exception events status"
603 "[EXCEPTION_EVENTS_STATUS]: 0x%04x\n",
604 (ext_csd[55] << 8) | ext_csd[54]);
605 printf("Extended Partitions Attribute"
606 " [EXT_PARTITIONS_ATTRIBUTE]: 0x%04x\n",
607 (ext_csd[53] << 8) | ext_csd[52]);
608
609 for (j = 51; j >= 37; j--)
610 printf("Context configuration"
611 " [CONTEXT_CONF[%d]]: 0x%02x\n", j, ext_csd[j]);
612
613 printf("Packed command status"
614 " [PACKED_COMMAND_STATUS]: 0x%02x\n", ext_csd[36]);
615 printf("Packed command failure index"
616 " [PACKED_FAILURE_INDEX]: 0x%02x\n", ext_csd[35]);
617 printf("Power Off Notification"
618 " [POWER_OFF_NOTIFICATION]: 0x%02x\n", ext_csd[34]);
Chris Ballb9c7a172012-02-20 12:34:25 -0500619 printf("Control to turn the Cache ON/OFF" " [CACHE_CTRL]: 0x%02x\n", ext_csd[33]);
Giuseppe CAVALLAROa5bf4a22012-02-20 09:45:29 +0100620 /* flush_cache ext_csd[32] not readable */
621 /*Reserved [31:0] */
622 }
623
624out_free:
Johan RUDHOLMa8bfde72012-02-12 11:46:44 -0500625 return ret;
626}