2 * Copyright (C) 2010 Freescale Semiconductor, Inc.
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 #ifdef CONFIG_GENERIC_MMC
30 #define MBR_SIGNATURE 0xaa55
31 #define MBR_SECTOR_COUNT (CONFIG_ENV_OFFSET >> 9)
32 /* 1. RSV partition (env and uImage) */
33 #define RSVPART_SECTOR_OFFSET (MBR_SECTOR_COUNT)
34 #define RSVPART_SECTOR_COUNT 0x3ffe /* 8 MB */
35 /* 2. FAT partition */
36 #define FATPART_FILESYS 0xb
37 #define FATPART_SECTOR_OFFSET (RSVPART_SECTOR_OFFSET + RSVPART_SECTOR_COUNT)
38 #define FATPART_SECTOR_COUNT 0x10000 /* 32 MB (minimal) */
39 /* 3. EXT partition */
40 #define EXTPART_FILESYS 0x83
41 #define EXTPART_SECTOR_COUNT 0xc0000 /* 384 MB */
42 /* 4. SB partition (uboot.sb or linux.sb) */
43 #define SBPART_FILESYS 'S'
44 #define SBPART_SECTOR_COUNT 0x4000 /* 8 MB */
45 #define CB_SIGNATURE 0x00112233
46 #define CB_SECTOR_COUNT 2
48 #define MAX_CYLINDERS 1024
50 #define MAX_SECTORS 63
63 } __attribute__ ((__packed__));
65 struct partition_table {
67 struct partition partitions[4];
84 struct drive_info drive_info[2];
87 static int mmc_format(int dev)
91 u32 i, cnt, total_sectors;
93 struct config_block *cb;
94 struct partition_table *mbr;
95 struct mmc *mmc = find_mmc_device(dev);
98 printf("WARN: Data on card will get lost with format.\n"
107 /* Allocate sector buffer */
108 buf = malloc(mmc->read_bl_len);
110 printf("%s[%d]: malloc error\n", __func__, __LINE__);
114 memset(buf, 0, mmc->read_bl_len);
116 /* Erase the first sector of each partition */
117 cnt = mmc->block_dev.block_read(dev, 0, 1, buf);
119 printf("%s[%d]: read mmc error\n", __func__, __LINE__);
123 mbr = (struct partition_table *)buf;
124 if (mbr->signature == MBR_SIGNATURE) {
125 /* Get sector offset of each partition */
126 for (i = 0; i < 4; i++)
127 offset[i] = mbr->partitions[i].sector_offset;
129 memset(buf, 0, mmc->read_bl_len);
130 for (i = 0; i < 4; i++) {
132 cnt = mmc->block_dev.block_write(dev,
135 printf("%s[%d]: write mmc error\n",
144 /* Get total sectors */
145 total_sectors = mmc->capacity >> 9;
146 if (RSVPART_SECTOR_COUNT + SBPART_SECTOR_COUNT > total_sectors) {
147 printf("Card capacity is too low to format\n");
152 /* Write config block */
153 cb = (struct config_block *)buf;
154 cb->signature = CB_SIGNATURE;
156 cb->primary_tag = 0x1;
157 cb->secondary_tag = 0x2;
158 cb->drive_info[0].chip_num = 0;
159 cb->drive_info[0].drive_type = 0;
160 cb->drive_info[0].drive_tag = 0x1;
161 cb->drive_info[0].sector_count = SBPART_SECTOR_COUNT - CB_SECTOR_COUNT;
162 cb->drive_info[0].sector_offset =
163 total_sectors - cb->drive_info[0].sector_count;
164 cb->drive_info[1].chip_num = 0;
165 cb->drive_info[1].drive_type = 0;
166 cb->drive_info[1].drive_tag = 0x2;
167 cb->drive_info[1].sector_count = SBPART_SECTOR_COUNT - CB_SECTOR_COUNT;
168 cb->drive_info[1].sector_offset =
169 total_sectors - cb->drive_info[1].sector_count;
171 cnt = mmc->block_dev.block_write(dev,
172 total_sectors - SBPART_SECTOR_COUNT, 1, (void *)cb);
174 printf("%s[%d]: write mmc error\n", __func__, __LINE__);
179 /* Prepare for MBR */
180 memset(buf, 0, mmc->read_bl_len);
181 mbr = (struct partition_table *)buf;
184 mbr->partitions[0].sector_offset = RSVPART_SECTOR_OFFSET;
185 mbr->partitions[0].sector_count = RSVPART_SECTOR_COUNT;
188 mbr->partitions[3].file_system = SBPART_FILESYS;
189 mbr->partitions[3].sector_offset = total_sectors - SBPART_SECTOR_COUNT;
190 mbr->partitions[3].sector_count = SBPART_SECTOR_COUNT;
193 if (EXTPART_SECTOR_COUNT + SBPART_SECTOR_COUNT +
194 RSVPART_SECTOR_COUNT > total_sectors) {
196 printf("No room for EXT partition\n");
199 mbr->partitions[2].file_system = EXTPART_FILESYS;
200 mbr->partitions[2].sector_offset = total_sectors -
201 SBPART_SECTOR_COUNT - EXTPART_SECTOR_COUNT;
202 mbr->partitions[2].sector_count = EXTPART_SECTOR_COUNT;
206 if (FATPART_SECTOR_COUNT + MBR_SECTOR_COUNT +
207 mbr->partitions[0].sector_count +
208 mbr->partitions[2].sector_count +
209 mbr->partitions[3].sector_count > total_sectors) {
211 printf("No room for FAT partition\n");
215 mbr->partitions[1].file_system = FATPART_FILESYS;
216 mbr->partitions[1].sector_offset = FATPART_SECTOR_OFFSET;
217 mbr->partitions[1].sector_count = total_sectors - MBR_SECTOR_COUNT -
218 mbr->partitions[0].sector_count -
219 mbr->partitions[2].sector_count -
220 mbr->partitions[3].sector_count;
225 mbr->signature = MBR_SIGNATURE;
226 cnt = mmc->block_dev.block_write(dev, 0, 1, (void *)mbr);
228 printf("%s[%d]: write mmc error\n", __func__, __LINE__);
239 static int install_sbimage(int dev, void *addr, u32 size)
243 u32 cnt, offset, cb_offset, sectors, not_format = 0;
244 struct config_block *cb;
245 struct partition_table *mbr;
246 struct mmc *mmc = find_mmc_device(dev);
248 /* Allocate sector buffer */
249 buf = malloc(mmc->read_bl_len);
251 printf("%s[%d]: malloc error\n", __func__, __LINE__);
256 /* Check partition */
258 cnt = mmc->block_dev.block_read(dev, offset, 1, buf);
260 printf("%s[%d]: read mmc error\n", __func__, __LINE__);
264 mbr = (struct partition_table *)buf;
265 if ((mbr->signature != MBR_SIGNATURE) ||
266 (mbr->partitions[3].file_system != SBPART_FILESYS))
269 /* Check config block */
270 offset = mbr->partitions[3].sector_offset;
271 cb_offset = offset; /* Save for later use */
272 cnt = mmc->block_dev.block_read(dev, offset, 1, buf);
274 printf("%s[%d]: read mmc error\n", __func__, __LINE__);
278 cb = (struct config_block *)buf;
279 if (cb->signature != CB_SIGNATURE)
284 printf("Card is not formatted yet\n");
289 /* Calculate sectors of image */
290 sectors = size / mmc->read_bl_len;
291 if (size % mmc->read_bl_len)
295 offset = cb->drive_info[0].sector_offset;
296 cnt = mmc->block_dev.block_write(dev, offset, sectors, addr);
297 if (cnt != sectors) {
298 printf("%s[%d]: write mmc error\n", __func__, __LINE__);
303 cnt = mmc->block_dev.block_read(dev, offset, sectors,
304 addr + sectors * mmc->read_bl_len);
305 if (cnt != sectors) {
306 printf("%s[%d]: read mmc error\n", __func__, __LINE__);
310 if (memcmp(addr, addr + sectors * mmc->read_bl_len,
311 sectors * mmc->read_bl_len)) {
312 printf("Verifying sbImage write fails\n");
319 cnt = mmc->block_dev.block_write(dev, offset, sectors, addr);
320 if (cnt != sectors) {
321 printf("%s[%d]: write mmc error\n", __func__, __LINE__);
326 cnt = mmc->block_dev.block_read(dev, offset, sectors,
327 addr + sectors * mmc->read_bl_len);
328 if (cnt != sectors) {
329 printf("%s[%d]: read mmc error\n", __func__, __LINE__);
333 if (memcmp(addr, addr + sectors * mmc->read_bl_len,
334 sectors * mmc->read_bl_len)) {
335 printf("Verifying redundant sbImage write fails");
340 /* Update config block */
341 cb->drive_info[0].sector_count = sectors;
342 cb->drive_info[1].sector_count = sectors;
343 cb->drive_info[1].sector_offset = offset;
344 cnt = mmc->block_dev.block_write(dev, cb_offset, 1, (void *)cb);
346 printf("%s[%d]: write mmc error\n", __func__, __LINE__);
352 printf("Done: %d (%x hex) sectors written at %d (%x hex)\n",
353 sectors, sectors, offset - sectors, offset - sectors);
361 static int install_uimage(int dev, void *addr, u32 size)
365 u32 cnt, offset, sectors;
366 struct partition_table *mbr;
367 struct mmc *mmc = find_mmc_device(dev);
369 /* Calculate sectors of uImage */
370 sectors = size / mmc->read_bl_len;
371 if (size % mmc->read_bl_len)
374 /* Allocate sector buffer */
375 buf = malloc(mmc->read_bl_len);
377 printf("%s[%d]: malloc error\n", __func__, __LINE__);
382 /* Check partition */
384 cnt = mmc->block_dev.block_read(dev, offset, 1, buf);
386 printf("%s[%d]: read mmc error\n", __func__, __LINE__);
390 mbr = (struct partition_table *)buf;
391 if (mbr->signature != MBR_SIGNATURE) {
392 printf("No valid partition table\n");
396 if (mbr->partitions[0].sector_count < sectors) {
397 printf("No enough uImage partition room\n");
403 offset = mbr->partitions[0].sector_offset + (CONFIG_ENV_SIZE >> 9);
404 cnt = mmc->block_dev.block_write(dev, offset, sectors, addr);
405 if (cnt != sectors) {
406 printf("%s[%d]: write mmc error\n", __func__, __LINE__);
411 cnt = mmc->block_dev.block_read(dev, offset, sectors,
412 addr + sectors * mmc->read_bl_len);
413 if (cnt != sectors) {
414 printf("%s[%d]: read mmc error\n", __func__, __LINE__);
418 if (memcmp(addr, addr + sectors * mmc->read_bl_len,
419 sectors * mmc->read_bl_len)) {
420 printf("Verifying uImage write fails");
426 printf("Done: %d (%x hex) sectors written at %d (%x hex)\n",
427 sectors, sectors, offset, offset);
435 static int install_rootfs(int dev, void *addr, u32 size)
439 u32 cnt, offset, sectors;
440 struct partition_table *mbr;
441 struct mmc *mmc = find_mmc_device(dev);
443 /* Calculate sectors of rootfs */
444 sectors = size / mmc->read_bl_len;
445 if (size % mmc->read_bl_len)
448 /* Allocate sector buffer */
449 buf = malloc(mmc->read_bl_len);
451 printf("%s[%d]: malloc error\n", __func__, __LINE__);
456 /* Check partition */
458 cnt = mmc->block_dev.block_read(dev, offset, 1, buf);
460 printf("%s[%d]: read mmc error\n", __func__, __LINE__);
464 mbr = (struct partition_table *)buf;
465 if ((mbr->signature != MBR_SIGNATURE) ||
466 (mbr->partitions[2].file_system != EXTPART_FILESYS)) {
467 printf("No rootfs partition\n");
471 if (mbr->partitions[2].sector_count < sectors) {
472 printf("No enough rootfs partition room\n");
478 offset = mbr->partitions[2].sector_offset;
479 cnt = mmc->block_dev.block_write(dev, offset, sectors, addr);
480 if (cnt != sectors) {
481 printf("%s[%d]: write mmc error\n", __func__, __LINE__);
487 printf("Done: %d (%x hex) sectors written at %d (%x hex)\n",
488 sectors, sectors, offset, offset);
496 int do_mxs_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
504 if (strcmp(argv[1], "format") &&
505 strcmp(argv[1], "install"))
508 if (argc == 2) { /* list */
509 print_mmc_devices('\n');
513 /* Find and init mmc */
514 dev = simple_strtoul(argv[2], NULL, 10);
515 mmc = find_mmc_device(dev);
517 printf("%s[%d]: find mmc error\n", __func__, __LINE__);
521 printf("%s[%d]: init mmc error\n", __func__, __LINE__);
525 if (!strcmp(argv[1], "format"))
527 if (argc == 3) /* rescan (mmc_init) */
533 if (!strcmp(argv[1], "install")) {
534 void *addr = (void *)simple_strtoul(argv[3], NULL, 16);
535 u32 size = simple_strtoul(argv[4], NULL, 16);
537 if (!strcmp(argv[5], "sbImage"))
538 return install_sbimage(dev, addr, size);
539 else if (!strcmp(argv[5], "uImage"))
540 return install_uimage(dev, addr, size);
541 else if (!strcmp(argv[5], "rootfs"))
542 return install_rootfs(dev, addr, size);
546 printf("Usage:\n%s\n", cmdtp->usage);
551 mxs_mmc, 6, 1, do_mxs_mmcops,
552 "MXS specific MMC sub system",
553 "mxs_mmc format <device num>\n"
554 "mxs_mmc install <device num> addr size sbImage/uImage/rootfs\n");
555 #endif /* CONFIG_GENERIC_MMC */