summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPeng Fan <peng.fan@nxp.com>2016-05-07 16:58:24 +0800
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2017-01-11 21:25:09 +0100
commit17053e88b3be38762664332a55b9e9217b3da9a2 (patch)
treeb83b5004a2483abb80e60e2a30ddc8680ec0c5a0 /drivers
parent6bef4602cc0d270c56277705180d634c3fa6a05c (diff)
MLK-12693-2 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 <peng.fan@nxp.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/mxs_nand.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c
index 42fb1877e5..43f00a5457 100644
--- a/drivers/mtd/nand/mxs_nand.c
+++ b/drivers/mtd/nand/mxs_nand.c
@@ -693,10 +693,12 @@ 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 mxs_dma_desc *d;
+ struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
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);
@@ -800,8 +802,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_soc_type(MXC_SOC_MX7) ||
+ is_cpu_type(MXC_CPU_MX6UL))
+ if (readl(bch_regs->hw_bch_debug1))
+ flag = 1;
continue;
+ }
if (status[i] == 0xfe) {
if (mxs_nand_erased_page(mtd, nand,
@@ -833,6 +840,9 @@ 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);
@@ -1155,6 +1165,12 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET;
writel(tmp, &bch_regs->hw_bch_flash0layout1);
+ /* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */
+ if (is_mx6dqp() || is_soc_type(MXC_SOC_MX7) ||
+ is_cpu_type(MXC_CPU_MX6UL))
+ writel(BCH_MODE_ERASE_THRESHOLD(ecc_strength),
+ &bch_regs->hw_bch_mode);
+
/* Set *all* chip selects to use layout 0 */
writel(0, &bch_regs->hw_bch_layoutselect);