diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | 49 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | 83 | ||||
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/nand-target.h | 1 |
3 files changed, 46 insertions, 87 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c index 6926c41607..321495a321 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | |||
@@ -1266,8 +1266,6 @@ uint32_t ftl_erase_block_internal(uint32_t block) | |||
1266 | block = block + (*ftl_nand_type).blocks | 1266 | block = block + (*ftl_nand_type).blocks |
1267 | - (*ftl_nand_type).userblocks - 0x17; | 1267 | - (*ftl_nand_type).userblocks - 0x17; |
1268 | if (block == 0 || block >= (*ftl_nand_type).blocks) return 1; | 1268 | if (block == 0 || block >= (*ftl_nand_type).blocks) return 1; |
1269 | uint32_t pblock[4]; | ||
1270 | uint32_t differs = 0; | ||
1271 | for (i = 0; i < ftl_banks; i++) | 1269 | for (i = 0; i < ftl_banks; i++) |
1272 | { | 1270 | { |
1273 | if (ftl_vfl_check_remap_scheduled(i, block) == 1) | 1271 | if (ftl_vfl_check_remap_scheduled(i, block) == 1) |
@@ -1276,38 +1274,29 @@ uint32_t ftl_erase_block_internal(uint32_t block) | |||
1276 | ftl_vfl_mark_remap_done(i, block); | 1274 | ftl_vfl_mark_remap_done(i, block); |
1277 | } | 1275 | } |
1278 | ftl_vfl_log_success(i, block); | 1276 | ftl_vfl_log_success(i, block); |
1279 | pblock[i] = ftl_vfl_get_physical_block(i, block); | 1277 | uint32_t pblock = ftl_vfl_get_physical_block(i, block); |
1280 | if (pblock[i] != pblock[0]) differs = 1; | 1278 | uint32_t rc; |
1281 | } | 1279 | for (j = 0; j < 3; j++) |
1282 | uint32_t res = 0xf; | ||
1283 | if (!differs) | ||
1284 | res = nand_block_erase_fast(pblock[0] * (*ftl_nand_type).pagesperblock); | ||
1285 | if (!res) return 0; | ||
1286 | for (i = 0; i < ftl_banks; i++) | ||
1287 | if (res & (1 << i)) | ||
1288 | { | 1280 | { |
1289 | uint32_t rc; | 1281 | rc = nand_block_erase(i, pblock * (*ftl_nand_type).pagesperblock); |
1290 | for (j = 0; j < 3; j++) | 1282 | if (rc == 0) break; |
1291 | { | 1283 | } |
1292 | rc = nand_block_erase(i, pblock[i] * (*ftl_nand_type).pagesperblock); | 1284 | if (rc != 0) |
1293 | if (rc == 0) break; | 1285 | { |
1294 | } | 1286 | panicf("FTL: Block erase failed on bank %u block %u", |
1295 | if (rc != 0) | 1287 | (unsigned)i, (unsigned)block); |
1288 | if (pblock != block) | ||
1296 | { | 1289 | { |
1297 | panicf("FTL: Block erase failed on bank %u block %u", | 1290 | uint32_t spareindex = pblock - ftl_vfl_cxt[i].firstspare; |
1298 | (unsigned)i, (unsigned)block); | 1291 | ftl_vfl_cxt[i].remaptable[spareindex] = 0xFFFF; |
1299 | if (pblock[i] != block) | ||
1300 | { | ||
1301 | uint32_t spareindex = pblock[i] - ftl_vfl_cxt[i].firstspare; | ||
1302 | ftl_vfl_cxt[i].remaptable[spareindex] = 0xFFFF; | ||
1303 | } | ||
1304 | ftl_vfl_cxt[i].field_18++; | ||
1305 | if (ftl_vfl_remap_block(i, block) == 0) return 1; | ||
1306 | if (ftl_vfl_commit_cxt(i) != 0) return 1; | ||
1307 | memset(&ftl_sparebuffer[0], 0, 0x40); | ||
1308 | nand_write_page(i, pblock[i], &ftl_vfl_cxt[0], &ftl_sparebuffer[0], 1); | ||
1309 | } | 1292 | } |
1293 | ftl_vfl_cxt[i].field_18++; | ||
1294 | if (ftl_vfl_remap_block(i, block) == 0) return 1; | ||
1295 | if (ftl_vfl_commit_cxt(i) != 0) return 1; | ||
1296 | memset(&ftl_sparebuffer, 0, 0x40); | ||
1297 | nand_write_page(i, pblock, &ftl_vfl_cxt[0], &ftl_sparebuffer, 1); | ||
1310 | } | 1298 | } |
1299 | } | ||
1311 | return 0; | 1300 | return 0; |
1312 | } | 1301 | } |
1313 | #endif | 1302 | #endif |
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c index 26c53edc79..687a3179f9 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c | |||
@@ -89,6 +89,7 @@ uint8_t nand_tunk2[4]; | |||
89 | uint8_t nand_tunk3[4]; | 89 | uint8_t nand_tunk3[4]; |
90 | uint32_t nand_type[4]; | 90 | uint32_t nand_type[4]; |
91 | int nand_powered = 0; | 91 | int nand_powered = 0; |
92 | int nand_sequential = 0; | ||
92 | long nand_last_activity_value = -1; | 93 | long nand_last_activity_value = -1; |
93 | static long nand_stack[32]; | 94 | static long nand_stack[32]; |
94 | 95 | ||
@@ -528,28 +529,20 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer, | |||
528 | nand_last_activity_value = current_tick; | 529 | nand_last_activity_value = current_tick; |
529 | led(true); | 530 | led(true); |
530 | if (!nand_powered) nand_power_up(); | 531 | if (!nand_powered) nand_power_up(); |
531 | for (i = 0; i < 4; i++) | 532 | uint8_t status[4]; |
533 | for (i = 0; i < 4; i++) status[i] = (nand_type[i] == 0xFFFFFFFF); | ||
534 | if (!status[0]) | ||
532 | { | 535 | { |
533 | if (nand_type[i] == 0xFFFFFFFF) continue; | 536 | nand_set_fmctrl0(0, FMCTRL0_ENABLEDMA); |
534 | nand_set_fmctrl0(i, FMCTRL0_ENABLEDMA); | ||
535 | if (nand_send_cmd(NAND_CMD_READ)) | 537 | if (nand_send_cmd(NAND_CMD_READ)) |
536 | { | 538 | status[0] = 1; |
537 | rc |= 1 << (i << 2); | ||
538 | continue; | ||
539 | } | ||
540 | if (nand_send_address(page, databuffer ? 0 : 0x800)) | ||
541 | { | ||
542 | rc |= 1 << (i << 2); | ||
543 | continue; | ||
544 | } | ||
545 | if (nand_send_cmd(NAND_CMD_READ2)) | ||
546 | { | ||
547 | rc |= 1 << (i << 2); | ||
548 | continue; | ||
549 | } | ||
550 | } | 539 | } |
551 | uint8_t status[4]; | 540 | if (!status[0]) |
552 | for (i = 0; i < 4; i++) status[i] = (nand_type[i] == 0xFFFFFFFF); | 541 | if (nand_send_address(page, 0)) |
542 | status[0] = 1; | ||
543 | if (!status[0]) | ||
544 | if (nand_send_cmd(NAND_CMD_READ2)) | ||
545 | status[0] = 1; | ||
553 | if (!status[0]) | 546 | if (!status[0]) |
554 | if (nand_wait_status_ready(0)) | 547 | if (nand_wait_status_ready(0)) |
555 | status[0] = 1; | 548 | status[0] = 1; |
@@ -562,6 +555,18 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer, | |||
562 | for (i = 1; i < 4; i++) | 555 | for (i = 1; i < 4; i++) |
563 | { | 556 | { |
564 | if (!status[i]) | 557 | if (!status[i]) |
558 | { | ||
559 | nand_set_fmctrl0(i, FMCTRL0_ENABLEDMA); | ||
560 | if (nand_send_cmd(NAND_CMD_READ)) | ||
561 | status[i] = 1; | ||
562 | } | ||
563 | if (!status[i]) | ||
564 | if (nand_send_address(page, 0)) | ||
565 | status[i] = 1; | ||
566 | if (!status[i]) | ||
567 | if (nand_send_cmd(NAND_CMD_READ2)) | ||
568 | status[i] = 1; | ||
569 | if (!status[i]) | ||
565 | if (nand_wait_status_ready(i)) | 570 | if (nand_wait_status_ready(i)) |
566 | status[i] = 1; | 571 | status[i] = 1; |
567 | if (!status[i]) | 572 | if (!status[i]) |
@@ -643,8 +648,8 @@ uint32_t nand_write_page_start(uint32_t bank, uint32_t page, void* databuffer, | |||
643 | void* sparebuffer, uint32_t doecc) | 648 | void* sparebuffer, uint32_t doecc) |
644 | { | 649 | { |
645 | if (((uint32_t)databuffer & 0xf) || ((uint32_t)sparebuffer & 0xf) | 650 | if (((uint32_t)databuffer & 0xf) || ((uint32_t)sparebuffer & 0xf) |
646 | || !databuffer || !sparebuffer || !doecc) | 651 | || !databuffer || !sparebuffer || !doecc || nand_sequential) |
647 | return nand_write_page_int(bank, page, databuffer, sparebuffer, doecc, 0); | 652 | return nand_write_page_int(bank, page, databuffer, sparebuffer, doecc, nand_sequential); |
648 | 653 | ||
649 | mutex_lock(&nand_mtx); | 654 | mutex_lock(&nand_mtx); |
650 | nand_last_activity_value = current_tick; | 655 | nand_last_activity_value = current_tick; |
@@ -676,41 +681,6 @@ uint32_t nand_write_page_collect(uint32_t bank) | |||
676 | return nand_wait_status_ready(bank); | 681 | return nand_wait_status_ready(bank); |
677 | } | 682 | } |
678 | 683 | ||
679 | uint32_t nand_block_erase_fast(uint32_t page) | ||
680 | { | ||
681 | uint32_t i, rc = 0; | ||
682 | mutex_lock(&nand_mtx); | ||
683 | nand_last_activity_value = current_tick; | ||
684 | led(true); | ||
685 | if (!nand_powered) nand_power_up(); | ||
686 | for (i = 0; i < 4; i++) | ||
687 | { | ||
688 | if (nand_type[i] == 0xFFFFFFFF) continue; | ||
689 | nand_set_fmctrl0(i, 0); | ||
690 | if (nand_send_cmd(NAND_CMD_BLOCKERASE)) | ||
691 | { | ||
692 | rc |= 1 << i; | ||
693 | continue; | ||
694 | } | ||
695 | FMANUM = 2; | ||
696 | FMADDR0 = page; | ||
697 | FMCTRL1 = FMCTRL1_DOTRANSADDR; | ||
698 | if (nand_wait_cmddone()) | ||
699 | { | ||
700 | rc |= 1 << i; | ||
701 | continue; | ||
702 | } | ||
703 | if (nand_send_cmd(NAND_CMD_ERASECNFRM)) rc |= 1 << i; | ||
704 | } | ||
705 | for (i = 0; i < 4; i++) | ||
706 | { | ||
707 | if (nand_type[i] == 0xFFFFFFFF) continue; | ||
708 | if (rc & (1 << i)) continue; | ||
709 | if (nand_wait_status_ready(i)) rc |= 1 << i; | ||
710 | } | ||
711 | return nand_unlock(rc); | ||
712 | } | ||
713 | |||
714 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank) | 684 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank) |
715 | { | 685 | { |
716 | if (nand_type[bank] == 0xFFFFFFFF) | 686 | if (nand_type[bank] == 0xFFFFFFFF) |
@@ -769,6 +739,7 @@ uint32_t nand_device_init(void) | |||
769 | nand_tunk3[i] = nand_deviceinfotable[nand_type[i]].tunk3; | 739 | nand_tunk3[i] = nand_deviceinfotable[nand_type[i]].tunk3; |
770 | } | 740 | } |
771 | if (nand_type[0] == 0xFFFFFFFF) return 1; | 741 | if (nand_type[0] == 0xFFFFFFFF) return 1; |
742 | nand_sequential = !((nand_type[0] >> 22) & 1); | ||
772 | 743 | ||
773 | nand_last_activity_value = current_tick; | 744 | nand_last_activity_value = current_tick; |
774 | create_thread(nand_thread, nand_stack, | 745 | create_thread(nand_thread, nand_stack, |
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-target.h b/firmware/target/arm/s5l8700/ipodnano2g/nand-target.h index 3961912403..aad15b2910 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/nand-target.h +++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-target.h | |||
@@ -52,7 +52,6 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer, | |||
52 | uint32_t nand_write_page_start(uint32_t bank, uint32_t page, void* databuffer, | 52 | uint32_t nand_write_page_start(uint32_t bank, uint32_t page, void* databuffer, |
53 | void* sparebuffer, uint32_t doecc); | 53 | void* sparebuffer, uint32_t doecc); |
54 | uint32_t nand_write_page_collect(uint32_t bank); | 54 | uint32_t nand_write_page_collect(uint32_t bank); |
55 | uint32_t nand_block_erase_fast(uint32_t page); | ||
56 | 55 | ||
57 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank); | 56 | const struct nand_device_info_type* nand_get_device_type(uint32_t bank); |
58 | uint32_t nand_reset(uint32_t bank); | 57 | uint32_t nand_reset(uint32_t bank); |