static PSNandInitInfo AT91F_NandReadID(void) { unsigned int uChipID; unsigned char bManufacturerID, bDeviceID; /* * Enable chipset */ NAND_ENABLE_CE(); /* * Ask the Nand its IDs */ WRITE_NAND_COMMAND(CMD_READID); WRITE_NAND_ADDRESS(0x00); /* * Read answer */ bManufacturerID = READ_NAND(); bDeviceID = READ_NAND(); /* * Disable chipset before returning */ NAND_DISABLE_CE(); uChipID = (bManufacturerID << 8) | bDeviceID; return AT91F_GetNandInitInfo(uChipID); }
/* read chip mfr and id * return 0 if they match board config * return 1 if not */ int nand_chip() { int mfr, id; NAND_ENABLE_CE(); if (NanD_Command(NAND_CMD_RESET)) { printf("Err: RESET\n"); NAND_DISABLE_CE(); return 1; } if (NanD_Command(NAND_CMD_READID)) { printf("Err: READID\n"); NAND_DISABLE_CE(); return 1; } NanD_Address(ADDR_COLUMN, 0); mfr = READ_NAND(NAND_ADDR); id = READ_NAND(NAND_ADDR); NAND_DISABLE_CE(); return (mfr != K9F5616_MFR || id != K9F5616_ID); }
static void reset_nandflash(void) { NAND_ENABLE_CE(); WRITE_NAND_COMMAND(0xFF); NAND_WAIT_READY(); NAND_WAIT_READY(); NAND_DISABLE_CE(); }
/* 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; }
/* 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; }
/*! \fn void ifx_nand_select_chip(struct mtd_info *mtd, int chip) \ingroup IFX_NAND_DRV \brief control CE line \param mtd MTD device structure \param chipnumber to select, -1 for deselect \return none */ static void ifx_nand_select_chip(struct mtd_info *mtd, int chip) { struct nand_chip *nand = mtd->priv; switch (chip) { case -1: NAND_DISABLE_CE(nand); IFX_REG_W32_MASK(IFX_EBU_NAND_CON_NANDM, 0, IFX_EBU_NAND_CON); break; case 0: IFX_REG_W32_MASK(0, IFX_EBU_NAND_CON_NANDM, IFX_EBU_NAND_CON); NAND_ENABLE_CE(nand); #if 0 // ctc // NAND_WRITE(NAND_WRITE_CMD, NAND_WRITE_CMD_RESET); // Reset nand chip // Jess Refer from Lantiq (Remove It.) #endif break; default: BUG(); } }