summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2010-03-13 21:41:14 +0000
committerMichael Sparmann <theseven@rockbox.org>2010-03-13 21:41:14 +0000
commitcb41b2f2457015a3594eb63e917c5742564fc801 (patch)
tree96b40dafcbd1e82ad2c880b051f4a33ac51b1d53 /firmware
parentaf77b1842ced33af99318f5cb24cd24718c78639 (diff)
downloadrockbox-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')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c132
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
502uint32_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
502const struct nand_device_info_type* nand_get_device_type(uint32_t bank) 634const 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)