During system startup, U-Boot overwrites the Bad Block Table (BBT) on NAND
flash
every time because it fails to properly read the existing BBT. This happens
due
to missing OOB (Out-Of-Band) reads when checking for the BBT signature.

As a result, U-Boot assumes the BBT is invalid or missing and rewrites it on
every boot, causing unnecessary NAND wear and slower startup.

This patch corrects the issue by enabling proper reading of the BBT from the
OOB area, preventing redundant writes.

Signed-off-by: Rafal Vonau <rafal.vo...@gmail.com>
---
drivers/mtd/nand/raw/zynq_nand.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/drivers/mtd/nand/raw/zynq_nand.c
b/drivers/mtd/nand/raw/zynq_nand.c
index ca1aff25a52..3adacb1b46c 100644
--- a/drivers/mtd/nand/raw/zynq_nand.c
+++ b/drivers/mtd/nand/raw/zynq_nand.c
@@ -522,6 +522,20 @@ static int zynq_nand_read_page_raw_nooob(struct
mtd_info *mtd,
               struct nand_chip *chip, u8 *buf, int oob_required, int page)
{
       chip->read_buf(mtd, buf, mtd->writesize);
+
+       if (oob_required) {
+               unsigned long data_width = 4;
+               unsigned long data_phase_addr = 0;
+               u8 *p = chip->oob_poi;
+               chip->read_buf(mtd, p, (mtd->oobsize - data_width));
+               p += (mtd->oobsize - data_width);
+
+               data_phase_addr = (unsigned long)chip->IO_ADDR_R;
+               data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
+               chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
+               chip->read_buf(mtd, p, data_width);
+       }
+
       return 0;
}

--
2.20.1
From 0b11bfbc2a53a13cb86e85ef3d6d04f4e06e4708 Mon Sep 17 00:00:00 2001
From: Rafal Vonau <rafal.vonau@elfin-pe.pl>
Date: Mon, 30 Jun 2025 10:22:00 +0200
Subject: [PATCH] fix: Fix for the write of the BBT table to the NAND at system
 startup

Signed-off-by: Rafal Vonau <rafal.vonau@elfin-pe.pl>
---
 drivers/mtd/nand/raw/zynq_nand.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mtd/nand/raw/zynq_nand.c b/drivers/mtd/nand/raw/zynq_nand.c
index ca1aff25a52..3adacb1b46c 100644
--- a/drivers/mtd/nand/raw/zynq_nand.c
+++ b/drivers/mtd/nand/raw/zynq_nand.c
@@ -522,6 +522,20 @@ static int zynq_nand_read_page_raw_nooob(struct mtd_info *mtd,
 		struct nand_chip *chip, u8 *buf, int oob_required, int page)
 {
 	chip->read_buf(mtd, buf, mtd->writesize);
+
+	if (oob_required) {
+		unsigned long data_width = 4;
+		unsigned long data_phase_addr = 0;
+		u8 *p = chip->oob_poi;
+		chip->read_buf(mtd, p, (mtd->oobsize - data_width));
+		p += (mtd->oobsize - data_width);
+
+		data_phase_addr = (unsigned long)chip->IO_ADDR_R;
+		data_phase_addr |= ZYNQ_NAND_CLEAR_CS;
+		chip->IO_ADDR_R = (void __iomem *)data_phase_addr;
+		chip->read_buf(mtd, p, data_width);
+	}
+
 	return 0;
 }
 
-- 
2.20.1

Reply via email to