[PATCH v2 4/5] mtd: nand: parse out the JEDEC compliant nand

Huang Shijie b32955 at freescale.com
Fri Feb 14 02:08:54 EST 2014


On Tue, Feb 11, 2014 at 12:32:24PM -0800, Brian Norris wrote:
> Hi Huang,
> 
> Looks good, but I have a few comments, now that I've given the spec a
> closer read.
> 
> On Sat, Feb 08, 2014 at 02:04:00PM +0800, Huang Shijie wrote:
> > This patch adds the parsing code for the JEDEC compliant nand.
> > 
> > Signed-off-by: Huang Shijie <b32955 at freescale.com>
> > ---
> >  drivers/mtd/nand/nand_base.c |   86 ++++++++++++++++++++++++++++++++++++++++++
> >  1 files changed, 86 insertions(+), 0 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> > index 47fdf17..eb9fb49 100644
> > --- a/drivers/mtd/nand/nand_base.c
> > +++ b/drivers/mtd/nand/nand_base.c
> > @@ -3163,6 +3163,88 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip,
> >  }
> >  
> >  /*
> > + * 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);
> 
> Where did you get this READID column address? I may be misreading

I get the column from the Toshiba and Micron datasheet.
the JEDEC really does not mention it.

> something, but I don't even find this in the JESD230A spec.
> 
> > +	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);
> 
> Same here. I don't actually find this column address in the spec. I
ditto.

> really hope this is specified somewhere.
> 
> Also, now that we may have non-zero address to NAND_CMD_PARAM, do we
> need to make this adjustment so it can be used on x16 buswidth? Perhaps this diff?

sorry, I really do not know the x16 issue :(

the gpmi is 8bit.

> 
> diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
> index 84cca611c2fd..1b1ad3d25336 100644
> --- a/include/linux/mtd/nand.h
> +++ b/include/linux/mtd/nand.h
> @@ -921,7 +921,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. */
> 
> > +	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 */
> 
> How did you determine that bit[1] means version 1 (or v0.1)? It's

The bit[1] is the vendor specific version. 
Some Micron chips uses the bit[1], such as MT29F64G08CBAB.

If we do not use the 1 for the it, do you have any suggestion
for the vendor specific version?


> unclear to me how to interpret the revision bitfield here, but it
> appears that bit[1] is not really useful to us yet, unless we're using
> vendor specific parameter page.

> 
> What do we do if we see bit[1] (vendor specific parameter page) but not
> bit[2] (parameter page revision 1.0 / standard revision 1.0)? I'm
> thinking that we should just ignore bit[1] entirely for now, and if the
> flash is missing bit[2], then we can't support it.

some Micron chips do use the bit[1]. i think that's why the JEDEC say:
"supports vendor specific parameter page" for the bit[1].

We'd better keep the support for the bit[1].
> 
> > +
> > +	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;
> 
> ecc_info is an array, and we're only looking at the first entry. This
> might be more clear:
> 
> 	ecc = &p->ecc_info[0];
okay.

> 
> > +
> > +	if (ecc->codeword_size) {
> 
> "The minimum value that shall be reported is 512 bytes (a value of 9)."
> 
> So how about this?
> 
> 	if (ecc->codeword_size >= 9)
okay.
> 
> > +		chip->ecc_strength_ds = ecc->ecc_bits;
> > +		chip->ecc_step_ds = 1 << ecc->codeword_size;
> > +	} else {
> > +		pr_debug("Invalid codeword size\n");
> > +		return 0;
> 
> Do we really want to fail detection if we can't get the ECC parameters?
> That's not what we do for ONFI, and we certainly don't do that for
> extended ID decoding. Right now, ECC specifications are an optional
> feature for autodetection, so I think this should be at most a
> pr_warn(), but return successfully still. See the ONFI detection routine
> for reference.
okay.

thanks
Huang Shijie




More information about the linux-mtd mailing list