
-----Original Message----- From: Michael Nazzareno Trimarchi michael@amarulasolutions.com Sent: Friday, 13 December 2024 2:38 am To: Maniyam, Dinesh dinesh.maniyam@intel.com Cc: u-boot@lists.denx.de; Marek marex@denx.de; Simon simon.k.r.goldschmidt@gmail.com; Tom Rini trini@konsulko.com; Dario Binacchi dario.binacchi@amarulasolutions.com; Johan Jonker jbx6244@gmail.com; Michal Simek michal.simek@amd.com; Arseniy Krasnov avkrasnov@salutedevices.com; Alexander Dahl ada@thorsis.com; William Zhang william.zhang@broadcom.com; Igor Prusov ivprusov@salutedevices.com; Meng, Tingting tingting.meng@intel.com; Chee, Tien Fong tien.fong.chee@intel.com; Hea, Kok Kiang kok.kiang.hea@intel.com; Ng, Boon Khai boon.khai.ng@intel.com; Yuslaimi, Alif Zakuan alif.zakuan.yuslaimi@intel.com; Zamri, Muhammad Hazim Izzat muhammad.hazim.izzat.zamri@intel.com; Lim, Jit Loon jit.loon.lim@intel.com; Tang, Sieu Mun sieu.mun.tang@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@intel.com wrote:
From: Dinesh Maniyam dinesh.maniyam@intel.com
Leverage linux code to support hardware ECC interface to verify nand bad block.
Signed-off-by: Dinesh Maniyam dinesh.maniyam@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@realitydiluted.com)
2002-2006 Thomas Gleixner (tglx@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@realitydiluted.com>
Thomas Gleixner <tglx@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@amarulasolutions.com
-- 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
Thanks for reviewing my patch.