diff options
author | Michael Sparmann <theseven@rockbox.org> | 2010-03-13 21:44:39 +0000 |
---|---|---|
committer | Michael Sparmann <theseven@rockbox.org> | 2010-03-13 21:44:39 +0000 |
commit | 382b6dca08254e815a39db5fefbc2bf98142c812 (patch) | |
tree | d665d8f283e1e96a67aceb02c310fc61d5ae8599 /firmware/target/arm | |
parent | cb41b2f2457015a3594eb63e917c5742564fc801 (diff) | |
download | rockbox-382b6dca08254e815a39db5fefbc2bf98142c812.tar.gz rockbox-382b6dca08254e815a39db5fefbc2bf98142c812.zip |
Nano2G NAND interleaved write support
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25154 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c index 7e455f044c..e9eab73df9 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | |||
@@ -440,8 +440,8 @@ uint32_t nand_read_page(uint32_t bank, uint32_t page, void* databuffer, | |||
440 | return nand_unlock(rc); | 440 | return nand_unlock(rc); |
441 | } | 441 | } |
442 | 442 | ||
443 | uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, | 443 | uint32_t nand_write_page_int(uint32_t bank, uint32_t page, void* databuffer, |
444 | void* sparebuffer, uint32_t doecc) | 444 | void* sparebuffer, uint32_t doecc, uint32_t wait) |
445 | { | 445 | { |
446 | uint8_t* data = nand_data; | 446 | uint8_t* data = nand_data; |
447 | uint8_t* spare = nand_spare; | 447 | uint8_t* spare = nand_spare; |
@@ -458,9 +458,14 @@ uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, | |||
458 | if (spare != sparebuffer) memcpy(spare, sparebuffer, 0x40); | 458 | if (spare != sparebuffer) memcpy(spare, sparebuffer, 0x40); |
459 | } | 459 | } |
460 | else memset(spare, 0xFF, 0x40); | 460 | else memset(spare, 0xFF, 0x40); |
461 | nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA); | ||
462 | if (nand_send_cmd(NAND_CMD_PROGRAM)) return nand_unlock(1); | ||
463 | if (nand_send_address(page, databuffer ? 0 : 0x800)) | ||
464 | return nand_unlock(1); | ||
465 | if (databuffer && data != databuffer) memcpy(data, databuffer, 0x800); | ||
466 | if (databuffer) nand_transfer_data_start(bank, 1, data, 0x800); | ||
461 | if (doecc) | 467 | if (doecc) |
462 | { | 468 | { |
463 | if (databuffer && data != databuffer) memcpy(data, databuffer, 0x800); | ||
464 | if (ecc_encode(3, data, nand_ecc)) return nand_unlock(1); | 469 | if (ecc_encode(3, data, nand_ecc)) return nand_unlock(1); |
465 | memcpy(&spare[0xC], nand_ecc, 0x28); | 470 | memcpy(&spare[0xC], nand_ecc, 0x28); |
466 | memset(nand_ctrl, 0xFF, 0x200); | 471 | memset(nand_ctrl, 0xFF, 0x200); |
@@ -468,18 +473,15 @@ uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, | |||
468 | if (ecc_encode(0, nand_ctrl, nand_ecc)) return nand_unlock(1); | 473 | if (ecc_encode(0, nand_ctrl, nand_ecc)) return nand_unlock(1); |
469 | memcpy(&spare[0x34], nand_ecc, 0xC); | 474 | memcpy(&spare[0x34], nand_ecc, 0xC); |
470 | } | 475 | } |
471 | nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA); | ||
472 | if (nand_send_cmd(NAND_CMD_PROGRAM)) return nand_unlock(1); | ||
473 | if (nand_send_address(page, databuffer ? 0 : 0x800)) | ||
474 | return nand_unlock(1); | ||
475 | if (databuffer) | 476 | if (databuffer) |
476 | if (nand_transfer_data(bank, 1, data, 0x800)) | 477 | if (nand_transfer_data_collect(1)) |
477 | return nand_unlock(1); | 478 | return nand_unlock(1); |
478 | if (sparebuffer || doecc) | 479 | if (sparebuffer || doecc) |
479 | if (nand_transfer_data(bank, 1, spare, 0x40)) | 480 | if (nand_transfer_data(bank, 1, spare, 0x40)) |
480 | return nand_unlock(1); | 481 | return nand_unlock(1); |
481 | if (nand_send_cmd(NAND_CMD_PROGCNFRM)) return nand_unlock(1); | 482 | if (nand_send_cmd(NAND_CMD_PROGCNFRM)) return nand_unlock(1); |
482 | return nand_unlock(nand_wait_status_ready(bank)); | 483 | if (wait) if (nand_wait_status_ready(bank)) return nand_unlock(1); |
484 | return nand_unlock(0); | ||
483 | } | 485 | } |
484 | 486 | ||
485 | uint32_t nand_block_erase(uint32_t bank, uint32_t page) | 487 | uint32_t nand_block_erase(uint32_t bank, uint32_t page) |
@@ -631,6 +633,49 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer, | |||
631 | return nand_unlock(rc); | 633 | return nand_unlock(rc); |
632 | } | 634 | } |
633 | 635 | ||
636 | uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, | ||
637 | void* sparebuffer, uint32_t doecc) | ||
638 | { | ||
639 | return nand_write_page_int(bank, page, databuffer, sparebuffer, doecc, 1); | ||
640 | } | ||
641 | |||
642 | uint32_t nand_write_page_start(uint32_t bank, uint32_t page, void* databuffer, | ||
643 | void* sparebuffer, uint32_t doecc) | ||
644 | { | ||
645 | if (((uint32_t)databuffer & 0xf) || ((uint32_t)sparebuffer & 0xf) | ||
646 | || !databuffer || !sparebuffer || !doecc) | ||
647 | return nand_write_page_int(bank, page, databuffer, sparebuffer, doecc, 0); | ||
648 | |||
649 | mutex_lock(&nand_mtx); | ||
650 | nand_last_activity_value = current_tick; | ||
651 | led(true); | ||
652 | if (!nand_powered) nand_power_up(); | ||
653 | nand_set_fmctrl0(bank, FMCTRL0_ENABLEDMA); | ||
654 | if (nand_send_cmd(NAND_CMD_PROGRAM)) | ||
655 | return nand_unlock(1); | ||
656 | if (nand_send_address(page, 0)) | ||
657 | return nand_unlock(1); | ||
658 | nand_transfer_data_start(bank, 1, databuffer, 0x800); | ||
659 | if (ecc_encode(3, databuffer, nand_ecc)) | ||
660 | return nand_unlock(1); | ||
661 | memcpy((void*)((uint32_t)sparebuffer + 0xC), nand_ecc, 0x28); | ||
662 | memset(nand_ctrl, 0xFF, 0x200); | ||
663 | memcpy(nand_ctrl, sparebuffer, 0xC); | ||
664 | if (ecc_encode(0, nand_ctrl, nand_ecc)) | ||
665 | return nand_unlock(1); | ||
666 | memcpy((void*)((uint32_t)sparebuffer + 0x34), nand_ecc, 0xC); | ||
667 | if (nand_transfer_data_collect(0)) | ||
668 | return nand_unlock(1); | ||
669 | if (nand_transfer_data(bank, 1, sparebuffer, 0x40)) | ||
670 | return nand_unlock(1); | ||
671 | return nand_unlock(nand_send_cmd(NAND_CMD_PROGCNFRM)); | ||
672 | } | ||
673 | |||
674 | uint32_t nand_write_page_collect(uint32_t bank) | ||
675 | { | ||
676 | return nand_wait_status_ready(bank); | ||
677 | } | ||
678 | |||
634 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank) | 679 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank) |
635 | { | 680 | { |
636 | if (nand_type[bank] == 0xFFFFFFFF) | 681 | if (nand_type[bank] == 0xFFFFFFFF) |