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:
Felix Fietkau 2018-07-11 20:56:42 +02:00
parent 21ee8ce9b5
commit 33553a11ab

View 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.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,10 +2177,7 @@ 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 = pPageBuf;
+ buf = local_buffer_16_align;
+ else
+ 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;
+ for (j = 0 ; j < u4SecNum; j++) { + for (j = 0 ; j < u4SecNum; 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,12 +2208,7 @@ 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) { + buf = pPageBuf;
+ 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;
+ +
+ if (mtk_nand_ready_for_write(chip, u4RowAddr, 0, true, buf)) { + if (mtk_nand_ready_for_write(chip, u4RowAddr, 0, true, buf)) {
+ mtk_nand_write_fdm_data(chip, pFDMBuf, u4SecNum); + mtk_nand_write_fdm_data(chip, pFDMBuf, u4SecNum);
@ -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 @@