[resend v2 15/19] drivers: mtd: nand: base: Add support for Hardware ECC for check bad block

Maniyam, Dinesh dinesh.maniyam at intel.com
Fri Dec 13 04:28:13 CET 2024



> -----Original Message-----
> From: Michael Nazzareno Trimarchi <michael at amarulasolutions.com>
> Sent: Friday, 13 December 2024 2:38 am
> To: Maniyam, Dinesh <dinesh.maniyam at intel.com>
> Cc: u-boot at lists.denx.de; Marek <marex at denx.de>; Simon
> <simon.k.r.goldschmidt at gmail.com>; Tom Rini <trini at konsulko.com>; Dario
> Binacchi <dario.binacchi at amarulasolutions.com>; Johan Jonker
> <jbx6244 at gmail.com>; Michal Simek <michal.simek at amd.com>; Arseniy
> Krasnov <avkrasnov at salutedevices.com>; Alexander Dahl <ada at thorsis.com>;
> William Zhang <william.zhang at broadcom.com>; Igor Prusov
> <ivprusov at salutedevices.com>; Meng, Tingting <tingting.meng at intel.com>;
> Chee, Tien Fong <tien.fong.chee at intel.com>; Hea, Kok Kiang
> <kok.kiang.hea at intel.com>; Ng, Boon Khai <boon.khai.ng at intel.com>; Yuslaimi,
> Alif Zakuan <alif.zakuan.yuslaimi at intel.com>; Zamri, Muhammad Hazim Izzat
> <muhammad.hazim.izzat.zamri at intel.com>; Lim, Jit Loon
> <jit.loon.lim at intel.com>; Tang, Sieu Mun <sieu.mun.tang at intel.com>
> Subject: Re: [resend v2 15/19] drivers: mtd: nand: base: Add support for
> Hardware ECC for check bad block
> 
> Hi
> 
> On Thu, Dec 5, 2024 at 10:24 AM <dinesh.maniyam at intel.com> wrote:
> >
> > From: Dinesh Maniyam <dinesh.maniyam at intel.com>
> >
> > Leverage linux code to support hardware ECC interface to verify nand
> > bad block.
> >
> > Signed-off-by: Dinesh Maniyam <dinesh.maniyam at intel.com>
> >
> > ---
> > v2:
> > - remove the "this patch is to" commit phrases
> > ---
> > ---
> >  drivers/mtd/nand/raw/nand_base.c | 71 +++++++++++++++++++++-----------
> >  include/linux/mtd/rawnand.h      | 13 ++++++
> >  2 files changed, 60 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/mtd/nand/raw/nand_base.c
> > b/drivers/mtd/nand/raw/nand_base.c
> > index 4401bdcdb9..9b1b2d1f85 100644
> > --- a/drivers/mtd/nand/raw/nand_base.c
> > +++ b/drivers/mtd/nand/raw/nand_base.c
> > @@ -9,6 +9,8 @@
> >   *  Copyright (C) 2000 Steven J. Hill (sjhill at realitydiluted.com)
> >   *               2002-2006 Thomas Gleixner (tglx at linutronix.de)
> >   *
> > + *  Copyright (C) 2024 Intel Corporation <www.intel.com>
> > + *
> 
> Drop it. I don't think that because you add a function here, you can add any
> copyright

Noted, will drop this.
> 
> >   *  Credits:
> >   *     David Woodhouse for adding multichip support
> >   *
> > @@ -306,6 +308,35 @@ void nand_read_buf16(struct mtd_info *mtd, uint8_t
> *buf, int len)
> >         ioread16_rep(chip->IO_ADDR_R, p, len >> 1);  }
> >
> > +/*
> > + * nand_bbm_get_next_page - Get the next page for bad block markers
> > + * @chip: The NAND chip
> > + * @page: First page to start checking for bad block marker usage
> > + *
> > + * Returns an integer that corresponds to the page offset within a
> > +block, for
> > + * a page that is used to store bad block markers. If no more pages
> > +are
> > + * available, -EINVAL is returned.
> > + */
> > +int nand_bbm_get_next_page(struct nand_chip *chip, int page) {
> > +       struct mtd_info *mtd = nand_to_mtd(chip);
> > +       int last_page = ((mtd->erasesize - mtd->writesize) >>
> > +                        chip->page_shift) & chip->pagemask;
> > +       unsigned int bbm_flags = NAND_BBM_FIRSTPAGE |
> NAND_BBM_SECONDPAGE
> > +               | NAND_BBM_LASTPAGE;
> > +
> > +       if (page == 0 && !(chip->options & bbm_flags))
> > +               return 0;
> > +       if (page == 0 && chip->options & NAND_BBM_FIRSTPAGE)
> > +               return 0;
> > +       if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE)
> > +               return 1;
> > +       if (page <= last_page && chip->options & NAND_BBM_LASTPAGE)
> > +               return last_page;
> > +
> > +       return -EINVAL;
> > +}
> > +
> >  /**
> >   * nand_block_bad - [DEFAULT] Read bad block marker from the chip
> >   * @mtd: MTD device structure
> > @@ -315,40 +346,32 @@ void nand_read_buf16(struct mtd_info *mtd, uint8_t
> *buf, int len)
> >   */
> >  static int nand_block_bad(struct mtd_info *mtd, loff_t ofs)  {
> > -       int page, res = 0, i = 0;
> >         struct nand_chip *chip = mtd_to_nand(mtd);
> > -       u16 bad;
> > +       int first_page, page_offset;
> > +       int res;
> > +       u8 bad;
> >
> > -       if (chip->bbt_options & NAND_BBT_SCANLASTPAGE)
> > -               ofs += mtd->erasesize - mtd->writesize;
> > +       first_page = (int)(ofs >> chip->page_shift) & chip->pagemask;
> > +       page_offset = nand_bbm_get_next_page(chip, 0);
> >
> > -       page = (int)(ofs >> chip->page_shift) & chip->pagemask;
> > +       while (page_offset >= 0) {
> > +               res = chip->ecc.read_oob(mtd, chip, first_page + page_offset);
> > +               if (res < 0)
> > +                       return res;
> >
> > -       do {
> > -               if (chip->options & NAND_BUSWIDTH_16) {
> > -                       chip->cmdfunc(mtd, NAND_CMD_READOOB,
> > -                                       chip->badblockpos & 0xFE, page);
> > -                       bad = cpu_to_le16(chip->read_word(mtd));
> > -                       if (chip->badblockpos & 0x1)
> > -                               bad >>= 8;
> > -                       else
> > -                               bad &= 0xFF;
> > -               } else {
> > -                       chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos,
> > -                                       page);
> > -                       bad = chip->read_byte(mtd);
> > -               }
> > +               bad = chip->oob_poi[chip->badblockpos];
> >
> >                 if (likely(chip->badblockbits == 8))
> >                         res = bad != 0xFF;
> >                 else
> >                         res = hweight8(bad) < chip->badblockbits;
> > -               ofs += mtd->writesize;
> > -               page = (int)(ofs >> chip->page_shift) & chip->pagemask;
> > -               i++;
> > -       } while (!res && i < 2 && (chip->bbt_options &
> NAND_BBT_SCAN2NDPAGE));
> > +               if (res)
> > +                       return res;
> >
> > -       return res;
> > +               page_offset = nand_bbm_get_next_page(chip, page_offset + 1);
> > +       }
> > +
> > +       return 0;
> >  }
> >
> >  /**
> > diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
> > index 14f93dab0a..35eb3b5678 100644
> > --- a/include/linux/mtd/rawnand.h
> > +++ b/include/linux/mtd/rawnand.h
> > @@ -4,6 +4,8 @@
> >   *                        Steven J. Hill <sjhill at realitydiluted.com>
> >   *                       Thomas Gleixner <tglx at linutronix.de>
> >   *
> > + *  Copyright (C) 2024 Intel Corporation <www.intel.com>
> > + *
> 
> Drop here

Noted, will drop the copyright.
> 
> >   * Info:
> >   *     Contains standard defines and IDs for NAND flash devices
> >   *
> > @@ -131,6 +133,17 @@ void nand_wait_ready(struct mtd_info *mtd);
> >
> >  #define NAND_DATA_IFACE_CHECK_ONLY     -1
> >
> > +/*
> > + * There are different places where the manufacturer stores the
> > +factory bad
> > + * block markers.
> > + *
> > + * Position within the block: Each of these pages needs to be checked
> > +for a
> > + * bad block marking pattern.
> > + */
> > +#define NAND_BBM_FIRSTPAGE     BIT(24)
> > +#define NAND_BBM_SECONDPAGE    BIT(25)
> > +#define NAND_BBM_LASTPAGE      BIT(26)
> > +
> >  /*
> >   * Constants for ECC_MODES
> >   */
> > --
> > 2.19.0
> >
> Reviewed-by: Michael Trimarchi <michael at amarulasolutions.com>
> 
> --
> Michael Nazzareno Trimarchi
> Co-Founder & Chief Executive Officer
> M. +39 347 913 2170
> michael at amarulasolutions.com
> __________________________________
> 
> Amarula Solutions BV
> Joop Geesinkweg 125, 1114 AB, Amsterdam, NL T. +31 (0)85 111 9172
> info at amarulasolutions.com www.amarulasolutions.com

Thanks for reviewing my patch.


More information about the U-Boot mailing list