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
This commit is contained in:
parent
24c0474472
commit
9f8e76bf22
3 changed files with 49 additions and 90 deletions
|
@ -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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
if (nand_type[i] == 0xFFFFFFFF) continue;
|
||||
nand_set_fmctrl0(i, 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;
|
||||
}
|
||||
}
|
||||
uint8_t status[4];
|
||||
for (i = 0; i < 4; i++) status[i] = (nand_type[i] == 0xFFFFFFFF);
|
||||
if (!status[0])
|
||||
{
|
||||
nand_set_fmctrl0(0, FMCTRL0_ENABLEDMA);
|
||||
if (nand_send_cmd(NAND_CMD_READ))
|
||||
status[0] = 1;
|
||||
}
|
||||
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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue