Commit 91361818 authored by Huang Shijie's avatar Huang Shijie Committed by Brian Norris

mtd: nand: parse out the JEDEC compliant NAND

This patch adds the parsing code for the JEDEC compliant NAND.

Since we need the 0x40 as the column address, this patch also
makes the NAND_CMD_PARAM to use the 8-bit address only.
Signed-off-by: default avatarHuang Shijie <b32955@freescale.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent 7852f896
......@@ -3162,6 +3162,87 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
return 1;
}
/*
* Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise.
*/
static int nand_flash_detect_jedec(struct mtd_info *mtd, struct nand_chip *chip,
int *busw)
{
struct nand_jedec_params *p = &chip->jedec_params;
struct jedec_ecc_info *ecc;
int val;
int i, j;
/* Try JEDEC for unknown chip or LP */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x40, -1);
if (chip->read_byte(mtd) != 'J' || chip->read_byte(mtd) != 'E' ||
chip->read_byte(mtd) != 'D' || chip->read_byte(mtd) != 'E' ||
chip->read_byte(mtd) != 'C')
return 0;
chip->cmdfunc(mtd, NAND_CMD_PARAM, 0x40, -1);
for (i = 0; i < 3; i++) {
for (j = 0; j < sizeof(*p); j++)
((uint8_t *)p)[j] = chip->read_byte(mtd);
if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
le16_to_cpu(p->crc))
break;
}
if (i == 3) {
pr_err("Could not find valid JEDEC parameter page; aborting\n");
return 0;
}
/* Check version */
val = le16_to_cpu(p->revision);
if (val & (1 << 2))
chip->jedec_version = 10;
else if (val & (1 << 1))
chip->jedec_version = 1; /* vendor specific version */
if (!chip->jedec_version) {
pr_info("unsupported JEDEC version: %d\n", val);
return 0;
}
sanitize_string(p->manufacturer, sizeof(p->manufacturer));
sanitize_string(p->model, sizeof(p->model));
if (!mtd->name)
mtd->name = p->model;
mtd->writesize = le32_to_cpu(p->byte_per_page);
/* Please reference to the comment for nand_flash_detect_onfi. */
mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
mtd->erasesize *= mtd->writesize;
mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
/* Please reference to the comment for nand_flash_detect_onfi. */
chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
chip->bits_per_cell = p->bits_per_cell;
if (jedec_feature(chip) & JEDEC_FEATURE_16_BIT_BUS)
*busw = NAND_BUSWIDTH_16;
else
*busw = 0;
/* ECC info */
ecc = &p->ecc_info[0];
if (ecc->codeword_size >= 9) {
chip->ecc_strength_ds = ecc->ecc_bits;
chip->ecc_step_ds = 1 << ecc->codeword_size;
} else {
pr_warn("Invalid codeword size\n");
}
return 1;
}
/*
* nand_id_has_period - Check if an ID string has a given wraparound period
* @id_data: the ID string
......@@ -3527,6 +3608,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
/* Check is chip is ONFI compliant */
if (nand_flash_detect_onfi(mtd, chip, &busw))
goto ident_done;
/* Check if the chip is JEDEC compliant */
if (nand_flash_detect_jedec(mtd, chip, &busw))
goto ident_done;
}
if (!type->name)
......
......@@ -925,7 +925,7 @@ static inline bool nand_is_slc(struct nand_chip *chip)
*/
static inline int nand_opcode_8bits(unsigned int command)
{
return command == NAND_CMD_READID;
return command == NAND_CMD_READID || command == NAND_CMD_PARAM;
}
/* return the supported JEDEC features. */
......
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