All of lore.kernel.org
 help / color / mirror / Atom feed
From: Igor Opaniuk <igor.opaniuk@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 4/5] imx: nandbcb: refactor update function
Date: Mon, 21 Oct 2019 16:38:58 +0300	[thread overview]
Message-ID: <20191021133859.23824-5-igor.opaniuk@gmail.com> (raw)
In-Reply-To: <20191021133859.23824-1-igor.opaniuk@gmail.com>

From: Igor Opaniuk <igor.opaniuk@toradex.com>

Move code for writing FCB/DBBT pages to a separate function

Signed-off-by: Igor Opaniuk <igor.opaniuk@toradex.com>
---

 arch/arm/mach-imx/cmd_nandbcb.c | 221 ++++++++++++++++++--------------
 1 file changed, 122 insertions(+), 99 deletions(-)

diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c
index aae2cc82f3..fbe780ccda 100644
--- a/arch/arm/mach-imx/cmd_nandbcb.c
+++ b/arch/arm/mach-imx/cmd_nandbcb.c
@@ -64,7 +64,8 @@ static u32 calc_chksum(void *buf, size_t size)
 	return ~chksum;
 }
 
-static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd)
+static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd,
+		     u32 fw1_start, u32 fw2_start, u32 fw_pages)
 {
 	struct nand_chip *chip = mtd_to_nand(mtd);
 	struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
@@ -112,6 +113,11 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd)
 	fcb->disbbm = 0;
 	fcb->disbbm_search = 0;
 
+	fcb->fw1_start = fw1_start; /* Firmware image starts on this sector */
+	fcb->fw2_start = fw2_start; /* Secondary FW Image starting Sector */
+	fcb->fw1_pages = fw_pages; /* Number of sectors in firmware image */
+	fcb->fw2_pages = fw_pages; /* Number of sector in secondary FW image */
+
 	fcb->checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4);
 }
 
@@ -135,6 +141,109 @@ static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks)
 	return n_bad_blocks;
 }
 
+static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb,
+			  struct dbbt_block *dbbt, void *dbbt_data_page,
+			  loff_t off)
+{
+	void *fcb_raw_page = 0;
+	int i, ret;
+	size_t dummy;
+
+	/*
+	 * We prepare raw page only for i.MX6, for i.MX7 we
+	 * leverage BCH hw module instead
+	 */
+	if (is_mx6()) {
+		/* write fcb/dbbt */
+		fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize,
+				       GFP_KERNEL);
+		if (!fcb_raw_page) {
+			debug("failed to allocate fcb_raw_page\n");
+			ret = -ENOMEM;
+			return ret;
+		}
+
+		memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block));
+		encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page +
+				    12 + 512, 512);
+		/*
+		 * Set the first and second byte of OOB data to 0xFF,
+		 * not 0x00. These bytes are used as the Manufacturers Bad
+		 * Block Marker (MBBM). Since the FCB is mostly written to
+		 * the first page in a block, a scan for
+		 * factory bad blocks will detect these blocks as bad, e.g.
+		 * when function nand_scan_bbt() is executed to build a new
+		 * bad block table.
+		 */
+		memset(fcb_raw_page + mtd->writesize, 0xFF, 2);
+	}
+	for (i = 0; i < 2; i++) {
+		if (mtd_block_isbad(mtd, off)) {
+			printf("Block %d is bad, skipped\n", i);
+			continue;
+		}
+
+		/*
+		 * User BCH ECC hardware module for i.MX7
+		 */
+		if (is_mx7()) {
+			u32 off = i * mtd->erasesize;
+			size_t rwsize = sizeof(*fcb);
+
+			printf("Writing %d bytes to 0x%x: ", rwsize, off);
+
+			/* switch nand BCH to FCB compatible settings */
+			mxs_nand_mode_fcb(mtd);
+			ret = nand_write(mtd, off, &rwsize,
+					 (unsigned char *)fcb);
+			mxs_nand_mode_normal(mtd);
+
+			printf("%s\n", ret ? "ERROR" : "OK");
+		} else if (is_mx6()) {
+			/* raw write */
+			mtd_oob_ops_t ops = {
+				.datbuf = (u8 *)fcb_raw_page,
+				.oobbuf = ((u8 *)fcb_raw_page) +
+					  mtd->writesize,
+				.len = mtd->writesize,
+				.ooblen = mtd->oobsize,
+				.mode = MTD_OPS_RAW
+			};
+
+			ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops);
+			if (ret)
+				goto fcb_raw_page_err;
+			debug("NAND fcb write: 0x%x offset 0x%x written: %s\n",
+			      mtd->erasesize * i, ops.len, ret ?
+			      "ERROR" : "OK");
+		}
+
+		ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize,
+				mtd->writesize, &dummy, (void *)dbbt);
+		if (ret)
+			goto fcb_raw_page_err;
+		debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n",
+		      mtd->erasesize * i + mtd->writesize, dummy,
+		      ret ? "ERROR" : "OK");
+
+		/* dbbtpages == 0 if no bad blocks */
+		if (dbbt->dbbtpages > 0) {
+			loff_t to = (mtd->erasesize * i + mtd->writesize * 5);
+
+			ret = mtd_write(mtd, to, mtd->writesize, &dummy,
+					dbbt_data_page);
+			if (ret)
+				goto fcb_raw_page_err;
+		}
+	}
+
+fcb_raw_page_err:
+	if (is_mx6())
+		kfree(fcb_raw_page);
+
+	return ret;
+}
+
 static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
 			  size_t maxsize, const u_char *buf)
 {
@@ -142,12 +251,12 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
 	struct fcb_block *fcb;
 	struct dbbt_block *dbbt;
 	loff_t fw1_off;
-	void *fwbuf, *fcb_raw_page, *dbbt_page, *dbbt_data_page;
+	void *fwbuf, *dbbt_page, *dbbt_data_page;
+	u32 fw1_start, fw1_pages;
 	int nr_blks, nr_blks_fcb, fw1_blk;
-	size_t fwsize, dummy;
-	int i, ret;
+	size_t fwsize;
+	int ret;
 
-	fcb_raw_page = 0;
 	/* erase */
 	memset(&opts, 0, sizeof(opts));
 	opts.offset = off;
@@ -209,9 +318,9 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
 		goto fwbuf_err;
 	}
 
-	fcb->fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize;
-	fcb->fw1_pages = size / mtd->writesize + 1;
-	fill_fcb(fcb, mtd);
+	fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize;
+	fw1_pages = size / mtd->writesize + 1;
+	fill_fcb(fcb, mtd, fw1_start, 0, fw1_pages);
 
 	/* fill dbbt */
 	dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL);
@@ -238,97 +347,11 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size,
 	else if (ret > 0)
 		dbbt->dbbtpages = 1;
 
-	/*
-	 * We prepare raw page only for i.MX6, for i.MX7 we
-	 * leverage BCH hw module instead
-	 */
-	if (is_mx6()) {
-		/* write fcb/dbbt */
-		fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize,
-				       GFP_KERNEL);
-		if (!fcb_raw_page) {
-			debug("failed to allocate fcb_raw_page\n");
-			ret = -ENOMEM;
-			goto dbbt_data_page_err;
-		}
-
-		memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block));
-		encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page +
-				    12 + 512, 512);
-		/*
-		 * Set the first and second byte of OOB data to 0xFF,
-		 * not 0x00. These bytes are used as the Manufacturers Bad
-		 * Block Marker (MBBM). Since the FCB is mostly written to
-		 * the first page in a block, a scan for
-		 * factory bad blocks will detect these blocks as bad, e.g.
-		 * when function nand_scan_bbt() is executed to build a new
-		 * bad block table.
-		 */
-		memset(fcb_raw_page + mtd->writesize, 0xFF, 2);
-	}
-	for (i = 0; i < nr_blks_fcb; i++) {
-		if (mtd_block_isbad(mtd, off)) {
-			printf("Block %d is bad, skipped\n", i);
-			continue;
-		}
-
-		/*
-		 * User BCH ECC hardware module for i.MX7
-		 */
-		if (is_mx7()) {
-			u32 off = i * mtd->erasesize;
-			size_t rwsize = sizeof(*fcb);
-
-			printf("Writing %d bytes to 0x%x: ", rwsize, off);
-
-			/* switch nand BCH to FCB compatible settings */
-			mxs_nand_mode_fcb(mtd);
-			ret = nand_write(mtd, off, &rwsize,
-					 (unsigned char *)fcb);
-			mxs_nand_mode_normal(mtd);
-
-			printf("%s\n", ret ? "ERROR" : "OK");
-		} else if (is_mx6()) {
-			/* raw write */
-			mtd_oob_ops_t ops = {
-				.datbuf = (u8 *)fcb_raw_page,
-				.oobbuf = ((u8 *)fcb_raw_page) +
-					  mtd->writesize,
-				.len = mtd->writesize,
-				.ooblen = mtd->oobsize,
-				.mode = MTD_OPS_RAW
-			};
-
-			ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops);
-			if (ret)
-				goto fcb_raw_page_err;
-			debug("NAND fcb write: 0x%x offset 0x%x written: %s\n",
-			      mtd->erasesize * i, ops.len, ret ?
-			      "ERROR" : "OK");
-		}
-
-		ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize,
-				mtd->writesize, &dummy, dbbt_page);
-		if (ret)
-			goto fcb_raw_page_err;
-		debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n",
-		      mtd->erasesize * i + mtd->writesize, dummy,
-		      ret ? "ERROR" : "OK");
-
-		/* dbbtpages == 0 if no bad blocks */
-		if (dbbt->dbbtpages > 0) {
-			loff_t to = (mtd->erasesize * i + mtd->writesize * 5);
-
-			ret = mtd_write(mtd, to, mtd->writesize, &dummy,
-					dbbt_data_page);
-			if (ret)
-				goto fcb_raw_page_err;
-		}
-	}
+	/* write fcb and dbbt to nand */
+	ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, off);
+	if (ret < 0)
+		printf("failed to write FCB/DBBT\n");
 
-fcb_raw_page_err:
-	if (is_mx6())
-		kfree(fcb_raw_page);
 dbbt_data_page_err:
 	kfree(dbbt_data_page);
 dbbt_page_err:
@@ -355,7 +378,7 @@ static int do_nandbcb_update(int argc, char * const argv[])
 
 	dev = nand_curr_device;
 	if (dev < 0) {
-		printf("failed to get nand_curr_device, run nand device");
+		printf("failed to get nand_curr_device, run nand device\n");
 		return CMD_RET_FAILURE;
 	}
 
-- 
2.17.1

  parent reply	other threads:[~2019-10-21 13:38 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-21 13:38 [U-Boot] [PATCH v2 0/5] imx: nandbcb: support for i.MX7 and bcb only updates Igor Opaniuk
2019-10-21 13:38 ` [U-Boot] [PATCH v2 1/5] imx: gpmi: add defines for hw randominizer Igor Opaniuk
2019-10-23 11:21   ` Oleksandr Suvorov
2019-10-23 17:51   ` Max Krummenacher
2019-10-21 13:38 ` [U-Boot] [PATCH v2 2/5] nand: mxs_nand: add API for switching different BCH layouts Igor Opaniuk
2019-10-23 11:23   ` Oleksandr Suvorov
2019-10-23 17:53   ` Max Krummenacher
2019-10-21 13:38 ` [U-Boot] [PATCH v2 3/5] imx: nandbcb: add support for i.MX7 Igor Opaniuk
2019-10-23 11:24   ` Oleksandr Suvorov
2019-10-23 18:30   ` Max Krummenacher
2019-11-03 13:55   ` Stefano Babic
2019-11-03 15:51     ` Igor Opaniuk
2019-10-21 13:38 ` Igor Opaniuk [this message]
2019-10-23 11:26   ` [U-Boot] [PATCH v2 4/5] imx: nandbcb: refactor update function Oleksandr Suvorov
2019-10-23 18:31   ` Max Krummenacher
2019-10-21 13:38 ` [U-Boot] [PATCH v2 5/5] imx: nandbcb: add support for writing BCB only Igor Opaniuk
2019-10-23 11:28   ` Oleksandr Suvorov
2019-10-23 18:32   ` Max Krummenacher

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191021133859.23824-5-igor.opaniuk@gmail.com \
    --to=igor.opaniuk@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.