From: Scott Wood <scottwood@freescale.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v5 2/8] lpc32xx: mtd: nand: add MLC NAND controller
Date: Fri, 13 Mar 2015 16:57:33 -0500 [thread overview]
Message-ID: <1426283853.27998.11.camel@freescale.com> (raw)
In-Reply-To: <1426233873-12690-3-git-send-email-albert.aribaud@3adev.fr>
On Fri, 2015-03-13 at 09:04 +0100, Albert ARIBAUD (3ADEV) wrote:
> + /* go through all four small pages */
> + for (i = 0; i < 4; i++) {
> + /* start auto decode (reads 528 NAND bytes) */
> + writel(0, &lpc32xx_nand_mlc_registers->ecc_auto_dec_reg);
> + /* wait for controller to return to ready state */
> + timeout = LPC32X_NAND_TIMEOUT;
> + do {
> + if (timeout-- == 0)
> + return -1;
> + status = readl(&lpc32xx_nand_mlc_registers->isr);
> + } while (!(status & ISR_CONTROLLER_READY));
How much time does 10000 reads of this register equate to? Are you sure
it's enough? Timeouts should generally be in terms of time, not loop
iterations.
> +static int read_single_page(uint8_t *dest, int page,
> + struct lpc32xx_oob *oob)
> +{
> + int status, i, timeout, err, max_bitflips = 0;
> +
> + /* enter read mode */
> + writel(NAND_CMD_READ0, &lpc32xx_nand_mlc_registers->cmd);
> + /* send column (lsb then MSB) and page (lsb to MSB) */
> + writel(0, &lpc32xx_nand_mlc_registers->addr);
> + writel(0, &lpc32xx_nand_mlc_registers->addr);
> + writel(page & 0xff, &lpc32xx_nand_mlc_registers->addr);
> + writel((page>>8) & 0xff, &lpc32xx_nand_mlc_registers->addr);
> + writel((page>>16) & 0xff, &lpc32xx_nand_mlc_registers->addr);
> + /* start reading */
> + writel(NAND_CMD_READSTART, &lpc32xx_nand_mlc_registers->cmd);
> +
> + /* large page auto decode read */
> + for (i = 0; i < 4; i++) {
> + /* start auto decode (reads 528 NAND bytes) */
> + writel(0, &lpc32xx_nand_mlc_registers->ecc_auto_dec_reg);
> + /* wait for controller to return to ready state */
> + timeout = LPC32X_NAND_TIMEOUT;
> + do {
> + if (timeout-- == 0)
> + return -1;
> + status = readl(&lpc32xx_nand_mlc_registers->isr);
> + } while (!(status & ISR_CONTROLLER_READY))
> + ;
> + /* return -1 if hard error */
> + if (status & ISR_DECODER_FAILURE)
> + return -1;
> + /* keep count of maximum bitflips performed */
> + if (status & ISR_DECODER_ERROR) {
> + err = ISR_DECODER_ERRORS(status);
> + if (err > max_bitflips)
> + max_bitflips = err;
> + }
> + /* copy first 512 bytes into buffer */
> + memcpy(dest+i*512, lpc32xx_nand_mlc_registers->buff, 512);
> + /* copy next 6 bytes bytes into OOB buffer */
> + memcpy(&oob->free[i], lpc32xx_nand_mlc_registers->buff, 6);
> + }
> + return max_bitflips;
> +}
> +
Why keep track of max_bitflips if the caller doesn't use it?
> +#define LARGE_PAGE_SIZE 2048
> +
> +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
> +{
> + struct lpc32xx_oob oob;
> + unsigned int page = offs / LARGE_PAGE_SIZE;
> + unsigned int left = DIV_ROUND_UP(size, LARGE_PAGE_SIZE);
> +
> + while (left) {
> + int res = read_single_page(dst, page, &oob);
> + page++;
> + /* if read succeeded, even if fixed by ECC */
> + if (res >= 0) {
> + /* skip bad block */
> + if (oob.free[0].free_oob_bytes[0] != 0xff)
> + continue;
> + if (oob.free[0].free_oob_bytes[1] != 0xff)
> + continue;
> + /* page is good, keep it */
> + dst += LARGE_PAGE_SIZE;
> + left--;
> + }
You should be checking the designated page(s) of the block, rather than
the current page, for the bad block markers -- and skipping the entire
block if it's bad.
Also, if you fail ECC, that should be a fatal error, not something to
silently skip.
-Scott
next prev parent reply other threads:[~2015-03-13 21:57 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-13 8:04 [U-Boot] [PATCH v5 0/8] Extend LPC32xx functionality and add LPC32xx-based work_92015 board Albert ARIBAUD
2015-03-13 8:04 ` [U-Boot] [PATCH v5 1/8] lpc32xx: add Ethernet support Albert ARIBAUD
2015-03-13 8:04 ` [U-Boot] [PATCH v5 2/8] lpc32xx: mtd: nand: add MLC NAND controller Albert ARIBAUD
2015-03-13 8:04 ` [U-Boot] [PATCH v5 3/8] lpc32xx: i2c: add LPC32xx I2C interface support Albert ARIBAUD
2015-03-13 8:04 ` [U-Boot] [PATCH v5 4/8] lpc32xx: add GPIO support Albert ARIBAUD
2015-03-13 8:04 ` [U-Boot] [PATCH v5 5/8] lpc32xx: add LPC32xx SSP support (SPI mode) Albert ARIBAUD
2015-03-13 8:04 ` [U-Boot] [PATCH v5 6/8] dtt: add ds620 support Albert ARIBAUD
2015-03-13 8:04 ` [U-Boot] [PATCH v5 7/8] lpc32xx: add lpc32xx-spl.bin boot image target Albert ARIBAUD
2015-03-13 8:04 ` [U-Boot] [PATCH v5 8/8] lpc32xx: add support for board work_92105 Albert ARIBAUD
2015-03-13 21:57 ` Scott Wood [this message]
2015-03-14 14:27 ` [U-Boot] [PATCH v5 2/8] lpc32xx: mtd: nand: add MLC NAND controller Albert ARIBAUD
2015-03-16 21:30 ` Scott Wood
2015-03-17 7:31 ` Albert ARIBAUD
2015-03-14 0:33 ` [U-Boot] [PATCH v5 0/8] Extend LPC32xx functionality and add LPC32xx-based work_92015 board Simon Glass
2015-03-14 13:49 ` Albert ARIBAUD
2015-03-16 15:46 ` Simon Glass
2015-03-16 16:28 ` Anish Khurana
2015-03-16 17:40 ` Simon Glass
2015-03-16 20:28 ` Albert ARIBAUD
2015-03-23 23:55 ` Simon Glass
2015-03-24 8:09 ` Albert ARIBAUD
2015-04-08 3:20 ` Simon Glass
2015-04-08 6:12 ` Albert ARIBAUD
2015-04-23 15:16 ` Simon Glass
2015-04-24 5:24 ` Albert ARIBAUD
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1426283853.27998.11.camel@freescale.com \
--to=scottwood@freescale.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.