Index: firmware/export/s5l8700.h =================================================================== --- firmware/export/s5l8700.h (Revision 24085) +++ firmware/export/s5l8700.h (Arbeitskopie) @@ -384,11 +384,21 @@ #define FMCSTAT_RBBDONE (1 << 1) #define FMCSTAT_CMDDONE (1 << 2) #define FMCSTAT_ADDRDONE (1 << 3) + +/* #define FMCSTAT_BANK0READY (1 << 4) #define FMCSTAT_BANK1READY (1 << 5) #define FMCSTAT_BANK2READY (1 << 6) #define FMCSTAT_BANK3READY (1 << 7) +*/ +#define FMCSTAT_TRANSDONE (1 << 4) +#define FMCSTAT_WFIFO_HEMPTY (1 << 5) +#define FMCSTAT_RFIFO_HFULL (1 << 6) +#define FMCSTAT_WFIFO_EMPTY (1 << 8) +#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 24085) +++ 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))) + if(nand_timeout(timeout)) return 1; + return 0; +} + uint32_t nand_wait_rbbdone(void) { long timeout = current_tick + HZ / 50; @@ -152,12 +168,12 @@ return 0; } -uint32_t nand_wait_chip_ready(uint32_t bank) +uint32_t nand_wait_transdone(void) { long timeout = current_tick + HZ / 50; - while (!(FMCSTAT & (FMCSTAT_BANK0READY << bank))) - if (nand_timeout(timeout)) return 1; - FMCSTAT = (FMCSTAT_BANK0READY << bank); + while(!(FMCSTAT & FMCSTAT_TRANSDONE)) + if(nand_timeout(timeout)) return 1; + FMCSTAT = FMCSTAT_TRANSDONE; return 0; } @@ -182,12 +198,15 @@ return nand_wait_cmddone(); } +uint32_t nand_wait_status_ready(uint32_t bank); + uint32_t nand_reset(uint32_t bank) { 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())) return 1; FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + if (nand_wait_status_ready(bank)) return 1; return 0; } @@ -195,9 +214,8 @@ { long timeout = current_tick + HZ / 50; 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) { @@ -234,6 +252,7 @@ if (!direction) invalidate_dcache(); if (nand_wait_addrdone()) return 1; if (!direction) FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + else FMCTRL1 = FMCTRL1_CLEARRFIFO; return 0; } @@ -287,18 +306,21 @@ uint32_t nand_get_chip_type(uint32_t bank) { mutex_lock(&nand_mtx); + uint32_t result; - if (nand_reset(bank)) return nand_unlock(0xFFFFFFFF); + nand_set_fmctrl0(bank, 0); /* select bank */ if (nand_send_cmd(0x90)) return nand_unlock(0xFFFFFFFF); FMANUM = 0; FMADDR0 = 0; FMCTRL1 = FMCTRL1_DOTRANSADDR; if (nand_wait_cmddone()) return nand_unlock(0xFFFFFFFF); + FMCSTAT = FMCSTAT_TRANSDONE; + nand_set_fmctrl0(bank, 0); FMDNUM = 4; FMCTRL1 = FMCTRL1_DOREADDATA; if (nand_wait_addrdone()) return nand_unlock(0xFFFFFFFF); result = FMFIFO; - FMCTRL1 = FMCTRL1_CLEARRFIFO | FMCTRL1_CLEARWFIFO; + FMCTRL1 = FMCTRL1_CLEARRFIFO; return nand_unlock(result); } @@ -327,11 +349,11 @@ PDAT4 = 0; PCON5 = (PCON5 & ~0xF) | 3; PUNK5 = 1; - pmu_ldo_set_voltage(4, 0x15); pmu_ldo_power_on(4); sleep(HZ / 20); nand_last_activity_value = current_tick; for (i = 0; i < 4; i++) nand_reset(i); + if(nand_wait_transdone()) return; nand_powered = 1; nand_last_activity_value = current_tick; mutex_unlock(&nand_mtx);