diff options
author | Michael Sparmann <theseven@rockbox.org> | 2010-03-13 21:41:14 +0000 |
---|---|---|
committer | Michael Sparmann <theseven@rockbox.org> | 2010-03-13 21:41:14 +0000 |
commit | cb41b2f2457015a3594eb63e917c5742564fc801 (patch) | |
tree | 96b40dafcbd1e82ad2c880b051f4a33ac51b1d53 /firmware/target/arm/s5l8700/ipodnano2g | |
parent | af77b1842ced33af99318f5cb24cd24718c78639 (diff) | |
download | rockbox-cb41b2f2457015a3594eb63e917c5742564fc801.tar.gz rockbox-cb41b2f2457015a3594eb63e917c5742564fc801.zip |
Nano2G NAND parallel read support
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25153 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s5l8700/ipodnano2g')
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c index 07eb344040..7e455f044c 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | |||
@@ -499,6 +499,138 @@ uint32_t nand_block_erase(uint32_t bank, uint32_t page) | |||
499 | return nand_unlock(0); | 499 | return nand_unlock(0); |
500 | } | 500 | } |
501 | 501 | ||
502 | uint32_t nand_read_page_fast(uint32_t page, void* databuffer, | ||
503 | void* sparebuffer, uint32_t doecc, | ||
504 | uint32_t checkempty) | ||
505 | { | ||
506 | uint32_t i, rc = 0; | ||
507 | if (((uint32_t)databuffer & 0xf) || ((uint32_t)sparebuffer & 0xf) | ||
508 | || !databuffer || !sparebuffer || !doecc) | ||
509 | { | ||
510 | for (i = 0; i < 4; i++) | ||
511 | { | ||
512 | if (nand_type[i] == 0xFFFFFFFF) continue; | ||
513 | void* databuf = (void*)0; | ||
514 | void* sparebuf = (void*)0; | ||
515 | if (databuffer) databuf = (void*)((uint32_t)databuffer + 0x800 * i); | ||
516 | if (sparebuffer) sparebuf = (void*)((uint32_t)sparebuffer + 0x40 * i); | ||
517 | uint32_t ret = nand_read_page(i, page, databuf, sparebuf, doecc, checkempty); | ||
518 | if (ret & 1) rc |= 1 << (i << 2); | ||
519 | if (ret & 2) rc |= 2 << (i << 2); | ||
520 | if (ret & 0x10) rc |= 4 << (i << 2); | ||
521 | if (ret & 0x100) rc |= 8 << (i << 2); | ||
522 | } | ||
523 | return rc; | ||
524 | } | ||
525 | mutex_lock(&nand_mtx); | ||
526 | nand_last_activity_value = current_tick; | ||
527 | led(true); | ||
528 | if (!nand_powered) nand_power_up(); | ||
529 | for (i = 0; i < 4; i++) | ||
530 | { | ||
531 | if (nand_type[i] == 0xFFFFFFFF) continue; | ||
532 | nand_set_fmctrl0(i, FMCTRL0_ENABLEDMA); | ||
533 | if (nand_send_cmd(NAND_CMD_READ)) | ||
534 | { | ||
535 | rc |= 1 << (i << 2); | ||
536 | continue; | ||
537 | } | ||
538 | if (nand_send_address(page, databuffer ? 0 : 0x800)) | ||
539 | { | ||
540 | rc |= 1 << (i << 2); | ||
541 | continue; | ||
542 | } | ||
543 | if (nand_send_cmd(NAND_CMD_READ2)) | ||
544 | { | ||
545 | rc |= 1 << (i << 2); | ||
546 | continue; | ||
547 | } | ||
548 | } | ||
549 | uint8_t status[4]; | ||
550 | for (i = 0; i < 4; i++) status[i] = (nand_type[i] == 0xFFFFFFFF); | ||
551 | if (!status[0]) | ||
552 | if (nand_wait_status_ready(0)) | ||
553 | status[0] = 1; | ||
554 | if (!status[0]) | ||
555 | if (nand_transfer_data(0, 0, databuffer, 0x800)) | ||
556 | status[0] = 1; | ||
557 | if (!status[0]) | ||
558 | if (nand_transfer_data(0, 0, sparebuffer, 0x40)) | ||
559 | status[0] = 1; | ||
560 | for (i = 1; i < 4; i++) | ||
561 | { | ||
562 | if (!status[i]) | ||
563 | if (nand_wait_status_ready(i)) | ||
564 | status[i] = 1; | ||
565 | if (!status[i]) | ||
566 | nand_transfer_data_start(i, 0, (void*)((uint32_t)databuffer | ||
567 | + 0x800 * i), 0x800); | ||
568 | if (!status[i - 1]) | ||
569 | { | ||
570 | memcpy(nand_ecc, (void*)((uint32_t)sparebuffer + 0x40 * (i - 1) + 0xC), 0x28); | ||
571 | ecc_start(3, (void*)((uint32_t)databuffer | ||
572 | + 0x800 * (i - 1)), nand_ecc, ECCCTRL_STARTDECODING); | ||
573 | } | ||
574 | if (!status[i]) | ||
575 | if (nand_transfer_data_collect(0)) | ||
576 | status[i] = 1; | ||
577 | if (!status[i]) | ||
578 | nand_transfer_data_start(i, 0, (void*)((uint32_t)sparebuffer | ||
579 | + 0x40 * i), 0x40); | ||
580 | if (!status[i - 1]) | ||
581 | if (ecc_collect() & 1) | ||
582 | status[i - 1] = 4; | ||
583 | if (!status[i - 1]) | ||
584 | { | ||
585 | memset(nand_ctrl, 0xFF, 0x200); | ||
586 | memcpy(nand_ctrl, (void*)((uint32_t)sparebuffer + 0x40 * (i - 1)), 0xC); | ||
587 | memcpy(nand_ecc, (void*)((uint32_t)sparebuffer + 0x40 * (i - 1) + 0x34), 0xC); | ||
588 | ecc_start(0, nand_ctrl, nand_ecc, ECCCTRL_STARTDECODING); | ||
589 | } | ||
590 | if (!status[i]) | ||
591 | if (nand_transfer_data_collect(0)) | ||
592 | status[i] = 1; | ||
593 | if (!status[i - 1]) | ||
594 | { | ||
595 | if (ecc_collect() & 1) | ||
596 | { | ||
597 | status[i - 1] |= 8; | ||
598 | memset((void*)((uint32_t)sparebuffer + 0x40 * (i - 1)), 0xFF, 0xC); | ||
599 | } | ||
600 | else memcpy((void*)((uint32_t)sparebuffer + 0x40 * (i - 1)), nand_ctrl, 0xC); | ||
601 | if (checkempty) | ||
602 | status[i - 1] |= nand_check_empty((void*)((uint32_t)sparebuffer | ||
603 | + 0x40 * (i - 1))) << 1; | ||
604 | } | ||
605 | } | ||
606 | if (!status[i - 1]) | ||
607 | { | ||
608 | memcpy(nand_ecc,(void*)((uint32_t)sparebuffer + 0x40 * (i - 1) + 0xC), 0x28); | ||
609 | if (ecc_decode(3, (void*)((uint32_t)databuffer | ||
610 | + 0x800 * (i - 1)), nand_ecc) & 1) | ||
611 | status[i - 1] = 4; | ||
612 | } | ||
613 | if (!status[i - 1]) | ||
614 | { | ||
615 | memset(nand_ctrl, 0xFF, 0x200); | ||
616 | memcpy(nand_ctrl, (void*)((uint32_t)sparebuffer + 0x40 * (i - 1)), 0xC); | ||
617 | memcpy(nand_ecc, (void*)((uint32_t)sparebuffer + 0x40 * (i - 1) + 0x34), 0xC); | ||
618 | if (ecc_decode(0, nand_ctrl, nand_ecc) & 1) | ||
619 | { | ||
620 | status[i - 1] |= 8; | ||
621 | memset((void*)((uint32_t)sparebuffer + 0x40 * (i - 1)), 0xFF, 0xC); | ||
622 | } | ||
623 | else memcpy((void*)((uint32_t)sparebuffer + 0x40 * (i - 1)), nand_ctrl, 0xC); | ||
624 | if (checkempty) | ||
625 | status[i - 1] |= nand_check_empty((void*)((uint32_t)sparebuffer | ||
626 | + 0x40 * (i - 1))) << 1; | ||
627 | } | ||
628 | for (i = 0; i < 4; i++) | ||
629 | if (nand_type[i] != 0xFFFFFFFF) | ||
630 | rc |= status[i] << (i << 2); | ||
631 | return nand_unlock(rc); | ||
632 | } | ||
633 | |||
502 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank) | 634 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank) |
503 | { | 635 | { |
504 | if (nand_type[bank] == 0xFFFFFFFF) | 636 | if (nand_type[bank] == 0xFFFFFFFF) |