From: Michael Trimarchi <michael@amarulasolutions.com>
To: Ye Li <ye.li@nxp.com>
Cc: Miquel Raynal <miquel.raynal@bootlin.com>,
u-boot@lists.denx.de, Fabio Estevam <festevam@denx.de>,
Dario Binacchi <dario.binacchi@amarulasolutions.com>,
Sean Anderson <sean.anderson@seco.com>
Subject: [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping
Date: Sat, 23 Apr 2022 10:11:55 +0200 [thread overview]
Message-ID: <20220423081155.27687-3-michael@amarulasolutions.com> (raw)
In-Reply-To: <20220423081155.27687-1-michael@amarulasolutions.com>
The file was fill of problems and bugs. The bad block are marked
beginning of erase block. The first erase block was never checked
and the specific function to skip bad block in fit image was never
implemented. The imx8mn bootrom seems that not handle the bad
block as expected so this needed later to switch from boot rom
loader to uboot spl one
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
---
drivers/mtd/nand/raw/mxs_nand_spl.c | 90 ++++++++++++++++-------------
1 file changed, 49 insertions(+), 41 deletions(-)
diff --git a/drivers/mtd/nand/raw/mxs_nand_spl.c b/drivers/mtd/nand/raw/mxs_nand_spl.c
index 59a67ee414..c1a833d6c8 100644
--- a/drivers/mtd/nand/raw/mxs_nand_spl.c
+++ b/drivers/mtd/nand/raw/mxs_nand_spl.c
@@ -218,14 +218,14 @@ void nand_init(void)
mxs_nand_setup_ecc(mtd);
}
-int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
{
- struct nand_chip *chip;
- unsigned int page;
+ unsigned int sz;
+ unsigned int block, lastblock;
+ unsigned int page, page_offset;
unsigned int nand_page_per_block;
- unsigned int sz = 0;
+ struct nand_chip *chip;
u8 *page_buf = NULL;
- u32 page_off;
chip = mtd_to_nand(mtd);
if (!chip->numchips)
@@ -235,47 +235,42 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
if (!page_buf)
return -ENOMEM;
- page = offs >> chip->page_shift;
- page_off = offs & (mtd->writesize - 1);
+ /* offs has to be aligned to a page address! */
+ block = offs / mtd->erasesize;
+ lastblock = (offs + size - 1) / mtd->erasesize;
+ page = (offs % mtd->erasesize) / mtd->writesize;
+ page_offset = offs % mtd->writesize;
nand_page_per_block = mtd->erasesize / mtd->writesize;
- debug("%s offset:0x%08x len:%d page:%x\n", __func__, offs, size, page);
-
- while (size) {
- if (mxs_read_page_ecc(mtd, page_buf, page) < 0)
- return -1;
-
- if (size > (mtd->writesize - page_off))
- sz = (mtd->writesize - page_off);
- else
- sz = size;
-
- memcpy(buf, page_buf + page_off, sz);
-
- offs += mtd->writesize;
- page++;
- buf += (mtd->writesize - page_off);
- page_off = 0;
- size -= sz;
-
- /*
- * Check if we have crossed a block boundary, and if so
- * check for bad block.
- */
- if (!(page % nand_page_per_block)) {
- /*
- * Yes, new block. See if this block is good. If not,
- * loop until we find a good block.
- */
- while (is_badblock(mtd, offs, 1)) {
- page = page + nand_page_per_block;
- /* Check i we've reached the end of flash. */
- if (page >= mtd->size >> chip->page_shift) {
+ while (block <= lastblock && size >= 0) {
+ if (!is_badblock(mtd, mtd->erasesize * block, 1)) {
+ /* Skip bad blocks */
+ while (page < nand_page_per_block) {
+ int curr_page = nand_page_per_block * block + page;
+
+ if (mxs_read_page_ecc(mtd, page_buf, curr_page) < 0) {
free(page_buf);
- return -ENOMEM;
+ return -EIO;
}
+
+ if (size > (mtd->writesize - page_offset))
+ sz = (mtd->writesize - page_offset);
+ else
+ sz = size;
+
+ memcpy(dst, page_buf + page_offset, sz);
+ dst += sz;
+ size -= sz;
+ page_offset = 0;
+ page++;
}
+
+ page = 0;
+ } else {
+ lastblock++;
}
+
+ block++;
}
free(page_buf);
@@ -294,6 +289,19 @@ void nand_deselect(void)
u32 nand_spl_adjust_offset(u32 sector, u32 offs)
{
- /* Handle the offset adjust in nand_spl_load_image,*/
+ unsigned int block, lastblock;
+
+ block = sector / mtd->erasesize;
+ lastblock = (sector + offs) / mtd->erasesize;
+
+ while (block <= lastblock) {
+ if (is_badblock(mtd, block * mtd->erasesize, 1)) {
+ offs += mtd->erasesize;
+ lastblock++;
+ }
+
+ block++;
+ }
+
return offs;
}
--
2.25.1
next prev parent reply other threads:[~2022-04-23 8:12 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-23 8:11 [PATCH 0/2] MXS nand fixes in SPL Michael Trimarchi
2022-04-23 8:11 ` [PATCH 1/2] nand: raw: mxs_nand: Fix specific hook registration Michael Trimarchi
2022-04-23 8:11 ` Michael Trimarchi [this message]
2022-04-25 11:45 ` [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping Michael Nazzareno Trimarchi
2022-04-26 12:48 ` Fabio Estevam
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=20220423081155.27687-3-michael@amarulasolutions.com \
--to=michael@amarulasolutions.com \
--cc=dario.binacchi@amarulasolutions.com \
--cc=festevam@denx.de \
--cc=miquel.raynal@bootlin.com \
--cc=sean.anderson@seco.com \
--cc=u-boot@lists.denx.de \
--cc=ye.li@nxp.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox