Lines Matching +full:nand +full:- +full:ecc +full:- +full:step +full:- +full:size

2  * Allwinner NAND randomizer and image builder implementation:
7 * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
19 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
45 buf[j] |= (1 << (7 - i)); in swap_bits()
53 while (count--) in lfsr_step()
88 if (info->boot0) { in scramble()
91 unsigned seedmod = info->eraseblock_size / info->page_size; in scramble()
94 if (!info->scramble) in scramble()
117 int steps = info->usable_page_size / info->ecc_step_size; in write_page()
118 int eccbytes = DIV_ROUND_UP(info->ecc_strength * 14, 8); in write_page()
126 memset(buffer, 0xff, info->page_size + info->oob_size); in write_page()
127 cnt = fread(buffer, 1, info->usable_page_size, src); in write_page()
132 return -1; in write_page()
138 fwrite(buffer, info->page_size + info->oob_size, 1, dst); in write_page()
140 for (i = 0; i < info->usable_page_size; i++) { in write_page()
146 if (i == info->usable_page_size) in write_page()
150 fseek(src, -cnt, SEEK_CUR); in write_page()
153 if (info->scramble) { in write_page()
156 if (info->boot0) { in write_page()
159 offs = steps * (info->ecc_step_size + eccbytes + 4); in write_page()
160 cnt = info->page_size + info->oob_size - offs; in write_page()
165 return -1; in write_page()
168 offs = info->page_size + (steps * (eccbytes + 4)); in write_page()
169 cnt = info->page_size + info->oob_size - offs; in write_page()
179 uint8_t *ecc; in write_page() local
181 memset(buffer, 0xff, info->ecc_step_size + eccbytes + 4); in write_page()
182 ecc = buffer + info->ecc_step_size + 4; in write_page()
183 if (info->boot0) { in write_page()
184 data_offs = i * (info->ecc_step_size + eccbytes + 4); in write_page()
185 ecc_offs = data_offs + info->ecc_step_size + 4; in write_page()
187 data_offs = i * info->ecc_step_size; in write_page()
188 ecc_offs = info->page_size + 4 + (i * (eccbytes + 4)); in write_page()
191 cnt = fread(buffer, 1, info->ecc_step_size, src); in write_page()
195 return -1; in write_page()
198 pad = info->ecc_step_size - cnt; in write_page()
200 if (info->scramble && info->boot0) { in write_page()
207 return -1; in write_page()
214 memset(ecc, 0, eccbytes); in write_page()
215 swap_bits(buffer, info->ecc_step_size + 4); in write_page()
216 encode_bch(bch, buffer, info->ecc_step_size + 4, ecc); in write_page()
217 swap_bits(buffer, info->ecc_step_size + 4); in write_page()
218 swap_bits(ecc, eccbytes); in write_page()
219 scramble(info, page, buffer, info->ecc_step_size + 4 + eccbytes); in write_page()
222 fwrite(buffer, info->ecc_step_size, 1, dst); in write_page()
223 fseek(dst, pos + ecc_offs - 4, SEEK_SET); in write_page()
224 fwrite(ecc - 4, eccbytes + 4, 1, dst); in write_page()
228 fseek(dst, pos + info->page_size, SEEK_SET); in write_page()
233 fseek(dst, pos + info->page_size + info->oob_size, SEEK_SET); in write_page()
240 off_t page = info->offset / info->page_size; in create_image()
245 bch = init_bch(14, info->ecc_strength, BCH_PRIMITIVE_POLY); in create_image()
248 return -1; in create_image()
251 buffer = malloc(info->page_size + info->oob_size); in create_image()
253 fprintf(stderr, "Failed to allocate the NAND page buffer\n"); in create_image()
254 return -1; in create_image()
257 memset(buffer, 0xff, info->page_size + info->oob_size); in create_image()
259 src = fopen(info->source, "r"); in create_image()
262 info->source); in create_image()
263 return -1; in create_image()
266 dst = fopen(info->dest, "w"); in create_image()
268 fprintf(stderr, "Failed to open dest file (%s)\n", info->dest); in create_image()
269 return -1; in create_image()
275 return -1; in create_image()
292 "sunxi-nand-image-builder %s\n" in display_help()
294 "Usage: sunxi-nand-image-builder [OPTIONS] source-image output-image\n" in display_help()
296 "Creates a raw NAND image that can be read by the sunxi NAND controller.\n" in display_help()
298 "-h --help Display this help and exit\n" in display_help()
299 "-c <str>/<step> --ecc=<str>/<step> ECC config (strength/step-size)\n" in display_help()
300 "-p <size> --page=<size> Page size\n" in display_help()
301 "-o <size> --oob=<size> OOB size\n" in display_help()
302 "-u <size> --usable=<size> Usable page size\n" in display_help()
303 "-e <size> --eraseblock=<size> Erase block size\n" in display_help()
304 "-b --boot0 Build a boot0 image.\n" in display_help()
305 "-s --scramble Scramble data\n" in display_help()
306 "-a <offset> --address=<offset> Where the image will be programmed.\n" in display_help()
310 "the NAND datasheet.\n" in display_help()
312 "The NAND controller only supports the following ECC configs\n" in display_help()
313 " Valid ECC strengths: 16, 24, 28, 32, 40, 48, 56, 60 and 64\n" in display_help()
314 " Valid ECC step size: 512 and 1024\n" in display_help()
318 " http://linux-sunxi.org/NAND#More_information_on_BROM_NAND\n" in display_help()
320 " --usable should be assigned the 'Hardware page' value\n" in display_help()
321 " --ecc should be assigned the 'ECC capacity'/'ECC page' values\n" in display_help()
322 " --usable should be smaller than --page\n" in display_help()
324 "The --address option is only required for non-boot0 images that are \n" in display_help()
328 " The H27UCG8T2BTR-BC NAND exposes\n" in display_help()
333 " * expects a minimum ECC of 40bits/1024bytes\n" in display_help()
336 " sunxi-nand-image-builder -p 16384 -o 1280 -e 0x400000 -s -c 40/1024\n" in display_help()
338 " sunxi-nand-image-builder -p 16384 -o 1280 -e 0x400000 -s -b -u 4096 -c 64/1024\n", in display_help()
349 if (!info->page_size) { in check_image_info()
350 fprintf(stderr, "--page is missing\n"); in check_image_info()
351 return -EINVAL; in check_image_info()
354 if (!info->page_size) { in check_image_info()
355 fprintf(stderr, "--oob is missing\n"); in check_image_info()
356 return -EINVAL; in check_image_info()
359 if (!info->eraseblock_size) { in check_image_info()
360 fprintf(stderr, "--eraseblock is missing\n"); in check_image_info()
361 return -EINVAL; in check_image_info()
364 if (info->ecc_step_size != 512 && info->ecc_step_size != 1024) { in check_image_info()
365 fprintf(stderr, "Invalid ECC step argument: %d\n", in check_image_info()
366 info->ecc_step_size); in check_image_info()
367 return -EINVAL; in check_image_info()
371 if (valid_ecc_strengths[i] == info->ecc_strength) in check_image_info()
376 fprintf(stderr, "Invalid ECC strength argument: %d\n", in check_image_info()
377 info->ecc_strength); in check_image_info()
378 return -EINVAL; in check_image_info()
381 eccbytes = DIV_ROUND_UP(info->ecc_strength * 14, 8); in check_image_info()
386 eccsteps = info->usable_page_size / info->ecc_step_size; in check_image_info()
388 if (info->page_size + info->oob_size < in check_image_info()
389 info->usable_page_size + (eccsteps * eccbytes)) { in check_image_info()
391 "ECC bytes do not fit in the NAND page, choose a weaker ECC\n"); in check_image_info()
392 return -EINVAL; in check_image_info()
411 {"ecc", required_argument, 0, 'c'}, in main()
458 display_help(-1); in main()
463 if ((argc - optind) != 2) in main()
464 display_help(-1); in main()
481 display_help(-1); in main()