summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2010-03-13 21:44:39 +0000
committerMichael Sparmann <theseven@rockbox.org>2010-03-13 21:44:39 +0000
commit382b6dca08254e815a39db5fefbc2bf98142c812 (patch)
treed665d8f283e1e96a67aceb02c310fc61d5ae8599 /firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
parentcb41b2f2457015a3594eb63e917c5742564fc801 (diff)
downloadrockbox-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/s5l8700/ipodnano2g/nand-nano2g.c')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c63
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
443uint32_t nand_write_page(uint32_t bank, uint32_t page, void* databuffer, 443uint32_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
485uint32_t nand_block_erase(uint32_t bank, uint32_t page) 487uint32_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
636uint32_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
642uint32_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
674uint32_t nand_write_page_collect(uint32_t bank)
675{
676 return nand_wait_status_ready(bank);
677}
678
634const struct nand_device_info_type* nand_get_device_type(uint32_t bank) 679const 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)