ソースを参照

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 <[email protected]>
Felix Fietkau 7 年 前
コミット
33553a11ab

+ 25 - 74
target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch

@@ -14,7 +14,6 @@ Signed-off-by: John Crispin <[email protected]>
  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 <[email protected]>
 +
 --- /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 <[email protected]>
 +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 <[email protected]>
 +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 <[email protected]>
 +
 +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 <[email protected]>
 +	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 <[email protected]>
 +		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 <[email protected]>
 +
 +	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 <[email protected]>
 +		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 <[email protected]>
 +	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 <[email protected]>
 +	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 <[email protected]>
 +	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 <[email protected]>
 +	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 <[email protected]>
  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 @@