From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751886AbcFXVkJ (ORCPT ); Fri, 24 Jun 2016 17:40:09 -0400 Received: from mail-am1on0091.outbound.protection.outlook.com ([157.56.112.91]:55571 "EHLO emea01-am1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751756AbcFXVj2 (ORCPT ); Fri, 24 Jun 2016 17:39:28 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=han.xu@nxp.com; From: Han Xu To: , , , , , , , , , CC: , , Subject: [PATCH v3 4/6] mtd: nand: gpmi: correct bitflip for erased NAND page Date: Fri, 24 Jun 2016 16:40:09 -0500 Message-ID: <1466804411-19874-5-git-send-email-han.xu@nxp.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1466804411-19874-1-git-send-email-han.xu@nxp.com> References: <1466804411-19874-1-git-send-email-han.xu@nxp.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [192.88.168.49] X-ClientProxiedBy: BY2PR04CA0010.namprd04.prod.outlook.com (10.255.247.20) To VI1PR0401MB1853.eurprd04.prod.outlook.com (10.165.235.19) X-MS-Office365-Filtering-Correlation-Id: ae938fae-da59-4285-72a2-08d39c77fe20 X-Microsoft-Exchange-Diagnostics: 1;VI1PR0401MB1853;2:8HeSJ6VCwWkzO+CQhQP3SvyMFuYbUfsghaLE75EWm8fia9FACq4si8bDLbOhIxNM2sPFQndrCR7FvmaeAfCVAssEkbVLRm+ajAmRMiaBDlPMUZX7dMOyZ7AmmNjmDXynsJmeBc+NsT2olEAdDag3sFXf9ON30PXVkvt1qZM0kv05SccBOY/RVCNr8KmdsItn;3:yszkNGVV6CU4D7Q/U54FMZIwlen6WlTxJZjRySab6Jo4CwfVd1XBTD6pVEUjc8ZmQAEifUO1YC/tuyOICo/24NjcW6rhb6X3JjxcU9IUhL0XAOgW8xW5VkY4xTzO1Eu/;25:Rbc4wiYMwhOopOjYxPKMDxuUPWCMvDu3C2iDIsnovi14kZ9/p7WmSWAyg+7N99M9niMGim/XIZS4nOXwPbtujnlfNF0TuUfNkJxT/+qn34APK29AkHVdluxOB+Sjn1INilCIotMRAFxOZwBRZxOFDqQ9B0Zx8FUe7CYS4ipLfPleM7QL7Sv0/MyQ1Pf3anAzbw6Ek6R+eYxhQRcm8EgEx7TVdDqe8Nd537zPdEcJnXIxbb8beMxogZ+tMLYzuMLDjp9YCrL15inNKdcOsGb3RF4x2XFusTOi8F6JYVhfaqiYDA/Lukj//wtUqCrRm5HB54e4BPmpa0l6hl/yBzPLvESQ6yKEU7+ZGx9TXPa/HVF63S492Ar9iIYiAYa1VBowBMqnCTIN6XArlQGVMNrCHpvNUfZnW84CBGnm9cfUliE= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:VI1PR0401MB1853; X-Microsoft-Exchange-Diagnostics: 1;VI1PR0401MB1853;20:ICFbgw5XLb/WkloVyOiYl4tcYfkq52zXQ6ga+DmF/TgasGQBKopqDyzleT2JF+Xa5QBGAd+gjOcisPMWTZYwDlPydmb2yjCNKRCZW3YStMlDgK4VzOiWNG7ayaP2ZG50lVFArZjnZMjlkiJzP5AXckKJJ0h/ciYWhpfFk93HLY0BBcJBtEpo7ZIHhScsUpXyUfb3L7vKAokBdS7Qs6Hv6KU0pZrS6OwJ7BHMXSAJu6b9H/jnaQ9vmCUUuPnFdRbk2ZD7pETfwdhxugAY9t5wDRyLYmezaxFImXjCJP1uMIqtJD4oWP4tXey3aC8BaqMFtDviij1gd5GALR5s+uwDIAyym5BbrCi9SULTJns8XoZXd2cM2MQftGPN5P7zOL70v9bdCcyNiKHfPMi3oYx7ZXcNypKOo88pbf3n/CKuqPcknKTxw3rxm2InD/3m1jwrpAIH5jX0LdUIEbsODJyZB14z6uQht6/6tbS7a3Oss0wN4I2dF3IaMceEQ17Krb0x;4:+TwZz9cqjiHsSI7lN2juKqz6G4fQSHHnFgLLWFupfHxsnAoQzxTSnhFU/5XdmXXuAWRDho6g5MwsLdhzx1b3TNFqf48/+C+o7Fu0xfx5fcXAquLVTSPAKr65NyVhGPzzzy1RIGVNnkv2pT4hiAUmSdrzKRLyOb++ISUmi1w3tnwVHjWATQLlHjDRJSN6BMs80cTNMp+Hn6CZxPCCupohYoY6wHQN6LwWXloHSgnIeS4vrWvUaeontEA0P7asvw2GeeB+Te2hSvV6i7UxtyN8j/dwv4JCI6GEqnutIyaoF3oYBYojOlAsFR1GvSjjrer2MTvyAxzPt1mC5f6wzRbfsMTAW+GtJrtlWpLuI+JxrRJj7hth+oJocDLmbmzPRwet6O14m4Ti4EbAWoOI4YpQt9POcjWsxh7wrXMQu+2GpHc98pVUjBdsenGSzzJmZYIw X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(185117386973197); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6055026);SRVR:VI1PR0401MB1853;BCL:0;PCL:0;RULEID:;SRVR:VI1PR0401MB1853; X-Forefront-PRVS: 0983EAD6B2 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(199003)(189002)(42186005)(68736007)(305945005)(7736002)(50226002)(229853001)(66066001)(105586002)(2950100001)(106356001)(48376002)(7846002)(4326007)(36756003)(77096005)(101416001)(2906002)(50466002)(76176999)(50986999)(8676002)(81166006)(81156014)(92566002)(33646002)(19580395003)(47776003)(19580405001)(2201001)(586003)(6116002)(3846002)(189998001)(97736004)(86362001)(5003940100001)(5001770100001)(575784001)(921003)(1121003);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR0401MB1853;H:Cayman.am.freescale.net;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;VI1PR0401MB1853;23:Gjoa2PG3tzD21bzP5wbRE/XoE2zjgilARQon8HI?= =?us-ascii?Q?fal6aL4F0eLrYSSEXJndlj69lQz/Jf1vCKkokjaKqjjViCT2x8A2g7m7yLsE?= =?us-ascii?Q?umxo2zmMwLbdKHfdsVvOVDXFtj+cFyaCglNN3k+RNLARHaP/25wHfXYXJJoK?= =?us-ascii?Q?6Ixlg3ydZU+JIN4aQaNi0xE7EpxxyfgwUoPoDpGEYTVzMUgLOmGIzn49q21Z?= =?us-ascii?Q?f4O7uNhbDushWJ6LLEuXX0rOsaPUb1qlidCWffADMGsqRXr/GxjNtwhT0ucX?= =?us-ascii?Q?X9dyjnr7HeQRpjfwAqwxA5hdZLFdevR75lDXQ1zod3P+FyXwBQezG3Xc+2Rj?= =?us-ascii?Q?6ZOlYPhwuMSujeMym1g1JLf5Sz6ljtATY/PtyL8nyhOEFPf/PyfbqRs8agIe?= =?us-ascii?Q?pn3zBctv1Z9UdtZgMzEwxtp+U/9hcjCeK2H6TfRIPF1T4f4Wma+jWgBwKrrI?= =?us-ascii?Q?v42fIIwhhFbnb5+/68I8KVJCPtmzX9Ltl6KdAb+G8ItYAOMim9eraDkeO4mU?= =?us-ascii?Q?DHdJq/wma+wLTSE74rJYVv5Ub2zfzsf5cNFd2VSpDhGFnf50yx4DQ08LcfbN?= =?us-ascii?Q?i7nF/Ez2uW48Hyp+FsSCo4JEj5cItYAIXzx8VtU4M6bJDqAJeMG0IH8pjOYv?= =?us-ascii?Q?dJ59T3m6iClUO5haYauF2ijlsotOpzuQnYqPmNfNG21fCDva3DawwSWOWoF8?= =?us-ascii?Q?qVjRozI0XReZjtYS1/RnHLmDyrUscFvgyg0hhKx1Xirm40rSG3lUnEpEgUe+?= =?us-ascii?Q?IgyKFCVnQ3OYPfbGgyc4eLu4fDy+W2YM7EWPnWDw7nFoL3W7VXm/iyOWzi9W?= =?us-ascii?Q?pyDGswv4XzQUvPFe81kMxpKuLmhvVefIcvZIRxFoTxGBhs1mhd7IZ+EFYFXY?= =?us-ascii?Q?0Ez1zvk/96/E2LpSwTZgNd6y6pVmJ6L+c4EsyFxWDjzssu0MkqHFLy2XZFL2?= =?us-ascii?Q?BV+I54AQFQtIuXzEUc9rXiKpzqnUI7/ET6+Zl2uqu59eYrs79j69/G1kaqQr?= =?us-ascii?Q?XOX15xiGOz8b/5gyQ/LR1HH847abLxhpd0QJEQ+Z/QAtbhA4m34yxdX0b2aM?= =?us-ascii?Q?gDOeUh/WmqU6AAQsqFbVmItp9I1lbB3lQk96wQ0FN16yGQwUQYeZiPTQLypo?= =?us-ascii?Q?cieGlBwtQwyF8G8GXKd7HIhzjMJDutOnC?= X-Microsoft-Exchange-Diagnostics: 1;VI1PR0401MB1853;6:GWbuku9a9LIHJzuV2R6K+0sSzx2II8nSNHWxR4DDGzYk8hEIMS3ttY5U3Ir1IlYhi0FGGvJFpCMYCSLcgHkP1KWheMxu4CDnvwU6qT5FN3HA2IYi9W4nj3nh4v6m3wKlq8Uq1esvdzb+chRlPLUr1bMOdFc3E/AHfCvXpBSvpbYxhkhOuJh7/GY/zIdwlVJMnBJVGF6Ge2RuKDCfjCcpC82+AfDao6mi+s2cniaMafKBWBAcw/ij16ZCmu4YWrIw79GlF4iJLCVF0iMY+LFGJjKYZK+JF0+xX7pPCLWqA2YT93GQEcs/lQ9y0U15jnW26QZJGnphkv4Ed1voPi+kItf5Hf1Bs6xXViRISmuit2k=;5:0+PfvTcxymY9FN9TiohPynVeiM4J471IFpCwVWUwmTPt+zypY1l4mE3PijAZOgj9Ng9Njt6gx5BLJBBx25+cEQPjmOsXHJEga9dpi4Y+YtgagzSML3tBK2/WJLpFwNExO83deFcW2+TAbY1tH4IIMg==;24:y+47D7ifdPz2JTvINduBF1vf/kC3H2Z0J23Pmyq8rkgXaNRYP9O/U3LJi/w7msZPVzXYsRfHjMmdv2C2s6pfF+2lU22kau1YvorQrz+6lRM=;7:YMVJ3boxn89saXmNsKZcXzA+dNncPKfOAHTOzFFBaD9AWYyceMcwgBbb6jY7dYaMHT5lGmhIzx07Npxz/55+5l+9hh9rRGBCOxEwv5vsCuTi8ZcqDus+iP7C+8RrKvndKRdcYRZ3bkib9u/ciKOjBvY4ZqZYMHGbxClzo/J3ObCoLgBq5aq8fbstse+lzVkGQRWYQBJUQgboMor07mB3qtx7FwlNrr3ZuonPtp3tMKAFabO9IN/rMU4y0gfwTBrTrRhnFoQL1bKGEen0GgVpQg== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Jun 2016 21:39:13.6537 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0401MB1853 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 ecc_strength and if bitflip detected, GPMI driver will correct the data to all 0xFF. Signed-off-by: Han Xu --- drivers/mtd/nand/gpmi-nand/bch-regs.h | 10 +++++++++ drivers/mtd/nand/gpmi-nand/gpmi-lib.c | 5 +++++ drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 37 +++++++++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/gpmi-nand/bch-regs.h index 228142c..2c44b88 100644 --- a/drivers/mtd/nand/gpmi-nand/bch-regs.h +++ b/drivers/mtd/nand/gpmi-nand/bch-regs.h @@ -30,7 +30,13 @@ #define BM_BCH_CTRL_COMPLETE_IRQ (1 << 0) #define HW_BCH_STATUS0 0x00000010 + #define HW_BCH_MODE 0x00000020 +#define BP_BCH_MODE_ERASE_THRESHOLD 0 +#define BM_BCH_MODE_ERASE_THRESHOLD (0xff << BP_BCH_MODE_ERASE_THRESHOLD) +#define BF_BCH_MODE_ERASE_THRESHOLD(v) \ + (((v) << BP_BCH_MODE_ERASE_THRESHOLD) & BM_BCH_MODE_ERASE_THRESHOLD) + #define HW_BCH_ENCODEPTR 0x00000030 #define HW_BCH_DATAPTR 0x00000040 #define HW_BCH_METAPTR 0x00000050 @@ -125,4 +131,8 @@ ) #define HW_BCH_VERSION 0x00000160 +#define HW_BCH_DEBUG1 0x00000170 +#define BP_BCH_DEBUG1_ERASED_ZERO_COUNT 0 +#define BM_BCH_DEBUG1_ERASED_ZERO_COUNT \ + (0x1ff << BP_BCH_DEBUG1_ERASED_ZERO_COUNT) #endif diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 358ff5d..0b5666a 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -298,6 +298,11 @@ int bch_set_geometry(struct gpmi_nand_data *this) | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size, this), r->bch_regs + HW_BCH_FLASH0LAYOUT1); + /* Set erase threshold to ecc_strength for mx6qp and mx7 */ + if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7(this)) + writel(BF_BCH_MODE_ERASE_THRESHOLD(ecc_strength), + r->bch_regs + HW_BCH_MODE); + /* Set *all* chip selects to use layout 0. */ writel(0, r->bch_regs + HW_BCH_LAYOUTSELECT); diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index aedaff3..db8e546 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -1043,11 +1043,12 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, { struct gpmi_nand_data *this = nand_get_controller_data(chip); struct bch_geometry *nfc_geo = &this->bch_geometry; + void __iomem *bch_regs = this->resources.bch_regs; void *payload_virt; dma_addr_t payload_phys; void *auxiliary_virt; dma_addr_t auxiliary_phys; - unsigned int i; + unsigned int i, j; unsigned char *status; unsigned int max_bitflips = 0; int ret; @@ -1087,9 +1088,14 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, nfc_geo->payload_size, payload_virt, payload_phys); - for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) { - if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED)) + for (i = 0, j = 0; i < nfc_geo->ecc_chunk_count; i++, status++) { + if (*status == STATUS_GOOD) + continue; + if (*status == STATUS_ERASED) { + /* count the number of erased chunks */ + j++; continue; + } if (*status == STATUS_UNCORRECTABLE) { int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; @@ -1098,6 +1104,12 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, int eccbytes; int flips; + /* shortcut for i.MX7 and i.MX6QP */ + if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7(this)) { + mtd->ecc_stats.failed++; + continue; + } + /* Read ECC bytes into our internal raw_buffer */ offset = nfc_geo->metadata_size * 8; offset += ((8 * nfc_geo->ecc_chunk_size) + eccbits) * (i + 1); @@ -1167,6 +1179,25 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, max_bitflips = max_t(unsigned int, max_bitflips, *status); } + /* + * i.MX6QP and i.MX7 have dedicate register to check bitflips in the + * page, while it cannot tell in which chunk bitflips locate, memset + * all the data if bitflips exist and all chunks are erased. + */ + if (j == nfc_geo->ecc_chunk_count && + (GPMI_IS_MX6QP(this) || GPMI_IS_MX7(this))) { + int flips; + + flips = readl(bch_regs + HW_BCH_DEBUG1); + if (flips) { + max_bitflips = max_t(unsigned int, max_bitflips, + flips); + memset(buf, ~0, nfc_geo->payload_size); + memset(chip->oob_poi, ~0, mtd->oobsize); + mtd->ecc_stats.corrected += flips; + } + } + if (oob_required) { /* * It's time to deliver the OOB bytes. See gpmi_ecc_read_oob() -- 1.9.1