static void reset_nandflash(void) { NAND_ENABLE_CE(); WRITE_NAND_COMMAND(0xFF); NAND_WAIT_READY(); NAND_WAIT_READY(); NAND_DISABLE_CE(); }
static int ifx_nand_ready(struct mtd_info *mtd) { struct nand_chip *nand = mtd->priv; NAND_WAIT_READY(nand); return 1; }
/* read from the 16 bytes of oob data that correspond to a 512 byte page. */ static int nand_read_oob(u_char *buf, ulong page_addr) { u16 val; int cntr; NAND_ENABLE_CE(); /* set pin low */ NanD_Command(NAND_CMD_READOOB); NanD_Address(ADDR_COLUMN_PAGE, page_addr>>1); NAND_WAIT_READY(); for (cntr = 0; cntr < 8; cntr++){ val = READ_NAND(NAND_ADDR); *buf++ = val & 0xff; *buf++ = val >> 8; } NAND_WAIT_READY(); NAND_DISABLE_CE(); /* set pin high */ return 0; }
/* read a page with ECC */ static int nand_read_page(u_char *buf, ulong page_addr) { u_char ecc_code[6]; u_char ecc_calc[3]; u_char oob_buf[16]; u_char *p; u16 val; int cntr; NAND_ENABLE_CE(); NanD_Command(NAND_CMD_READ0); NanD_Address(ADDR_COLUMN_PAGE, page_addr>>1); NAND_WAIT_READY(); p = buf; for (cntr = 0; cntr < 256; cntr++){ val = READ_NAND(NAND_ADDR); *p++ = val & 0xff; *p++ = val >> 8; } p = oob_buf; for (cntr = 0; cntr < 8; cntr++){ val = READ_NAND(NAND_ADDR); *p++ = val & 0xff; *p++ = val >> 8; } NAND_DISABLE_CE(); /* set pin high */ /* Pick the ECC bytes out of the oob data */ for (cntr = 0; cntr < 6; cntr++) ecc_code[cntr] = oob_buf[ecc_pos[cntr]]; if ((oob_buf[eccvalid_pos] & 0x0f) != 0x0f) { nand_calculate_ecc (buf, &ecc_calc[0]); if (nand_correct_data (buf, &ecc_code[0], &ecc_calc[0]) == -1) { printf ("ECC Failed, page 0x%08x\n", page_addr); return 1; } } if ((oob_buf[eccvalid_pos] & 0xf0) != 0xf0) { nand_calculate_ecc (buf + 256, &ecc_calc[0]); if (nand_correct_data (buf + 256, &ecc_code[3], &ecc_calc[0]) == -1) { printf ("ECC Failed, page 0x%08x\n", page_addr+0x100); return 1; } } return 0; }
/* NanD_Command: Send a flash command to the flash chip */ static int NanD_Command(unsigned char command) { NAND_CTL_SETCLE(NAND_ADDR); WRITE_NAND_COMMAND(command, NAND_ADDR); NAND_CTL_CLRCLE(NAND_ADDR); if(command == NAND_CMD_RESET){ unsigned char ret_val; NanD_Command(NAND_CMD_STATUS); do{ ret_val = READ_NAND(NAND_ADDR);/* wait till ready */ } while((ret_val & 0x40) != 0x40); } NAND_WAIT_READY(); return 0; }
/* NanD_Address: Set the current address for the flash chip */ static int NanD_Address(int numbytes, unsigned long ofs) { int i; NAND_CTL_SETALE(NAND_ADDR); if (numbytes == ADDR_COLUMN || numbytes == ADDR_COLUMN_PAGE) WRITE_NAND_ADDRESS(ofs, NAND_ADDR); ofs = ofs >> 8; if (numbytes == ADDR_PAGE || numbytes == ADDR_COLUMN_PAGE) for (i = 0; i < 2; i++, ofs = ofs >> 8) WRITE_NAND_ADDRESS(ofs, NAND_ADDR); NAND_CTL_CLRALE(NAND_ADDR); NAND_WAIT_READY(); return 0; }