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:
parent
21ee8ce9b5
commit
33553a11ab
1 changed files with 25 additions and 74 deletions
|
@ -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 @@
|
||||||
|
|
Loading…
Reference in a new issue