/* * drivers/mtd/nand/nand_id_decode.c * * Determine NAND device properties by decoding the READID string * * The following code attempts to encapsulate the knowledge in * mtd-2.6(2011-07-09):nand_base.c:nand_get_flash_type(), refactored according * to three basic schemes: * * 'ID 2' : extract properties from device table. For 2-byte IDs, * or where device ID gives a non-zero page-size * (SP devices). * * 'Extended ID': decode properties from ID string where possible, falling * back to device table. For 3/4/5-byte IDs. * * 'ID 6' : decode properties from ID string where possible, falling * back to device table. For 6-byte IDs. * * The refactoring is primarily aimed at simplifying the way in which decoding * exceptions (growing fast!) can be accomodated. * * Tested on all devices found in * http://www.linux-mtd.infradead.org/nand-data/nanddata.html (2011-07-09), * EXCLUDING the following: * * - 'ONFI-only': READID is insufficient to decode all properties. * * - Toshiba devices: datasheets only present decode table, not actual * READID strings. * * * Author: Angus Clark * Copyright (c) 2012 STMicroelectronics Limited * * ------------------------------------------------------------------------ * May be copied or modified under the terms of the GNU General Public * License Version 2.0 only. See linux/COPYING for more information. * ------------------------------------------------------------------------ * */ #include #include static struct nand_flash_dev *search_nand_flash_dev(uint8_t id); static int nand_decode_id_2(struct mtd_info *mtd, struct nand_chip *chip, struct nand_flash_dev *type, uint8_t *id, int id_len); static int nand_decode_id_ext(struct mtd_info *mtd, struct nand_chip *chip, struct nand_flash_dev *type, uint8_t *id, int id_len); static int nand_decode_id_6(struct mtd_info *mtd, struct nand_chip *chip, struct nand_flash_dev *type, uint8_t *id, int id_len); static void nand_decode_id_bbm(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *id, int id_len); int nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *id, int id_len) { struct nand_flash_dev *type = NULL; int ret = 0; /* * Find 'nand_flash_dev' in table */ type = search_nand_flash_dev(id[1]); if (!type) { pr_err("[MTD][NAND]:%s: failed to find NAND " "device ID [%02x] in table\n", __func__, id[1]); return 1; } /* * Decode ID string */ if (id_len == 2 || type->pagesize) ret = nand_decode_id_2(mtd, chip, type, id, id_len); else if (id_len <= 5) ret = nand_decode_id_ext(mtd, chip, type, id, id_len); else if (id_len == 6) ret = nand_decode_id_6(mtd, chip, type, id, id_len); else ret = 1; if (ret) { pr_err("[MTD][NAND]:%s:failed to decode NAND " "device ID\n", __func__); return ret; } /* * Determine bad-block marker scheme */ nand_decode_id_bbm(mtd, chip, id, id_len); return 0; } EXPORT_SYMBOL_GPL(nand_decode_id); static struct nand_flash_dev *search_nand_flash_dev(uint8_t id) { struct nand_flash_dev *device; for (device = nand_flash_ids; device->name != NULL; device++) { if (device->id == id) return device; } return NULL; } static int nand_decode_id_2(struct mtd_info *mtd, struct nand_chip *chip, struct nand_flash_dev *type, uint8_t *id, int id_len) { mtd->writesize = type->pagesize; mtd->oobsize = type->pagesize / 32; chip->chipsize = ((uint64_t)type->chipsize) << 20; /* SPANSION/AMD (S30ML-P ORNAND) has non-standard block size */ if (id[0] == NAND_MFR_AMD) mtd->erasesize = 512 * 1024; else mtd->erasesize = type->erasesize; /* Get chip options from table */ chip->options &= ~NAND_CHIPOPTIONS_MSK; chip->options |= type->options & NAND_CHIPOPTIONS_MSK; chip->options |= NAND_NO_AUTOINCR; if (mtd->writesize > 512) chip->options |= NAND_NO_READRDY; /* Assume some defaults */ chip->bits_per_cell = 1; chip->cellinfo = 0; chip->planes_per_chip = 1; chip->luns_per_chip = 1; return 0; } static int nand_decode_id_ext(struct mtd_info *mtd, struct nand_chip *chip, struct nand_flash_dev *type, uint8_t *id, int id_len) { uint8_t data; if (id_len < 3 || id_len > 5) { pr_err("[MTD][NAND]:%s: invalid ID length [%d]\n", __func__, id_len); return 1; } /* Clear chip options */ chip->options &= ~NAND_CHIPOPTIONS_MSK; /* ID4: Planes/Chip Size */ if (id[0] == NAND_MFR_HYNIX && id_len == 5 && id[4] == 0 && (id[1] == 0xDA || id[1] == 0xCA)) { /* Non-standard decode: HY27UF082G2A, HY27UF162G2A */ chip->planes_per_chip = 2; chip->chipsize = (128 * 1024 * 1024) * chip->planes_per_chip; } else if (id_len == 5) { /* - Planes per chip: ID4[3:2] */ data = (id[4] >> 2) & 0x3; chip->planes_per_chip = 1 << data; /* - Plane size: ID4[6:4], multiples of 8MiB */ data = (id[4] >> 4) & 0x7; chip->chipsize = (8 * 1024 * 1024) << data; /* plane size */ chip->chipsize *= chip->planes_per_chip; /* chip size */ } else { /* Fall-back to table */ chip->planes_per_chip = 1; chip->chipsize = (((uint64_t)type->chipsize) << 20); } /* ID3: Page/OOB/Block Size */ if (id_len >= 4) { /* - Page Size: ID3[1:0] */ data = id[3] & 0x3; mtd->writesize = 1024 << data; /* multiples of 1k */ /* - OOB Size: ID3[2] */ data = (id[3] >> 2) & 0x1; mtd->oobsize = 8 << data; /* per 512 */ mtd->oobsize *= mtd->writesize / 512; /* per page */ /* - Block Size: ID3[5:4] */ data = (id[3] >> 4) & 0x3; mtd->erasesize = (64 * 1024) << data; /* multiples of 64k */ /* - Bus Width; ID3[6] */ if ((id[3] >> 6) & 0x1) chip->options |= NAND_BUSWIDTH_16; } else { /* Fall-back to table */ mtd->writesize = type->pagesize; mtd->oobsize = type->pagesize / 32; if (type->options & NAND_BUSWIDTH_16) chip->options |= NAND_BUSWIDTH_16; } /* Some default 'chip' options */ chip->options |= NAND_NO_AUTOINCR; if (chip->planes_per_chip > 1) chip->options |= NAND_MULTIPLANE_READ; if (mtd->writesize > 512) chip->options |= NAND_NO_READRDY; if (id[0] == NAND_MFR_SAMSUNG && mtd->writesize > 512) chip->options |= NAND_SAMSUNG_LP_OPTIONS; /* ID2: Package/Cell/Features */ /* Note, ID2 invalid, or documented as "don't care" on certain devices * (assume some defaults) */ if (id_len == 4 && id[0] == NAND_MFR_HYNIX && (id[1] == 0xF1 || id[1] == 0xC1 || id[1] == 0xA1 || id[1] == 0xAD || id[1] == 0xDA || id[1] == 0xCA)) { /* HY27{U,S}F{08,16}1G2M; * HY27UF{08,16}2G2M */ chip->luns_per_chip = 1; chip->bits_per_cell = 1; chip->cellinfo = 0; chip->options |= (NAND_CACHEPRG | NAND_CACHERD | NAND_COPYBACK); } else if (id_len == 4 && id[0] == NAND_MFR_MICRON && (id[1] == 0xDA || id[1] == 0xCA || id[1] == 0xDC || id[1] == 0xCC || id[1] == 0xAA || id[1] == 0xBA)) { /* MT29F2G{08,16}AAB; * MT29F4G{08,16}BAB; * MT29F2G{08,16}A{A,B}C; * MT29F4G08BAC */ chip->luns_per_chip = 1; chip->bits_per_cell = 1; chip->cellinfo = 0; chip->options |= (NAND_CACHEPRG | NAND_CACHERD | NAND_COPYBACK); } else if (id_len == 4 && id[0] == NAND_MFR_SAMSUNG && (id[1] == 0xF1 || id[1] == 0xA1)) { /* K9F1G08{U,Q}A */ chip->luns_per_chip = 1; chip->bits_per_cell = 1; chip->cellinfo = 0; chip->options |= (NAND_CACHEPRG | NAND_CACHERD | NAND_COPYBACK); } else { /* - LUNs: ID2[1:0] */ data = id[2] & 0x3; chip->luns_per_chip = 0x1 << data; /* - Cell levels: ID2[3:2] */ data = (id[2] >> 2) & 0x3; chip->bits_per_cell = data + 1; /* - Interleave: ID2[6] */ if ((id[2] >> 6) & 0x1) chip->options |= NAND_MULTILUN; /* - Cache Program: ID2[7] */ if ((id[2] >> 7) & 0x1) chip->options |= NAND_CACHEPRG; /* - Copy to 'cellinfo' */ chip->cellinfo = id[2]; } return 0; } static int nand_decode_id_6(struct mtd_info *mtd, struct nand_chip *chip, struct nand_flash_dev *type, uint8_t *id, int id_len) { uint8_t data; if (id_len != 6) { pr_err("[MTD][NAND]:%s: invalid ID length [%d]\n", __func__, id_len); return 1; } chip->chipsize = (((uint64_t)type->chipsize) << 20); /* ID4: Planes */ /* - Number: ID4[3:2] */ data = (id[4] >> 2) & 0x3; chip->planes_per_chip = 1 << data; /* ID3: Page/OOB/Block Size */ /* - Page Size: ID3[1:0] */ data = id[3] & 0x3; mtd->writesize = 2048 << data; /* multiples of 2k */ /* - OOB Size: ID3[6,3:2] */ data = ((id[3] >> 4) & 0x4) | ((id[3] >> 2) & 0x3); if (id[0] == NAND_MFR_SAMSUNG) { switch (data) { case 1: mtd->oobsize = 128; break; case 2: mtd->oobsize = 218; break; case 3: mtd->oobsize = 400; break; case 4: mtd->oobsize = 436; break; case 5: mtd->oobsize = 640; break; default: pr_err("[MTD][NAND]:%s: unknown OOB size\n", __func__); return 1; break; } } else { switch (data) { case 0: mtd->oobsize = 128; break; case 1: mtd->oobsize = 224; break; case 2: mtd->oobsize = 448; break; default: pr_err("[MTD][NAND]:%s: unknown OOB size\n", __func__); break; } } /* - Block Size: ID3[7,5:4] */ data = ((id[3] >> 5) & 0x4) | ((id[3] >> 4) & 0x3); switch (data) { case 0: case 1: case 2: mtd->erasesize = (128 * 1024) << data; break; case 3: if (id[0] == NAND_MFR_SAMSUNG) mtd->erasesize = (1024 * 1024); else mtd->erasesize = (768 * 1024); break; case 4: case 5: mtd->erasesize = (1024 * 1024) << (data - 4); break; default: pr_err("[MTD][NAND]:%s: unknown block size\n", __func__); return 1; break; } /* Some default 'chip' options */ chip->options &= ~NAND_CHIPOPTIONS_MSK; chip->options |= NAND_NO_AUTOINCR; if (chip->planes_per_chip > 1) chip->options |= NAND_MULTIPLANE_READ; if (mtd->writesize > 512) chip->options |= NAND_NO_READRDY; if (id[0] == NAND_MFR_SAMSUNG && mtd->writesize > 512) chip->options |= NAND_SAMSUNG_LP_OPTIONS; /* ID2: Package/Cell/Features */ /* - LUNs: ID2[1:0] */ data = id[2] & 0x3; chip->luns_per_chip = 0x1 << data; /* - Cell levels: ID2[3:2] */ data = (id[2] >> 2) & 0x3; chip->bits_per_cell = data + 1; /* - Interleave: ID2[6] */ if ((id[2] >> 6) & 0x1) chip->options |= NAND_MULTILUN; /* - Cache Program: ID2[7] */ if ((id[2] >> 7) & 0x1) chip->options |= NAND_CACHEPRG; /* - Copy to 'cellinfo' */ chip->cellinfo = id[2]; /* Bus Width, from table */ chip->options |= (type->options & NAND_BUSWIDTH_16); return 0; } /* * Heuristics for factory-programmed bad-block marker (BBM) schemes, largely * based on code in mtd-2.6 (2011-07-09) * nand_base.c:nand_get_flash_type(), and datasheets for devices in * http://www.linux-mtd.infradead.org/nand-data/nanddata.html (2011-07-09). */ static void nand_decode_id_bbm(struct mtd_info *mtd, struct nand_chip *chip, uint8_t *id, int id_len) { /* * Some special cases first */ /* Hynix HY27US1612{1,2}B: 3rd word for x16 device! */ if (id[0] == NAND_MFR_HYNIX && id[1] == 0x56) { chip->bbt_options = (NAND_BBM_PAGE_0 | NAND_BBM_PAGE_1 | NAND_BBM_BYTE_OOB_5); return; } /* Hynix H27UAG8T2A: last and last-2 pages, byte 0 */ if (id[0] == NAND_MFR_HYNIX && id_len == 6 && id[1] == 0xD5 && id[2] == 0x94 && id[3] == 0x25 && id[4] == 0x44 && id[5] == 0x41) { chip->bbt_options = (NAND_BBM_PAGE_LAST | NAND_BBM_PAGE_LMIN2 | NAND_BBM_BYTE_OOB_0); return; } /* Numonyx/ST 2K/4K pages, x8 bus use BOTH byte 0 and 5 (drivers may * need to disable 'byte 5' depending on ECC layout) */ if (!(chip->options & NAND_BUSWIDTH_16) && mtd->writesize >= 2048 && id[0] == NAND_MFR_STMICRO) { chip->bbt_options = (NAND_BBM_PAGE_0 | NAND_BBM_BYTE_OOB_0 | NAND_BBM_BYTE_OOB_5); return; } /* Samsung and Hynix MLC NAND: last page, byte 0; and 1st page for 8KiB * page devices */ if ((id[0] == NAND_MFR_SAMSUNG || id[0] == NAND_MFR_HYNIX) && chip->bits_per_cell == 2) { chip->bbt_options = NAND_BBM_PAGE_LAST | NAND_BBM_BYTE_OOB_0; if (mtd->writesize == 8192) chip->bbt_options |= NAND_BBM_PAGE_0; return; } /* Micron 2KiB page devices use 1st and 2nd page, byte 0 */ if (id[0] == NAND_MFR_MICRON && mtd->writesize == 2048) { chip->bbt_options = NAND_BBM_PAGE_0 | NAND_BBM_PAGE_1 | NAND_BBM_BYTE_OOB_0; return; } /* * For the rest... */ /* Scan at least the first page */ chip->bbt_options = NAND_BBM_PAGE_0; /* Also 2nd page for SLC Samsung, Hynix, Toshia, and AMD/Spansion */ if (chip->bits_per_cell == 1 && (id[0] == NAND_MFR_SAMSUNG || id[0] == NAND_MFR_HYNIX || id[0] == NAND_MFR_TOSHIBA || id[0] == NAND_MFR_AMD)) chip->bbt_options |= NAND_BBM_PAGE_1; /* SP x8 devices use 6th byte OOB; everything else uses 1st byte OOB */ if (mtd->writesize == 512 && !(chip->options & NAND_BUSWIDTH_16)) chip->bbt_options |= NAND_BBM_BYTE_OOB_5; else chip->bbt_options |= NAND_BBM_BYTE_OOB_0; return; }