All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] MXS nand fixes in SPL
@ 2022-04-23  8:11 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 ` [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping Michael Trimarchi
  0 siblings, 2 replies; 5+ messages in thread
From: Michael Trimarchi @ 2022-04-23  8:11 UTC (permalink / raw)
  To: Ye Li; +Cc: Miquel Raynal, u-boot, Fabio Estevam, Dario Binacchi, Sean Anderson

Those patches come after some testing of failing in factory on some
unit. We found out that the bootrom imx loader was not able to handling
badblock. This can be a limit of the implementation right now in imx8mn.
Anyway not all the imx platform has the support of this loader. I found
some problems on the implementation so I have fixed it up according the
experience of Sitara. I tested only using a Fit Image as a flash
container

Michael Trimarchi (2):
  nand: raw: mxs_nand: Fix specific hook registration
  mtd: nand: mxs_nand_spl: Fix bad block skipping

 drivers/mtd/nand/raw/mxs_nand.c     | 32 +++++-----
 drivers/mtd/nand/raw/mxs_nand_spl.c | 90 ++++++++++++++++-------------
 2 files changed, 65 insertions(+), 57 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] nand: raw: mxs_nand: Fix specific hook registration
  2022-04-23  8:11 [PATCH 0/2] MXS nand fixes in SPL Michael Trimarchi
@ 2022-04-23  8:11 ` Michael Trimarchi
  2022-04-23  8:11 ` [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping Michael Trimarchi
  1 sibling, 0 replies; 5+ messages in thread
From: Michael Trimarchi @ 2022-04-23  8:11 UTC (permalink / raw)
  To: Ye Li; +Cc: Miquel Raynal, u-boot, Fabio Estevam, Dario Binacchi, Sean Anderson

Move the hook after nand_scan_tail is called. The hook must be replaced
to the mxs specific one but those must to be assignment later in the
probe function.

With this fix markbad is working

Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
---
 drivers/mtd/nand/raw/mxs_nand.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c
index ee5d7fde9c..53f24b9c4b 100644
--- a/drivers/mtd/nand/raw/mxs_nand.c
+++ b/drivers/mtd/nand/raw/mxs_nand.c
@@ -1246,22 +1246,6 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd)
 	/* Enable BCH complete interrupt */
 	writel(BCH_CTRL_COMPLETE_IRQ_EN, &bch_regs->hw_bch_ctrl_set);
 
-	/* Hook some operations at the MTD level. */
-	if (mtd->_read_oob != mxs_nand_hook_read_oob) {
-		nand_info->hooked_read_oob = mtd->_read_oob;
-		mtd->_read_oob = mxs_nand_hook_read_oob;
-	}
-
-	if (mtd->_write_oob != mxs_nand_hook_write_oob) {
-		nand_info->hooked_write_oob = mtd->_write_oob;
-		mtd->_write_oob = mxs_nand_hook_write_oob;
-	}
-
-	if (mtd->_block_markbad != mxs_nand_hook_block_markbad) {
-		nand_info->hooked_block_markbad = mtd->_block_markbad;
-		mtd->_block_markbad = mxs_nand_hook_block_markbad;
-	}
-
 	return 0;
 }
 
@@ -1467,6 +1451,22 @@ int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info)
 	if (err)
 		goto err_free_buffers;
 
+	/* Hook some operations at the MTD level. */
+	if (mtd->_read_oob != mxs_nand_hook_read_oob) {
+		nand_info->hooked_read_oob = mtd->_read_oob;
+		mtd->_read_oob = mxs_nand_hook_read_oob;
+	}
+
+	if (mtd->_write_oob != mxs_nand_hook_write_oob) {
+		nand_info->hooked_write_oob = mtd->_write_oob;
+		mtd->_write_oob = mxs_nand_hook_write_oob;
+	}
+
+	if (mtd->_block_markbad != mxs_nand_hook_block_markbad) {
+		nand_info->hooked_block_markbad = mtd->_block_markbad;
+		mtd->_block_markbad = mxs_nand_hook_block_markbad;
+	}
+
 	err = nand_register(0, mtd);
 	if (err)
 		goto err_free_buffers;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping
  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
  2022-04-25 11:45   ` Michael Nazzareno Trimarchi
  1 sibling, 1 reply; 5+ messages in thread
From: Michael Trimarchi @ 2022-04-23  8:11 UTC (permalink / raw)
  To: Ye Li; +Cc: Miquel Raynal, u-boot, Fabio Estevam, Dario Binacchi, Sean Anderson

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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping
  2022-04-23  8:11 ` [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping Michael Trimarchi
@ 2022-04-25 11:45   ` Michael Nazzareno Trimarchi
  2022-04-26 12:48     ` Fabio Estevam
  0 siblings, 1 reply; 5+ messages in thread
From: Michael Nazzareno Trimarchi @ 2022-04-25 11:45 UTC (permalink / raw)
  To: Ye Li, Stefano Babic
  Cc: Miquel Raynal, u-boot, Fabio Estevam, Dario Binacchi, Sean Anderson

Hi

+cc Stefano Babic

We have right now a while (1) if we find a badblock

On Sat, Apr 23, 2022 at 10:12 AM Michael Trimarchi
<michael@amarulasolutions.com> wrote:
>
> 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
>


-- 
Michael Nazzareno Trimarchi
Co-Founder & Chief Executive Officer
M. +39 347 913 2170
michael@amarulasolutions.com
__________________________________

Amarula Solutions BV
Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
T. +31 (0)85 111 9172
info@amarulasolutions.com
www.amarulasolutions.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping
  2022-04-25 11:45   ` Michael Nazzareno Trimarchi
@ 2022-04-26 12:48     ` Fabio Estevam
  0 siblings, 0 replies; 5+ messages in thread
From: Fabio Estevam @ 2022-04-26 12:48 UTC (permalink / raw)
  To: Michael Nazzareno Trimarchi, Han Xu
  Cc: Ye Li, Stefano Babic, Miquel Raynal, U-Boot-Denx, Fabio Estevam,
	Dario Binacchi, Sean Anderson

Adding Han Xu.

On Mon, Apr 25, 2022 at 8:45 AM Michael Nazzareno Trimarchi
<michael@amarulasolutions.com> wrote:
>
> Hi
>
> +cc Stefano Babic
>
> We have right now a while (1) if we find a badblock
>
> On Sat, Apr 23, 2022 at 10:12 AM Michael Trimarchi
> <michael@amarulasolutions.com> wrote:
> >
> > 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
> >
>
>
> --
> Michael Nazzareno Trimarchi
> Co-Founder & Chief Executive Officer
> M. +39 347 913 2170
> michael@amarulasolutions.com
> __________________________________
>
> Amarula Solutions BV
> Joop Geesinkweg 125, 1114 AB, Amsterdam, NL
> T. +31 (0)85 111 9172
> info@amarulasolutions.com
> www.amarulasolutions.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-04-26 12:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 2/2] mtd: nand: mxs_nand_spl: Fix bad block skipping Michael Trimarchi
2022-04-25 11:45   ` Michael Nazzareno Trimarchi
2022-04-26 12:48     ` Fabio Estevam

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.