[Bugfix][API-584]update ubi problem for add patch3 and delete patch 1 2

Change-Id: I5283cd172ac72a80a6fa10d1d912137b4e2f8f7f
(cherry picked from commit 0f77d81a828e1020be3169ac03a1ca696dbb73cc)
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand/device_slc.c b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand/device_slc.c
old mode 100644
new mode 100755
index b663257..ecfa847
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand/device_slc.c
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nand/device_slc.c
@@ -303,7 +303,7 @@
                 &slc_endurance, &slc_array_timing),
         SLC_DRIVE_STRENGTH(0x80, 0x00, 0x01, 0x02, 0x03),
         &onfi_extend_cmds,
-        CHIP_TIMING_MODE3,
+        CHIP_TIMING_MODE2, //jb.qi change for ubi problem on 20221129
         &timing_mode[0],
 		sdr_timing_micron_slc //MT29GZ6A6BPIET-046AAT.112
 	//zhengzhou for 	"MT29F8G08ADBFA"
diff --git a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_base.c b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_base.c
old mode 100644
new mode 100755
index 5511d3d..cf7f19d
--- a/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_base.c
+++ b/src/bsp/lk/platform/mt2735/drivers/nandx/core/nfi/nfi_base.c
@@ -1418,6 +1418,7 @@
 	void *regs = nb->res.nfi_regs;
 	u32 tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt, tstrobe = 0;
 	u32 rate, val;
+	u16 thold; //jb.qi change for ubi problem on 20221129
 	int ret;
 
 	ret = wait_flash_macro_idle(regs);
@@ -1425,14 +1426,14 @@
 		return ret;
 
 	/* turn clock rate into KHZ */
-	rate = nb->res.clock_1x / 1000;
+	rate = div_down(nb->res.clock_1x, 1000); //jb.qi change for ubi problem on 20221129
 
 	tpoecs = max_t(u32, sdr->tALH, sdr->tCLH);
 	tpoecs = div_up(tpoecs * rate, 1000000);
 	tpoecs &= 0xf;
 
 	tprecs = max_t(u32, sdr->tCLS, sdr->tALS);
-	tprecs = div_up(tprecs * rate, 1000000);
+	tprecs = div_up(tprecs * rate, 1000000) + 1; //jb.qi change for ubi problem on 20221129
 	tprecs &= 0x3f;
 
 	/* tc2r is in unit of 2T */
@@ -1448,16 +1449,32 @@
 	twh = div_up(twh * rate, 1000000) - 1;
 	twh &= 0xf;
 
-	twst = div_up(sdr->tWP * rate, 1000000) - 1;
+	/*jb.qi change for ubi problem on 20221129 start*/
+	twst = 0;
+	thold = div_down((twh + 1) * 1000000, rate);
+	if (thold < sdr->tWC)
+        	twst = sdr->tWC - thold;
+	twst = max_t(u32, sdr->tWP, twst);
+	twst = div_up(twst * rate, 1000000) - 1;
+	/*jb.qi change for ubi problem on 20221129 end*/
 	twst &= 0xf;
 
-	trlt = div_up(sdr->tRP * rate, 1000000) - 1;
+	/*jb.qi change for ubi problem on 20221129 start*/
+	trlt = 0;
+	if (thold < sdr->tRC)
+	        trlt = sdr->tRC - thold;
+	trlt = max_t(u32, sdr->tRP, trlt);
+	trlt = div_up(trlt * rate, 1000000) - 1;
+	/*jb.qi change for ubi problem on 20221129 end*/
 	trlt &= 0xf;
 
+	tstrobe = 0; //jb.qi change for ubi problem on 20221129
 	/* If tREA is bigger than tRP, setup strobe sel here */
-	if ((trlt + 1) * 1000000 / rate < sdr->tREA) {
-		tstrobe = sdr->tREA - (trlt + 1) * 1000000 / rate;
-		tstrobe = div_up(tstrobe * rate, 1000000);
+	/*jb.qi change for ubi problem on 20221129 start*/
+	if (div_down((trlt + 1) * 1000000, rate) < sdr->tREA) {
+	        tstrobe = div_up(sdr->tREA * rate, 1000000);
+	        tstrobe -= trlt + 1;
+	/*jb.qi change for ubi problem on 20221129 end*/
 		val = readl(regs + NFI_DEBUG_CON1);
 		val &= ~STROBE_MASK;
 		val |= tstrobe << STROBE_SHIFT;
@@ -1478,7 +1495,7 @@
 	 * 03:00: trlt, read wait states
 	 */
 	val = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt);
-	pr_info("acctiming: 0x%x, tstrobe:%d\n", val, tstrobe);
+	pr_debug("NAND acctiming: 0x%x, strobe_sel:0x%x\n", val, tstrobe); //jb.qi change for ubi problem on 20221129
 	writel(val, regs + NFI_ACCCON);
 
 	/* set NAND type */
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand/device_slc.c b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand/device_slc.c
old mode 100644
new mode 100755
index 175e6cd..0963660
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand/device_slc.c
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand/device_slc.c
@@ -297,7 +297,7 @@
 				&slc_endurance, &slc_array_timing),
 		SLC_DRIVE_STRENGTH(0x80, 0x00, 0x01, 0x02, 0x03),
 		&onfi_extend_cmds,
-		CHIP_TIMING_MODE3,
+		CHIP_TIMING_MODE2, //jb.qi change for ubi problem on 20221129
 		&timing_mode[0],
 		sdr_timing_micron_slc //zhengzhou for MT29GZ6A6BPIET-046AAT.112 
 	},
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.c b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.c
old mode 100644
new mode 100755
index 702da05..81f8755
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.c
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.c
@@ -63,10 +63,6 @@
 		}
 		nand->performance->read_data_time = (int)time_cons;
 #endif
-		/*jb.qi change for ubi problem on 20221026 start*/
-		if (ops[i].status < 0)
-			pr_err("%s, row:0x%x, status: %d\n", __func__, row, ops[i].status);
-		/*jb.qi change for ubi problem on 20221026 end*/
 		ret_max = max_t(int, ret_max, ops[i].status);
 		ret_min = min_t(int, ret_min, ops[i].status);
 #if NANDX_PAGE_PERFORMANCE_TRACE
@@ -102,8 +98,6 @@
 		row = ops[i].row;
 		col = ops[i].col;
 
-		pr_err("%s, row:0x%x\n", __func__, row);//jb.qi change for ubi problem on 20221026 start
-
 		nand->addressing(nand, &row, &col);
 
 		ops[i].status = nand->write_enable(nand);
@@ -166,6 +160,107 @@
 	return ret;
 }
 
+/*jb.qi change for ubi problem on 20221129 start*/
+static inline void nand_bit_invert(u8 *buf, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		buf[i] = ~buf[i];
+}
+
+/**
+ * This function is called before erasing nand block, it wipes out EC
+ * and VID part nand page(s) in order to invalidate them and prevent the
+ * failures due to power loss during nand block erase operation.
+ * Since ec and vid info locate in separate nand page in non-subpage config
+ * proj, wipe out first two pages in non-subpage config project.
+ */
+static void nand_chip_erase_prepare(struct nand_chip *chip,
+				int row, int col)
+{
+	int nfi_ecc_en, nfi_ecc_en_old, ret, i;
+	int nfi_bbm_swap, nfi_bbm_swap_old;
+	int page_sectors = div_down(chip->page_size, chip->sector_size);
+	int sector_padded_size = chip->sector_size + chip->sector_spare_size;
+	int page_padded_size = page_sectors * sector_padded_size;
+	int count = 2;
+
+	struct nand_ops ops = {
+		.col = col,
+		.len = page_padded_size,
+		.data = chip->raw_buf,
+		.oob = NULL,
+	};
+
+	ret = nandx_ioctl(NFI_CTRL_ECC_GET_ECC_EN, &nfi_ecc_en_old);
+	if (ret) {
+		pr_err("%s:get ecc info fail at row %d, ret:%d\n",
+			__func__, row, ret);
+		return;
+	}
+
+	ret = nandx_ioctl(NFI_CTRL_BAD_MARK_SWAP_GET_SWAP_EN, &nfi_bbm_swap_old);
+	if (ret) {
+		pr_err("%s:get BBM swap status fail at row %d, ret:%d\n",
+			__func__, row, ret);
+		return;
+	}
+
+	/* To invert nand data, raw_read and raw_write operation are needed.
+	 * Disable NFI ECC
+	 */
+	nfi_ecc_en = 0;
+	ret = nandx_ioctl(NFI_CTRL_ECC, &nfi_ecc_en);
+	if (ret) {
+		pr_err("%s:disable ecc fail at row %d, ret:%d\n",
+			__func__, row, ret);
+		return;
+	}
+
+	nfi_bbm_swap = 0;
+	ret = nandx_ioctl(NFI_CTRL_BAD_MARK_SWAP, &nfi_bbm_swap);
+	if (ret) {
+		pr_err("%s:disable BBM swap at row %d, ret:%d\n",
+			__func__, row, ret);
+		goto restore_ecc;
+	}
+
+	for (i = 0; i < count; i++) {
+		ops.row = row + i;
+
+		memset(ops.data, 0xff, page_padded_size);
+		ret = chip->read_page(chip, &ops, 1);
+		if (ret < 0) {
+			pr_err("%s:raw read fail at row %d, ret:%d\n",
+				__func__, ops.row, ret);
+			break;
+		}
+
+		/* To avoid further 0 program causing difficulty to nand block
+		 * erase operation, invert the whole nand page.
+		 */
+		nand_bit_invert(ops.data, page_padded_size);
+
+		/* Ensure that nand block bad mark flag is not destroyed. */
+		*((u8 *)ops.data + chip->page_size) = 0xff;
+
+		/* Raw_write the inverted page data back to nand. */
+		ret = chip->write_page(chip, &ops, 1);
+		if (ret < 0) {
+			pr_err("%s:raw write fail at row %d, ret:%d\n",
+				__func__, ops.row, ret);
+			break;
+		}
+	}
+
+	nandx_ioctl(NFI_CTRL_BAD_MARK_SWAP, &nfi_bbm_swap_old);
+	/* Enable NFI ECC if need */
+restore_ecc:
+	nandx_ioctl(NFI_CTRL_ECC, &nfi_ecc_en_old);
+}
+/*jb.qi change for ubi problem on 20221129 end*/
+
 static int nand_chip_erase_block(struct nand_chip *chip,
 				 struct nand_ops *ops,
 				 int count)
@@ -181,8 +276,12 @@
 
 		nand->addressing(nand, &row, &col);
 
-		pr_err("%s, row:0x%x\n", __func__, row);//jb.qi change for ubi problem on 20221026 start
-
+		/*jb.qi change for ubi problem on 20221129 start*/
+		/* void type to avoid mis-judging this block as bad in ubi,
+		 * nand block erase operation can continue
+		 */
+		nand_chip_erase_prepare(chip, row, col);
+		/*jb.qi change for ubi problem on 20221129 end*/
 		ops[i].status = nand->write_enable(nand);
 		if (ops[i].status) {
 			pr_debug("Write Protect at %x!\n", row);
@@ -298,6 +397,11 @@
 	if (!nand)
 		goto nand_err;
 
+	chip->raw_buf = (u8 *)mem_alloc(1,
+		nand->dev->page_size + nand->dev->spare_size);
+	if (!chip->raw_buf)
+		goto nand_err;
+
 	chip->nand = (void *)nand;
 	chip->plane_num = nand->dev->plane_num;
 	chip->block_num = nand_total_blocks(nand->dev);
@@ -331,5 +435,6 @@
 		nand_spi_exit(chip->nand);
 	else
 		nand_exit(chip->nand);
+	mem_free(chip->raw_buf); //jb.qi change for ubi problem on 20221129
 	mem_free(chip);
 }
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.h b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.h
old mode 100644
new mode 100755
index 5295138..997fad0
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.h
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nand_chip.h
@@ -75,7 +75,7 @@
 	u32 fdm_reg_size;
 
 	void *nand;
-
+	u8 *raw_buf; //jb.qi add for ubi problem on 20221129
 	int (*read_page)(struct nand_chip *chip, struct nand_ops *ops,
 			 int count);
 	int (*write_page)(struct nand_chip *chip, struct nand_ops *ops,
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nfi/nfi_base.c b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nfi/nfi_base.c
old mode 100644
new mode 100755
index 1f57869..e6528f5
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nfi/nfi_base.c
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/core/nfi/nfi_base.c
@@ -558,7 +558,15 @@
 	case NFI_CTRL_BAD_MARK_SWAP:
 		nb->bad_mark_swap_en = *(bool *)args;
 		break;
+	/*jb.qi change for ubi problem on 20221129 start*/
+	case NFI_CTRL_BAD_MARK_SWAP_GET_SWAP_EN:
+		*(bool *)args = nb->bad_mark_swap_en;
+		break;
 
+	case NFI_CTRL_ECC_GET_ECC_EN:
+		*(bool *)args = nb->ecc_en;
+		break;
+	/*jb.qi change for ubi problem on 20221129 end*/
 #ifdef NANDX_TEST_BUF_ALIGN
 	case NFI_ADDR_ALIGNMENT_EN:
 		if (*(u8 *)args)
@@ -1335,6 +1343,7 @@
 	void *regs = nb->res.nfi_regs;
 	u32 tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt, tstrobe;
 	u32 rate, val;
+	u16 thold; //jb.qi change for ubi problem on 20221129
 	int ret;
 
 	ret = wait_flash_macro_idle(regs);
@@ -1344,14 +1353,13 @@
 	}
 
 	/* turn clock rate into KHZ */
-	rate = nb->res.clock_1x / 1000;
-
-	tpoecs = max(sdr->tALH, sdr->tCLH);
+	rate = div_down(nb->res.clock_1x, 1000);  //jb.qi change for ubi problem on 20221129
+	tpoecs = max(sdr->tALH, sdr->tCLH);    
 	tpoecs = div_up(tpoecs * rate, 1000000);
 	tpoecs &= 0xf;
 
 	tprecs = max(sdr->tCLS, sdr->tALS);
-	tprecs = div_up(tprecs * rate, 1000000);
+	tprecs = div_up(tprecs * rate, 1000000) + 1;  //jb.qi change for ubi problem on 20221129
 	tprecs &= 0x3f;
 
 	/* tc2r is in unit of 2T */
@@ -1367,16 +1375,32 @@
 	twh = div_up(twh * rate, 1000000) - 1;
 	twh &= 0xf;
 
-	twst = div_up(sdr->tWP * rate, 1000000) - 1;
+	/*jb.qi change for ubi problem on 20221129 start*/
+	twst = 0;
+	thold = div_down((twh + 1) * 1000000, rate);
+	if (thold < sdr->tWC)
+		twst = sdr->tWC - thold;
+	twst = max((u32)sdr->tWP, twst);
+	twst = div_up(twst * rate, 1000000) - 1;
+	/*jb.qi change for ubi problem on 20221129 end*/
 	twst &= 0xf;
 
-	trlt = div_up(sdr->tRP * rate, 1000000) - 1;
+	/*jb.qi change for ubi problem on 20221129 start*/
+	trlt = 0;
+	if (thold < sdr->tRC)
+		trlt = sdr->tRC - thold;
+	trlt = max((u32)sdr->tRP, trlt);
+	trlt = div_up(trlt * rate, 1000000) - 1;
+	/*jb.qi change for ubi problem on 20221129 end*/
 	trlt &= 0xf;
 
+	tstrobe = 0; //jb.qi change for ubi problem on 20221129
 	/* If tREA is bigger than tRP, setup strobe sel here */
-	if ((trlt + 1) * 1000000 / rate < sdr->tREA) {
-		tstrobe = sdr->tREA - (trlt + 1) * 1000000 / rate;
-		tstrobe = div_up(tstrobe * rate, 1000000);
+	/*jb.qi change for ubi problem on 20221129 start*/
+	if (div_down((trlt + 1) * 1000000, rate) < sdr->tREA) {
+		tstrobe = div_up(sdr->tREA * rate, 1000000);
+		tstrobe -= trlt + 1;
+	/*jb.qi change for ubi problem on 20221129 end*/
 		val = readl(regs + NFI_DEBUG_CON1);
 		val &= ~STROBE_MASK;
 		val |= tstrobe << STROBE_SHIFT;
@@ -1397,7 +1421,7 @@
 	 * 03:00: trlt, read wait states
 	 */
 	val = ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt);
-	pr_debug("acctiming: 0x%x\n", val);
+	pr_debug("NAND acctiming: 0x%x, strobe_sel:0x%x\n", val, tstrobe); //jb.qi change for ubi problem on 20221129
 	writel(val, regs + NFI_ACCCON);
 
 	/* set NAND type */
diff --git a/src/kernel/linux/v4.19/drivers/mtd/nandx/include/internal/nandx_core.h b/src/kernel/linux/v4.19/drivers/mtd/nandx/include/internal/nandx_core.h
old mode 100644
new mode 100755
index 384ac5c..61d1288
--- a/src/kernel/linux/v4.19/drivers/mtd/nandx/include/internal/nandx_core.h
+++ b/src/kernel/linux/v4.19/drivers/mtd/nandx/include/internal/nandx_core.h
@@ -67,8 +67,11 @@
 	NFI_CTRL_ECC_DECODE_MODE,
 	NFI_CTRL_ECC_ERRNUM0,
 	NFI_CTRL_ECC_GET_STATUS, /*20*/
+	NFI_CTRL_ECC_GET_ECC_EN, //jb.qi change for ubi problem on 20221129
+
 
 	NFI_CTRL_BAD_MARK_SWAP,
+	NFI_CTRL_BAD_MARK_SWAP_GET_SWAP_EN, //jb.qi change for ubi problem on 20221129
 	NFI_CTRL_IOCON,
 
 	SNFI_CTRL_OP_MODE,
diff --git a/src/kernel/linux/v4.19/fs/ubifs/lpt.c b/src/kernel/linux/v4.19/fs/ubifs/lpt.c
index 22ba82e..3139337 100644
--- a/src/kernel/linux/v4.19/fs/ubifs/lpt.c
+++ b/src/kernel/linux/v4.19/fs/ubifs/lpt.c
@@ -1334,11 +1334,6 @@
 	buf = vmalloc(c->ltab_sz);
 	if (!buf)
 		return -ENOMEM;
-	/*jb.qi change for ubi problem on 20221026 start*/
-	/* check the whole LEB */
-	ubifs_err(c, "check the LEB of ltab!\n");
-	ubifs_leb_read(c, c->ltab_lnum, c->sbuf, 0, c->leb_size, 1);
-	/*jb.qi change for ubi problem on 20221026 end*/
 	err = ubifs_leb_read(c, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz, 1);
 	if (err)
 		goto out;
diff --git a/src/kernel/linux/v4.19/fs/ubifs/recovery.c b/src/kernel/linux/v4.19/fs/ubifs/recovery.c
index 36107ee..abf4597 100644
--- a/src/kernel/linux/v4.19/fs/ubifs/recovery.c
+++ b/src/kernel/linux/v4.19/fs/ubifs/recovery.c
@@ -923,7 +923,7 @@
 static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
 {
 	int len = c->max_write_size, err;
-
+	bool forceclean = true; //jb.qi add for ubi problem on 20221129
 	if (offs + len > c->leb_size)
 		len = c->leb_size - offs;
 
@@ -932,8 +932,8 @@
 
 	/* Read at the head location and check it is empty flash */
 	err = ubifs_leb_read(c, lnum, sbuf, offs, len, 1);
-	if (err || !is_empty(sbuf, len)) {
-		ubifs_err(c, "cleaning head at %d:%d", lnum, offs); //jb.qi change for ubi problem on 20221026
+	if (err || !is_empty(sbuf, len) || forceclean) { //jb.qi add for ubi problem on 20221129
+		dbg_rcvry("cleaning head at %d:%d", lnum, offs);
 		if (offs == 0)
 			return ubifs_leb_unmap(c, lnum);
 		err = ubifs_leb_read(c, lnum, sbuf, 0, offs, 1);
@@ -968,12 +968,12 @@
 
 	ubifs_assert(c, !c->ro_mount || c->remounting_rw);
 
-	ubifs_err(c, "checking index head at %d:%d", c->ihead_lnum, c->ihead_offs);//jb.qi change for ubi problem on 20221026
+	dbg_rcvry("checking index head at %d:%d", c->ihead_lnum, c->ihead_offs);
 	err = recover_head(c, c->ihead_lnum, c->ihead_offs, sbuf);
 	if (err)
 		return err;
 
-	ubifs_err(c, "checking LPT head at %d:%d", c->nhead_lnum, c->nhead_offs);//jb.qi change for ubi problem on 20221026
+	dbg_rcvry("checking LPT head at %d:%d", c->nhead_lnum, c->nhead_offs);
 
 	return recover_head(c, c->nhead_lnum, c->nhead_offs, sbuf);
 }