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
	 Felix Fietkau
					Felix Fietkau