ramips: clean up and fix MT7621 NAND driver issues
authorFelix Fietkau <nbd@nbd.name>
Wed, 11 Jul 2018 18:56:42 +0000 (20:56 +0200)
committerFelix Fietkau <nbd@nbd.name>
Fri, 13 Jul 2018 15:01:41 +0000 (17:01 +0200)
- remove misaligned custom buffer allocation in the NAND driver
- remove broken bounce buffer implementation for 16-byte align

Let the MTD core take care of both

Fixes messages like these:
[  102.820541] Data buffer not 16 bytes aligned: 87daf08c

Signed-off-by: Felix Fietkau <nbd@nbd.name>
target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch

index f5cdfc9..d50e689 100644 (file)
@@ -14,7 +14,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
  drivers/mtd/nand/mtk_nand2.c         | 2304 +++++++++++++++++++++++++++++++++++
  drivers/mtd/nand/mtk_nand2.h         |  452 +++++++
  drivers/mtd/nand/nand_base.c        |    6 +-
- drivers/mtd/nand/nand_bbt.c         |   19 +
  drivers/mtd/nand/nand_def.h         |  123 ++
  drivers/mtd/nand/nand_device_list.h |   55 +
  drivers/mtd/nand/partition.h        |  115 ++
@@ -1299,7 +1298,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +
 --- /dev/null
 +++ b/drivers/mtd/nand/mtk_nand2.c
-@@ -0,0 +1,2365 @@
+@@ -0,0 +1,2345 @@
 +/******************************************************************************
 +* mtk_nand2.c - MTK NAND Flash Device Driver
 + *
@@ -1347,8 +1346,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +unsigned int CFG_BLOCKSIZE;
 +
 +static int shift_on_bbt = 0;
-+extern void nand_bbt_set(struct mtd_info *mtd, int page, int flag);
-+extern int nand_bbt_get(struct mtd_info *mtd, int page);
 +int mtk_nand_read_oob_hw(struct mtd_info *mtd, struct nand_chip *chip, int page);
 +
 +static const char * const probe_types[] = { "cmdlinepart", "ofpart", NULL };
@@ -1397,9 +1394,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +BOOL g_bHwEcc = true;
 +
 +
-+static u8 *local_buffer_16_align;   // 16 byte aligned buffer, for HW issue
-+static u8 local_buffer[4096 + 512];
-+
 +extern void nand_release_device(struct mtd_info *mtd);
 +extern int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state);
 +
@@ -1420,6 +1414,25 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +
 +static u8 nand_badblock_offset = 0;
 +
++static void nand_bbt_set(struct mtd_info *mtd, int page, int flag)
++{
++      struct nand_chip *this = mtd->priv;
++      int block;
++
++      block = (int)(page >> (this->bbt_erase_shift - this->page_shift - 1));
++      this->bbt[block >> 3] &= ~(0x03 << (block & 0x6));
++      this->bbt[block >> 3] |= (flag & 0x3) << (block & 0x6);
++}
++
++static int nand_bbt_get(struct mtd_info *mtd, int page)
++{
++      struct nand_chip *this = mtd->priv;
++      int block;
++
++      block = (int)(page >> (this->bbt_erase_shift - this->page_shift - 1));
++      return (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
++}
++
 +void nand_enable_clock(void)
 +{
 +    //enable_clock(MT65XX_PDN_PERI_NFI, "NAND");
@@ -2164,10 +2177,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +      struct nand_chip *nand = mtd->priv;
 +      u32 u4SecNum = u4PageSize >> 9;
 +
-+      if (((u32) pPageBuf % 16) && local_buffer_16_align)
-+              buf = local_buffer_16_align;
-+      else
-+              buf = pPageBuf;
++      buf = pPageBuf;
 +      if (mtk_nand_ready_for_read(nand, u4RowAddr, 0, true, buf)) {
 +              int j;
 +              for (j = 0 ; j < u4SecNum; j++) {
@@ -2185,9 +2195,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +              mtk_nand_stop_read();
 +      }
 +
-+      if (buf == local_buffer_16_align)
-+              memcpy(pPageBuf, buf, u4PageSize);
-+
 +      return bRet;
 +}
 +
@@ -2201,12 +2208,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +
 +      MSG(WRITE, "mtk_nand_exec_write_page, page: 0x%x\n", u4RowAddr);
 +
-+      if (((u32) pPageBuf % 16) && local_buffer_16_align) {
-+              printk(KERN_INFO "Data buffer not 16 bytes aligned: %p\n", pPageBuf);
-+              memcpy(local_buffer_16_align, pPageBuf, mtd->writesize);
-+              buf = local_buffer_16_align;
-+      } else
-+              buf = pPageBuf;
++      buf = pPageBuf;
 +
 +      if (mtk_nand_ready_for_write(chip, u4RowAddr, 0, true, buf)) {
 +              mtk_nand_write_fdm_data(chip, pFDMBuf, u4SecNum);
@@ -3390,9 +3392,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +              return -ENOMEM;
 +      }
 +
-+      /* Allocate memory for 16 byte aligned buffer */
-+      local_buffer_16_align = local_buffer + 16 - ((u32) local_buffer % 16);
-+      printk(KERN_INFO "Allocate 16 byte aligned buffer: %p\n", local_buffer_16_align);
 +      host->hw = hw;
 +
 +      /* init mtd data structure */
@@ -3515,23 +3514,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +      nand_chip->chip_shift = ffs(nand_chip->chipsize) - 1;//0x1C;//ffs(nand_chip->chipsize) - 1;
 +        nand_chip->cmd_ctrl = mtk_nfc_cmd_ctrl;
 +
-+      /* allocate buffers or call select_chip here or a bit earlier*/
-+      {
-+              struct nand_buffers *nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize + mtd->oobsize * 3, GFP_KERNEL);
-+              if (!nbuf) {
-+                      return -ENOMEM;
-+              }
-+              nbuf->ecccalc = (uint8_t *)(nbuf + 1);
-+              nbuf->ecccode = nbuf->ecccalc + mtd->oobsize;
-+              nbuf->databuf = nbuf->ecccode + mtd->oobsize;
-+
-+              nand_chip->buffers = nbuf;
-+              nand_chip->options |= NAND_OWN_BUFFERS;
-+      }
-+
-+      nand_chip->oob_poi = nand_chip->buffers->databuf + mtd->writesize;
-+      nand_chip->badblockpos = 0;
-+
 +      if (devinfo.pagesize == 4096)
 +              layout = &nand_oob_128;
 +      else if (devinfo.pagesize == 2048)
@@ -3555,6 +3537,9 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +      mtd->oobsize = devinfo.sparesize;
 +      hw->nfi_cs_num = 1;
 +
++      nand_chip->options |= NAND_USE_BOUNCE_BUFFER;
++      nand_chip->buf_align = 16;
++
 +      /* Scan to find existance of the device */
 +      if (nand_scan(mtd, hw->nfi_cs_num)) {
 +              MSG(INIT, "%s : nand_scan fail.\n", MODULE_NAME);
@@ -3607,9 +3592,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +      MSG(INIT, "[NFI] mtk_nand_probe fail, err = %d!\n", err);
 +      nand_release(mtd);
 +      platform_set_drvdata(pdev, NULL);
-+      if ( NULL != nand_chip->buffers) {
-+              kfree(nand_chip->buffers);
-+      }
 +      kfree(host);
 +      nand_disable_clock();
 +      return err;
@@ -3623,9 +3605,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 +      struct nand_chip *nand_chip = &host->nand_chip;
 +
 +      nand_release(mtd);
-+      if ( NULL != nand_chip->buffers) {
-+              kfree(nand_chip->buffers);
-+      }
 +      kfree(host);
 +      nand_disable_clock();
 +
@@ -4149,34 +4128,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
  nand_get_device(struct mtd_info *mtd, int new_state)
  {
        struct nand_chip *chip = mtd_to_nand(mtd);
---- a/drivers/mtd/nand/nand_bbt.c
-+++ b/drivers/mtd/nand/nand_bbt.c
-@@ -1215,6 +1215,25 @@ err:
-       return res;
- }
-+void nand_bbt_set(struct mtd_info *mtd, int page, int flag)
-+{
-+      struct nand_chip *this = mtd->priv;
-+      int block;
-+
-+      block = (int)(page >> (this->bbt_erase_shift - this->page_shift - 1));
-+      this->bbt[block >> 3] &= ~(0x03 << (block & 0x6));
-+      this->bbt[block >> 3] |= (flag & 0x3) << (block & 0x6);
-+}
-+
-+int nand_bbt_get(struct mtd_info *mtd, int page)
-+{
-+      struct nand_chip *this = mtd->priv;
-+      int block;
-+
-+      block = (int)(page >> (this->bbt_erase_shift - this->page_shift - 1));
-+      return (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
-+}
-+
- /**
-  * nand_update_bbt - update bad block table(s)
-  * @mtd: MTD device structure
 --- /dev/null
 +++ b/drivers/mtd/nand/nand_def.h
 @@ -0,0 +1,123 @@