[PATCH] mtd: nand: Add support for Micron on-die ECC controller (rev2).
Gupta, Pekon
pekon at ti.com
Fri Mar 28 04:37:47 EDT 2014
Hi,
>From: Gerhard Sittig [mailto:gsi at denx.de]
>>On Thu, 2014-03-27 at 06:56 +0000, Gupta, Pekon wrote:
>> >From: David Mosberger
[...]
>> >+/**
>> >+ * nand_read_page_on_die - [INTERN] read raw page data without ecc
>> >+ * @mtd: mtd info structure
>> >+ * @chip: nand chip info structure
>> >+ * @buf: buffer to store read data
>> >+ * @oob_required: caller requires OOB data read to chip->oob_poi
>> >+ * @page: page number to read
>> >+ */
>> >+static int nand_read_page_on_die(struct mtd_info *mtd, struct nand_chip *chip,
>> >+ uint8_t *buf, int oob_required, int page)
>> >+{
>> >+ uint32_t failed;
>> >+ int ret;
>> >+
>> >+ failed = mtd->ecc_stats.failed;
>> >+
>>
>> This is the entry point of chip->ecc.read_page(), So, your first call to ecc.read_buf
>> should have happened here, not in check_for_bitflips(). And you should have just
>> passed the read_buffer to for checking of bit-flips.
>>
>> >+ ret = check_read_status_on_die(mtd, chip, page);
>> Also this should have been part of nand_chip->ecc.correct() interface.
>
>AFAIU the sequence of commands which the NAND chip requires
>doesn't quite map to the sequence of what the MTD layer does
>(emit the read command, read the data, optionally check ECC)
>
>when "on die ECC" is enabled, the chip requires a sequence of
>- read page command (READ0, addresses, READSTART)
>- status check (mandatory! cmd 70, to check FAIL and REWRITE bits)
>- re-enter data read mode (READ0, _without_ addresses and START)
>- fetch data bytes
>
I checked Micron Datasheet for "MT29F4G16ABADAWP by name
"m60a_4gb_8gb_16gb_ecc_nand.pdf" and on its
"Figure 39: READ PAGE (00h-30h) Operation with Internal ECC Enabled"
There is no mention of above third step.
As per the "figure 39" a READ_PAGE Operation with internal ECC enabled
requires following sequence..
- [00h] <address> <address> ... <address> [30h] /* READ_PAGE command */
- [70h] <status> [00h] /* READ_STATUS command */
And after that data comes our serial on the bus. So in that case you can
>actually the READ0 plus READSTART does a transfer from the chip's
>array into the chip's caches, before data is fetched out of the
>chip into the SoC; the repeated READ0 does some kind of "rewind"
>from status output to data output, it doesn't re-read the array
>within the chip
>
Agree.. All I'm saying is if you merge "check_read_status_on_die()" into
nand_read_page_on_die() then this would map to normal NAND driver flow.
nand_read_page_on_die( ... ) {
(a) chip->cmdfunc(mtd, NAND_CMD_READ0, column, page); /* READ_PAGE command */
(b) /* Check ECC status of page just transferred into NAND's page buffer: */
chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
status = chip->read_byte(mtd);
(c) /* Read the data out from the NAND device */
chip->read_buf(mtd, buf, mtd->writesize);
if (oob_required)
chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
(d) /* check for ECC errors */
if (status & NAND_STATUS_FAIL) {
/* Page has invalid ECC, but still pass to above layers */
return -EBADMSG;
} else if (status & NAND_STATUS_REWRITE) {
bitflip_count = chip->ecc.correct( mtd, buf, , ... )
return bitflip_count;
} else {
return 0;
}
}
Where; chip->ecc.correct = check_for_bitflips();
Above implementation, as you already fetch the data from NAND device
at the start, it saves you from one extra read done in check_for_bitflips()
+ /* Read entire page w/OOB area with on-die ECC on: */
+ chip->read_buf(mtd, chkbuf, read_size);
Also, you have to return the read_data, even in case of ECC failures,
which was not earlier done in check_read_status_on_die()
[...]
>> (1) read buffer (with on-die ECC == ON)
>> (2) check for bit-flips (just pass the read_buffer)
>> (3) correct bit-flips (again just pass read_buffer)
>> Then probably you don't need this call, and you can re-use existing generic
>> NAND driver implementations.
>
>unfortunately this is not possible according to the chip's
>datasheet; even if you _evaluate_ the status only later, you have
>to _fetch_ it before the data, and thus do the command re-issue
>dance, and cannot use nand_command_lp() since it automatically
>does READSTART for READ0
>
I have broken (1) into (a) + (b) + (c) above.
And (2) + (3) = (d), where, (3) is actually chip->ecc.correct() = check_for_bitflips().
Hope that clarifies the intend..
With regards, pekon
More information about the linux-mtd
mailing list