summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
diff options
context:
space:
mode:
authorMichael Sparmann <theseven@rockbox.org>2010-03-12 20:44:03 +0000
committerMichael Sparmann <theseven@rockbox.org>2010-03-12 20:44:03 +0000
commit9f8e76bf22482e67cceddd35580c84d66877af5d (patch)
treee707985559bf5ee9e8751caeca80c42f80efdb70 /firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
parent24c0474472015655c7b40bcdfc1537baf1642927 (diff)
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
Diffstat (limited to 'firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c83
1 files changed, 27 insertions, 56 deletions
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;
@@ -562,6 +555,18 @@ uint32_t nand_read_page_fast(uint32_t page, void* databuffer,
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;
if (!status[i])
@@ -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,