Commit 1d0ed69d authored by Huang Shijie's avatar Huang Shijie Committed by Brian Norris

mtd: nand: add a helper to check the SLC/MLC nand chip

Add a helper to check if a nand chip is SLC or MLC.
This helper makes the code more readable.
Signed-off-by: default avatarHuang Shijie <b32955@freescale.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent 4ae7d228
...@@ -1520,7 +1520,7 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1520,7 +1520,7 @@ int denali_init(struct denali_nand_info *denali)
* so just let controller do 15bit ECC for MLC and 8bit ECC for * so just let controller do 15bit ECC for MLC and 8bit ECC for
* SLC if possible. * SLC if possible.
* */ * */
if (denali->nand.cellinfo & NAND_CI_CELLTYPE_MSK && if (!nand_is_slc(&denali->nand) &&
(denali->mtd.oobsize > (denali->bbtskipbytes + (denali->mtd.oobsize > (denali->bbtskipbytes +
ECC_15BITS * (denali->mtd.writesize / ECC_15BITS * (denali->mtd.writesize /
ECC_SECTOR_SIZE)))) { ECC_SECTOR_SIZE)))) {
......
...@@ -3108,8 +3108,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -3108,8 +3108,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
* ID to decide what to do. * ID to decide what to do.
*/ */
if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
(chip->cellinfo & NAND_CI_CELLTYPE_MSK) && !nand_is_slc(chip) && id_data[5] != 0x00) {
id_data[5] != 0x00) {
/* Calc pagesize */ /* Calc pagesize */
mtd->writesize = 2048 << (extid & 0x03); mtd->writesize = 2048 << (extid & 0x03);
extid >>= 2; extid >>= 2;
...@@ -3141,7 +3140,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -3141,7 +3140,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
(((extid >> 1) & 0x04) | (extid & 0x03)); (((extid >> 1) & 0x04) | (extid & 0x03));
*busw = 0; *busw = 0;
} else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX && } else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) { !nand_is_slc(chip)) {
unsigned int tmp; unsigned int tmp;
/* Calc pagesize */ /* Calc pagesize */
...@@ -3204,7 +3203,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -3204,7 +3203,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
* - ID byte 5, bit[7]: 1 -> BENAND, 0 -> raw SLC * - ID byte 5, bit[7]: 1 -> BENAND, 0 -> raw SLC
*/ */
if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA && if (id_len >= 6 && id_data[0] == NAND_MFR_TOSHIBA &&
!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) && nand_is_slc(chip) &&
(id_data[5] & 0x7) == 0x6 /* 24nm */ && (id_data[5] & 0x7) == 0x6 /* 24nm */ &&
!(id_data[4] & 0x80) /* !BENAND */) { !(id_data[4] & 0x80) /* !BENAND */) {
mtd->oobsize = 32 * mtd->writesize >> 9; mtd->oobsize = 32 * mtd->writesize >> 9;
...@@ -3265,11 +3264,11 @@ static void nand_decode_bbm_options(struct mtd_info *mtd, ...@@ -3265,11 +3264,11 @@ static void nand_decode_bbm_options(struct mtd_info *mtd,
* Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba, * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
* AMD/Spansion, and Macronix. All others scan only the first page. * AMD/Spansion, and Macronix. All others scan only the first page.
*/ */
if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) && if (!nand_is_slc(chip) &&
(maf_id == NAND_MFR_SAMSUNG || (maf_id == NAND_MFR_SAMSUNG ||
maf_id == NAND_MFR_HYNIX)) maf_id == NAND_MFR_HYNIX))
chip->bbt_options |= NAND_BBT_SCANLASTPAGE; chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) && else if ((nand_is_slc(chip) &&
(maf_id == NAND_MFR_SAMSUNG || (maf_id == NAND_MFR_SAMSUNG ||
maf_id == NAND_MFR_HYNIX || maf_id == NAND_MFR_HYNIX ||
maf_id == NAND_MFR_TOSHIBA || maf_id == NAND_MFR_TOSHIBA ||
...@@ -3745,8 +3744,7 @@ int nand_scan_tail(struct mtd_info *mtd) ...@@ -3745,8 +3744,7 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.total = chip->ecc.steps * chip->ecc.bytes; chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
/* Allow subpage writes up to ecc.steps. Not possible for MLC flash */ /* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
!(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
switch (chip->ecc.steps) { switch (chip->ecc.steps) {
case 2: case 2:
mtd->subpage_sft = 1; mtd->subpage_sft = 1;
......
...@@ -795,4 +795,13 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip) ...@@ -795,4 +795,13 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
return le16_to_cpu(chip->onfi_params.src_sync_timing_mode); return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
} }
/*
* Check if it is a SLC nand.
* The !nand_is_slc() can be used to check the MLC/TLC nand chips.
* We do not distinguish the MLC and TLC now.
*/
static inline bool nand_is_slc(struct nand_chip *chip)
{
return !(chip->cellinfo & NAND_CI_CELLTYPE_MSK);
}
#endif /* __LINUX_MTD_NAND_H */ #endif /* __LINUX_MTD_NAND_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment