summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700
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
parent24c0474472015655c7b40bcdfc1537baf1642927 (diff)
downloadrockbox-9f8e76bf22482e67cceddd35580c84d66877af5d.tar.gz
rockbox-9f8e76bf22482e67cceddd35580c84d66877af5d.zip
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')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c49
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c83
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-target.h1
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];
89uint8_t nand_tunk3[4]; 89uint8_t nand_tunk3[4];
90uint32_t nand_type[4]; 90uint32_t nand_type[4];
91int nand_powered = 0; 91int nand_powered = 0;
92int nand_sequential = 0;
92long nand_last_activity_value = -1; 93long nand_last_activity_value = -1;
93static long nand_stack[32]; 94static 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
679uint32_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
714const struct nand_device_info_type* nand_get_device_type(uint32_t bank) 684const 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,
52uint32_t nand_write_page_start(uint32_t bank, uint32_t page, void* databuffer, 52uint32_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);
54uint32_t nand_write_page_collect(uint32_t bank); 54uint32_t nand_write_page_collect(uint32_t bank);
55uint32_t nand_block_erase_fast(uint32_t page);
56 55
57const struct nand_device_info_type* nand_get_device_type(uint32_t bank); 56const struct nand_device_info_type* nand_get_device_type(uint32_t bank);
58uint32_t nand_reset(uint32_t bank); 57uint32_t nand_reset(uint32_t bank);