Index: firmware/export/s5l8700.h =================================================================== --- firmware/export/s5l8700.h (Revision 23621) +++ firmware/export/s5l8700.h (Arbeitskopie) @@ -389,6 +389,10 @@ #define FMCSTAT_BANK2READY (1 << 6) #define FMCSTAT_BANK3READY (1 << 7) +/* described in the s5l8700 datasheet(there is a little typo: FCMSTAT vs. FMCSTAT) */ +#define FMCSTAT_WFIFO_HEMPTY (1 << 5) +#define FMCSTAT_RFIFO_HEMPTY (1 << 6) + /* 13. SECURE DIGITAL CARD INTERFACE (SDCI) */ #define SDCI_CTRL (*(REG32_PTR_T)(0x3C300000)) /* Control Register */ #define SDCI_DCTRL (*(REG32_PTR_T)(0x3C300004)) /* Data Control Register */ Index: firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c =================================================================== --- firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c (Revision 23621) +++ firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c (Arbeitskopie) @@ -125,6 +125,22 @@ } } +uint32_t nand_wait_wfifo_done(void) +{ + long timeout = current_tick + HZ / 50; + while((!(FMCSTAT & FMCSTAT_WFIFO_HEMPTY))&&(!(FMCSTAT & 0x100))) + if(nand_timeout(timeout)) return 1; + return 0; +} + +uint32_t nand_wait_rfifo_done(void) +{ + long timeout = current_tick + HZ / 50; + while((!(FMCSTAT & FMCSTAT_RFIFO_HEMPTY))&&(!(FMCSTAT & (1<<9)))) + if(nand_timeout(timeout)) return 1; + return 0; +} + uint32_t nand_wait_rbbdone(void) { long timeout = current_tick + HZ / 50; @@ -187,7 +203,10 @@ nand_set_fmctrl0(bank, 0); if (nand_send_cmd(NAND_CMD_RESET)) return 1; if (nand_wait_chip_ready(bank)) return 1; - FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + FMCTRL1 = FMCTRL1_CLEARRFIFO; + if(nand_wait_rfifo_done()) return 1; + FMCTRL1 = FMCTRL1_CLEARWFIFO; + if(nand_wait_wfifo_done()) return 1; return 0; } @@ -197,7 +216,10 @@ nand_set_fmctrl0(bank, 0); if ((FMCSTAT & (FMCSTAT_BANK0READY << bank))) FMCSTAT = (FMCSTAT_BANK0READY << bank); - FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + FMCTRL1 = FMCTRL1_CLEARRFIFO; + if(nand_wait_rfifo_done()) return 1; + FMCTRL1 = FMCTRL1_CLEARWFIFO; + if(nand_wait_wfifo_done()) return 1; if (nand_send_cmd(NAND_CMD_GET_STATUS)) return 1; while (1) { @@ -207,8 +229,11 @@ if (nand_wait_addrdone()) return 1; if ((FMFIFO & NAND_STATUS_READY)) break; FMCTRL1 = FMCTRL1_CLEARRFIFO; + if(nand_wait_rfifo_done()) return 1; + } FMCTRL1 = FMCTRL1_CLEARRFIFO; + if(nand_wait_rfifo_done()) return 1; return nand_send_cmd(NAND_CMD_READ); } @@ -233,7 +258,13 @@ if (nand_timeout(timeout)) return 1; if (!direction) invalidate_dcache(); if (nand_wait_addrdone()) return 1; - if (!direction) FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + if (!direction) + { + FMCTRL1 = FMCTRL1_CLEARRFIFO; + if(nand_wait_rfifo_done()) return 1; + FMCTRL1 = FMCTRL1_CLEARWFIFO; + if(nand_wait_wfifo_done()) return 1; + } return 0; } @@ -298,7 +329,10 @@ FMCTRL1 = FMCTRL1_DOREADDATA; if (nand_wait_addrdone()) return nand_unlock(0xFFFFFFFF); result = FMFIFO; - FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + FMCTRL1 = FMCTRL1_CLEARRFIFO; + if(nand_wait_rfifo_done()) return 1; + FMCTRL1 = FMCTRL1_CLEARWFIFO; + if(nand_wait_wfifo_done()) return 1; return nand_unlock(result); }