From bc308f8d1d90b4d0750fe53a8af3b6d33a10537b Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Thu, 6 Nov 2025 13:57:15 +0100 Subject: [PATCH] fix(nand): add read parameter page retry SLC NAND embeds 3 parameter pages. In case CRC check fails on the first parameter page, we try to read the redundant pages. Change-Id: I055afecf0d28e78976c49614e957fa07821ac21f Signed-off-by: Christophe Kerello --- drivers/mtd/nand/raw_nand.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c index 3595c2142..e3581a4de 100644 --- a/drivers/mtd/nand/raw_nand.c +++ b/drivers/mtd/nand/raw_nand.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2022, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2026, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -282,6 +282,7 @@ static int nand_read_param_page(void) struct nand_param_page page; uint8_t addr = 0U; int ret; + int i; ret = nand_send_cmd(NAND_CMD_READ_PARAM_PAGE, 0U); if (ret != 0) { @@ -298,9 +299,20 @@ static int nand_read_param_page(void) return ret; } - ret = nand_read_data((uint8_t *)&page, sizeof(page), true); - if (ret != 0) { - return ret; + for (i = 0; i < 3; i++) { + ret = nand_read_data((uint8_t *)&page, sizeof(page), true); + if (ret != 0) { + return ret; + } + + if (nand_check_crc(CRC_INIT_VALUE, (uint8_t *)&page, 254U) == page.crc16) { + break; + } + } + + if (i == 3) { + WARN("Error reading param\n"); + return -EINVAL; } if (strncmp((char *)&page.page_sig, "ONFI", 4) != 0) { @@ -308,12 +320,6 @@ static int nand_read_param_page(void) return -EINVAL; } - if (nand_check_crc(CRC_INIT_VALUE, (uint8_t *)&page, 254U) != - page.crc16) { - WARN("Error reading param\n"); - return -EINVAL; - } - if ((page.features & ONFI_FEAT_BUS_WIDTH_16) != 0U) { rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_16; } else {