ramips: clean up and fix MT7621 NAND driver issues
- 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>
This commit is contained in:
		@@ -14,7 +14,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
 drivers/mtd/nand/mtk_nand2.c         | 2304 +++++++++++++++++++++++++++++++++++
 | 
					 drivers/mtd/nand/mtk_nand2.c         | 2304 +++++++++++++++++++++++++++++++++++
 | 
				
			||||||
 drivers/mtd/nand/mtk_nand2.h         |  452 +++++++
 | 
					 drivers/mtd/nand/mtk_nand2.h         |  452 +++++++
 | 
				
			||||||
 drivers/mtd/nand/nand_base.c        |    6 +-
 | 
					 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_def.h         |  123 ++
 | 
				
			||||||
 drivers/mtd/nand/nand_device_list.h |   55 +
 | 
					 drivers/mtd/nand/nand_device_list.h |   55 +
 | 
				
			||||||
 drivers/mtd/nand/partition.h        |  115 ++
 | 
					 drivers/mtd/nand/partition.h        |  115 ++
 | 
				
			||||||
@@ -1299,7 +1298,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
+
 | 
					+
 | 
				
			||||||
--- /dev/null
 | 
					--- /dev/null
 | 
				
			||||||
+++ b/drivers/mtd/nand/mtk_nand2.c
 | 
					+++ b/drivers/mtd/nand/mtk_nand2.c
 | 
				
			||||||
@@ -0,0 +1,2365 @@
 | 
					@@ -0,0 +1,2345 @@
 | 
				
			||||||
+/******************************************************************************
 | 
					+/******************************************************************************
 | 
				
			||||||
+* mtk_nand2.c - MTK NAND Flash Device Driver
 | 
					+* mtk_nand2.c - MTK NAND Flash Device Driver
 | 
				
			||||||
+ *
 | 
					+ *
 | 
				
			||||||
@@ -1347,8 +1346,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
+unsigned int CFG_BLOCKSIZE;
 | 
					+unsigned int CFG_BLOCKSIZE;
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
+static int shift_on_bbt = 0;
 | 
					+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);
 | 
					+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 };
 | 
					+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;
 | 
					+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 void nand_release_device(struct mtd_info *mtd);
 | 
				
			||||||
+extern int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state);
 | 
					+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 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)
 | 
					+void nand_enable_clock(void)
 | 
				
			||||||
+{
 | 
					+{
 | 
				
			||||||
+    //enable_clock(MT65XX_PDN_PERI_NFI, "NAND");
 | 
					+    //enable_clock(MT65XX_PDN_PERI_NFI, "NAND");
 | 
				
			||||||
@@ -2164,9 +2177,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
+	struct nand_chip *nand = mtd->priv;
 | 
					+	struct nand_chip *nand = mtd->priv;
 | 
				
			||||||
+	u32 u4SecNum = u4PageSize >> 9;
 | 
					+	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)) {
 | 
					+	if (mtk_nand_ready_for_read(nand, u4RowAddr, 0, true, buf)) {
 | 
				
			||||||
+		int j;
 | 
					+		int j;
 | 
				
			||||||
@@ -2185,9 +2195,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
+		mtk_nand_stop_read();
 | 
					+		mtk_nand_stop_read();
 | 
				
			||||||
+	}
 | 
					+	}
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
+	if (buf == local_buffer_16_align)
 | 
					 | 
				
			||||||
+		memcpy(pPageBuf, buf, u4PageSize);
 | 
					 | 
				
			||||||
+
 | 
					 | 
				
			||||||
+	return bRet;
 | 
					+	return bRet;
 | 
				
			||||||
+}
 | 
					+}
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
@@ -2201,11 +2208,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
+
 | 
					+
 | 
				
			||||||
+	MSG(WRITE, "mtk_nand_exec_write_page, page: 0x%x\n", u4RowAddr);
 | 
					+	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)) {
 | 
					+	if (mtk_nand_ready_for_write(chip, u4RowAddr, 0, true, buf)) {
 | 
				
			||||||
@@ -3390,9 +3392,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
+		return -ENOMEM;
 | 
					+		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;
 | 
					+	host->hw = hw;
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
+	/* init mtd data structure */
 | 
					+	/* 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->chip_shift = ffs(nand_chip->chipsize) - 1;//0x1C;//ffs(nand_chip->chipsize) - 1;
 | 
				
			||||||
+        nand_chip->cmd_ctrl = mtk_nfc_cmd_ctrl;
 | 
					+        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)
 | 
					+	if (devinfo.pagesize == 4096)
 | 
				
			||||||
+		layout = &nand_oob_128;
 | 
					+		layout = &nand_oob_128;
 | 
				
			||||||
+	else if (devinfo.pagesize == 2048)
 | 
					+	else if (devinfo.pagesize == 2048)
 | 
				
			||||||
@@ -3555,6 +3537,9 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
+	mtd->oobsize = devinfo.sparesize;
 | 
					+	mtd->oobsize = devinfo.sparesize;
 | 
				
			||||||
+	hw->nfi_cs_num = 1;
 | 
					+	hw->nfi_cs_num = 1;
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
 | 
					+	nand_chip->options |= NAND_USE_BOUNCE_BUFFER;
 | 
				
			||||||
 | 
					+	nand_chip->buf_align = 16;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
+	/* Scan to find existance of the device */
 | 
					+	/* Scan to find existance of the device */
 | 
				
			||||||
+	if (nand_scan(mtd, hw->nfi_cs_num)) {
 | 
					+	if (nand_scan(mtd, hw->nfi_cs_num)) {
 | 
				
			||||||
+		MSG(INIT, "%s : nand_scan fail.\n", MODULE_NAME);
 | 
					+		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);
 | 
					+	MSG(INIT, "[NFI] mtk_nand_probe fail, err = %d!\n", err);
 | 
				
			||||||
+	nand_release(mtd);
 | 
					+	nand_release(mtd);
 | 
				
			||||||
+	platform_set_drvdata(pdev, NULL);
 | 
					+	platform_set_drvdata(pdev, NULL);
 | 
				
			||||||
+	if ( NULL != nand_chip->buffers) {
 | 
					 | 
				
			||||||
+		kfree(nand_chip->buffers);
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+	kfree(host);
 | 
					+	kfree(host);
 | 
				
			||||||
+	nand_disable_clock();
 | 
					+	nand_disable_clock();
 | 
				
			||||||
+	return err;
 | 
					+	return err;
 | 
				
			||||||
@@ -3623,9 +3605,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
 | 
				
			|||||||
+	struct nand_chip *nand_chip = &host->nand_chip;
 | 
					+	struct nand_chip *nand_chip = &host->nand_chip;
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
+	nand_release(mtd);
 | 
					+	nand_release(mtd);
 | 
				
			||||||
+	if ( NULL != nand_chip->buffers) {
 | 
					 | 
				
			||||||
+		kfree(nand_chip->buffers);
 | 
					 | 
				
			||||||
+	}
 | 
					 | 
				
			||||||
+	kfree(host);
 | 
					+	kfree(host);
 | 
				
			||||||
+	nand_disable_clock();
 | 
					+	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)
 | 
					 nand_get_device(struct mtd_info *mtd, int new_state)
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
 	struct nand_chip *chip = mtd_to_nand(mtd);
 | 
					 	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
 | 
					--- /dev/null
 | 
				
			||||||
+++ b/drivers/mtd/nand/nand_def.h
 | 
					+++ b/drivers/mtd/nand/nand_def.h
 | 
				
			||||||
@@ -0,0 +1,123 @@
 | 
					@@ -0,0 +1,123 @@
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user