From 29f40c07e7a649c6fc44a3a44449dce1ee733816 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 4 May 2020 22:08:53 +0800 Subject: nand: mxs: correct bitflip for erased NAND page This patch is a porting of http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/ commit/?h=imx_4.1.15_1.0.0_ga&id=e4dacc44d22e9474ec456cb330df525cd805ea38 " i.MX6QP and i.MX7D BCH module integrated a new feature to detect the bitflip number for erased NAND page. So for these two platform, set the erase threshold to gf/2 and if bitflip detected, GPMI driver will correct the data to all 0xFF. Also updated the imx6qp dts file to ditinguish the GPMI module for i.MX6Q with the one for i.MX6QP. " In this patch, i.MX6UL is added and threshold changed to use ecc_strength. Signed-off-by: Peng Fan --- drivers/mtd/nand/raw/mxs_nand.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 55d24cd062..2ac06a5730 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -10,6 +10,7 @@ * * Copyright (C) 2010 Freescale Semiconductor, Inc. * Copyright (C) 2008 Embedded Alley Solutions, Inc. + * Copyright 2017-2019 NXP */ #include @@ -660,11 +661,13 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, { struct mxs_nand_info *nand_info = nand_get_controller_data(nand); struct bch_geometry *geo = &nand_info->bch_geometry; + struct mxs_bch_regs *bch_regs = nand_info->bch_regs; struct mxs_dma_desc *d; uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip; uint32_t corrected = 0, failed = 0; uint8_t *status; int i, ret; + int flag = 0; /* Compile the DMA descriptor - wait for ready. */ d = mxs_nand_get_dma_desc(nand_info); @@ -768,8 +771,13 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, if (status[i] == 0x00) continue; - if (status[i] == 0xff) + if (status[i] == 0xff) { + if (is_mx6dqp() || is_mx7() || + is_mx6ul()) + if (readl(&bch_regs->hw_bch_debug1)) + flag = 1; continue; + } if (status[i] == 0xfe) { if (mxs_nand_erased_page(mtd, nand, @@ -801,6 +809,8 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, memcpy(buf, nand_info->data_buf, mtd->writesize); + if (flag) + memset(buf, 0xff, mtd->writesize); rtn: mxs_nand_return_dma_descs(nand_info); @@ -1160,6 +1170,12 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) writel(tmp, &bch_regs->hw_bch_flash0layout1); nand_info->bch_flash0layout1 = tmp; + /* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */ + if (is_mx6dqp() || is_mx7() || + is_mx6ul()) + writel(BCH_MODE_ERASE_THRESHOLD(geo->ecc_strength), + &bch_regs->hw_bch_mode); + /* Set *all* chip selects to use layout 0 */ writel(0, &bch_regs->hw_bch_layoutselect); -- cgit v1.2.3