From 9f8e76bf22482e67cceddd35580c84d66877af5d Mon Sep 17 00:00:00 2001 From: Michael Sparmann Date: Fri, 12 Mar 2010 20:44:03 +0000 Subject: Hopefully fix the latest Nano2G NAND issues. (FS#11092) Transfers for some of the chips apple is using will be slow until someone implements cached writes. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25137 a1c6a512-1295-4272-9138-f99709370657 --- .../target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | 49 +++++-------- .../target/arm/s5l8700/ipodnano2g/nand-nano2g.c | 83 +++++++--------------- .../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) block = block + (*ftl_nand_type).blocks - (*ftl_nand_type).userblocks - 0x17; if (block == 0 || block >= (*ftl_nand_type).blocks) return 1; - uint32_t pblock[4]; - uint32_t differs = 0; for (i = 0; i < ftl_banks; i++) { if (ftl_vfl_check_remap_scheduled(i, block) == 1) @@ -1276,38 +1274,29 @@ uint32_t ftl_erase_block_internal(uint32_t block) ftl_vfl_mark_remap_done(i, block); } ftl_vfl_log_success(i, block); - pblock[i] = ftl_vfl_get_physical_block(i, block); - if (pblock[i] != pblock[0]) differs = 1; - } - uint32_t res = 0xf; - if (!differs) - res = nand_block_erase_fast(pblock[0] * (*ftl_nand_type).pagesperblock); - if (!res) return 0; - for (i = 0; i < ftl_banks; i++) - if (res & (1 << i)) + uint32_t pblock = ftl_vfl_get_physical_block(i, block); + uint32_t rc; + for (j = 0; j < 3; j++) { - uint32_t rc; - for (j = 0; j < 3; j++) - { - rc = nand_block_erase(i, pblock[i] * (*ftl_nand_type).pagesperblock); - if (rc == 0) break; - } - if (rc != 0) + rc = nand_block_erase(i, pblock * (*ftl_nand_type).pagesperblock); + if (rc == 0) break; + } + if (rc != 0) + { + panicf("FTL: Block erase failed on bank %u block %u", + (unsigned)i, (unsigned)block); + if (pblock != block) { - panicf("FTL: Block erase failed on bank %u block %u", - (unsigned)i, (unsigned)block); - if (pblock[i] != block) - { - uint32_t spareindex = pblock[i] - ftl_vfl_cxt[i].firstspare; - ftl_vfl_cxt[i].remaptable[spareindex] = 0xFFFF; - } - ftl_vfl_cxt[i].field_18++; - if (ftl_vfl_remap_block(i, block) == 0) return 1; - if (ftl_vfl_commit_cxt(i) != 0) return 1; - memset(&ftl_sparebuffer[0], 0, 0x40); - nand_write_page(i, pblock[i], &ftl_vfl_cxt[0], &ftl_sparebuffer[0], 1); + uint32_t spareindex = pblock - ftl_vfl_cxt[i].firstspare; + ftl_vfl_cxt[i].remaptable[spareindex] = 0xFFFF; } + ftl_vfl_cxt[i].field_18++; + if (ftl_vfl_remap_block(i, block) == 0) return 1; + if (ftl_vfl_commit_cxt(i) != 0) return 1; + memset(&ftl_sparebuffer, 0, 0x40); + nand_write_page(i, pblock, &ftl_vfl_cxt[0], &ftl_sparebuffer, 1); } + } return 0; } #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]; uint8_t nand_tunk3[4]; uint32_t nand_type[4]; int nand_powered = 0; +int nand_sequential = 0; long nand_last_activity_value = -1; static long nand_stack[32]; @@ -528,28 +529,20 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer, nand_last_activity_value = current_tick; led(true); if (!nand_powered) nand_power_up(); - for (i = 0; i < 4; i++) + uint8_t status[4]; + for (i = 0; i < 4; i++) status[i] = (nand_type[i] == 0xFFFFFFFF); + if (!status[0]) { - if (nand_type[i] == 0xFFFFFFFF) continue; - nand_set_fmctrl0(i, FMCTRL0_ENABLEDMA); + nand_set_fmctrl0(0, FMCTRL0_ENABLEDMA); if (nand_send_cmd(NAND_CMD_READ)) - { - rc |= 1 << (i << 2); - continue; - } - if (nand_send_address(page, databuffer ? 0 : 0x800)) - { - rc |= 1 << (i << 2); - continue; - } - if (nand_send_cmd(NAND_CMD_READ2)) - { - rc |= 1 << (i << 2); - continue; - } + status[0] = 1; } - uint8_t status[4]; - for (i = 0; i < 4; i++) status[i] = (nand_type[i] == 0xFFFFFFFF); + if (!status[0]) + if (nand_send_address(page, 0)) + status[0] = 1; + if (!status[0]) + if (nand_send_cmd(NAND_CMD_READ2)) + status[0] = 1; if (!status[0]) if (nand_wait_status_ready(0)) status[0] = 1; @@ -561,6 +554,18 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer, status[0] = 1; for (i = 1; i < 4; i++) { + if (!status[i]) + { + nand_set_fmctrl0(i, FMCTRL0_ENABLEDMA); + if (nand_send_cmd(NAND_CMD_READ)) + status[i] = 1; + } + if (!status[i]) + if (nand_send_address(page, 0)) + status[i] = 1; + if (!status[i]) + if (nand_send_cmd(NAND_CMD_READ2)) + status[i] = 1; if (!status[i]) if (nand_wait_status_ready(i)) status[i] = 1; @@ -643,8 +648,8 @@ uint32_t nand_write_page_start(uint32_t bank, uint32_t page, void* databuffer, void* sparebuffer, uint32_t doecc) { if (((uint32_t)databuffer & 0xf) || ((uint32_t)sparebuffer & 0xf) - || !databuffer || !sparebuffer || !doecc) - return nand_write_page_int(bank, page, databuffer, sparebuffer, doecc, 0); + || !databuffer || !sparebuffer || !doecc || nand_sequential) + return nand_write_page_int(bank, page, databuffer, sparebuffer, doecc, nand_sequential); mutex_lock(&nand_mtx); nand_last_activity_value = current_tick; @@ -676,41 +681,6 @@ uint32_t nand_write_page_collect(uint32_t bank) return nand_wait_status_ready(bank); } -uint32_t nand_block_erase_fast(uint32_t page) -{ - uint32_t i, rc = 0; - mutex_lock(&nand_mtx); - nand_last_activity_value = current_tick; - led(true); - if (!nand_powered) nand_power_up(); - for (i = 0; i < 4; i++) - { - if (nand_type[i] == 0xFFFFFFFF) continue; - nand_set_fmctrl0(i, 0); - if (nand_send_cmd(NAND_CMD_BLOCKERASE)) - { - rc |= 1 << i; - continue; - } - FMANUM = 2; - FMADDR0 = page; - FMCTRL1 = FMCTRL1_DOTRANSADDR; - if (nand_wait_cmddone()) - { - rc |= 1 << i; - continue; - } - if (nand_send_cmd(NAND_CMD_ERASECNFRM)) rc |= 1 << i; - } - for (i = 0; i < 4; i++) - { - if (nand_type[i] == 0xFFFFFFFF) continue; - if (rc & (1 << i)) continue; - if (nand_wait_status_ready(i)) rc |= 1 << i; - } - return nand_unlock(rc); -} - const struct nand_device_info_type* nand_get_device_type(uint32_t bank) { if (nand_type[bank] == 0xFFFFFFFF) @@ -769,6 +739,7 @@ uint32_t nand_device_init(void) nand_tunk3[i] = nand_deviceinfotable[nand_type[i]].tunk3; } if (nand_type[0] == 0xFFFFFFFF) return 1; + nand_sequential = !((nand_type[0] >> 22) & 1); nand_last_activity_value = current_tick; 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, uint32_t nand_write_page_start(uint32_t bank, uint32_t page, void* databuffer, void* sparebuffer, uint32_t doecc); uint32_t nand_write_page_collect(uint32_t bank); -uint32_t nand_block_erase_fast(uint32_t page); const struct nand_device_info_type* nand_get_device_type(uint32_t bank); uint32_t nand_reset(uint32_t bank); -- cgit v1.2.3