Index: firmware/export/s5l8700.h =================================================================== --- firmware/export/s5l8700.h (Revision 23655) +++ firmware/export/s5l8700.h (Arbeitskopie) @@ -389,6 +389,11 @@ #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_HFULL (1 << 6) +#define FMCSTAT_RFIFO_FULL (1 << 9) + /* 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 23655) +++ 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 / 5; + while(!(FMCSTAT & FMCSTAT_WFIFO_HEMPTY)) + if(nand_timeout(timeout)) return 1; + return 0; +} + +uint32_t nand_wait_rfifo_done(void) +{ + long timeout = current_tick + HZ / 5; + while((!(FMCSTAT & FMCSTAT_RFIFO_HFULL))&&(!(FMCSTAT & FMCSTAT_RFIFO_FULL))) /* datasheet says wait for one of them */ + if(nand_timeout(timeout)) return 1; + return 0; +} + uint32_t nand_wait_rbbdone(void) { long timeout = current_tick + HZ / 50; @@ -187,6 +203,7 @@ nand_set_fmctrl0(bank, 0); if (nand_send_cmd(NAND_CMD_RESET)) return 1; if (nand_wait_chip_ready(bank)) return 1; + if((nand_wait_rfifo_done())||(nand_wait_wfifo_done())) return 1; FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; return 0; } @@ -197,7 +214,8 @@ nand_set_fmctrl0(bank, 0); if ((FMCSTAT & (FMCSTAT_BANK0READY << bank))) FMCSTAT = (FMCSTAT_BANK0READY << bank); - FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + if(nand_wait_rfifo_done()) return 1; + FMCTRL1 = FMCTRL1_CLEARRFIFO; if (nand_send_cmd(NAND_CMD_GET_STATUS)) return 1; while (1) { @@ -206,8 +224,10 @@ FMCTRL1 = FMCTRL1_DOREADDATA; if (nand_wait_addrdone()) return 1; if ((FMFIFO & NAND_STATUS_READY)) break; + if(nand_wait_rfifo_done()) return 1; FMCTRL1 = FMCTRL1_CLEARRFIFO; } + if(nand_wait_rfifo_done()) return 1; FMCTRL1 = FMCTRL1_CLEARRFIFO; return nand_send_cmd(NAND_CMD_READ); } @@ -233,7 +253,16 @@ 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) + { + if(nand_wait_rfifo_done()) return 1; + FMCTRL1 = FMCTRL1_CLEARRFIFO; + } + else + { + if((nand_wait_rfifo_done())||(nand_wait_wfifo_done())) return 1; + FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + } return 0; } @@ -298,6 +327,7 @@ FMCTRL1 = FMCTRL1_DOREADDATA; if (nand_wait_addrdone()) return nand_unlock(0xFFFFFFFF); result = FMFIFO; + if((nand_wait_rfifo_done())||(nand_wait_wfifo_done())) return nand_unlock(0xFFFFFFFF); FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; return nand_unlock(result); }