diff options
author | Felix Fietkau <nbd@nbd.name> | 2018-07-11 20:56:42 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2018-07-11 20:59:44 +0200 |
commit | 33553a11ab83c4e487f357e3b4a8c3000e1c499d (patch) | |
tree | aae2711686fd0ce035df791c3bd537f32c2bad8a /target | |
parent | 21ee8ce9b52f8ae4a6babf4032f71e2d4d56392b (diff) | |
download | upstream-33553a11ab83c4e487f357e3b4a8c3000e1c499d.tar.gz upstream-33553a11ab83c4e487f357e3b4a8c3000e1c499d.tar.bz2 upstream-33553a11ab83c4e487f357e3b4a8c3000e1c499d.zip |
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>
Diffstat (limited to 'target')
-rw-r--r-- | target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch | 99 |
1 files changed, 25 insertions, 74 deletions
diff --git a/target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch b/target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch index f5cdfc9bc3..d50e689110 100644 --- a/target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch +++ b/target/linux/ramips/patches-4.14/0039-mtd-add-mt7621-nand-support.patch @@ -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 @@ |