[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);
}