From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759463AbbLBXCu (ORCPT ); Wed, 2 Dec 2015 18:02:50 -0500 Received: from mail-by2on0102.outbound.protection.outlook.com ([207.46.100.102]:54986 "EHLO na01-by2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1758392AbbLBXAV (ORCPT ); Wed, 2 Dec 2015 18:00:21 -0500 Authentication-Results: spf=permerror (sender IP is 192.88.168.50) smtp.mailfrom=freescale.com; vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=none action=none header.from=freescale.com; From: Han Xu To: CC: , , , , , , , , , , Subject: [PATCH v8 6/7] mtd: nand: gpmi: correct bitflip for erased NAND page Date: Wed, 2 Dec 2015 16:47:45 -0600 Message-ID: <1449096466-18064-7-git-send-email-b45815@freescale.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1449096466-18064-1-git-send-email-b45815@freescale.com> References: <1449096466-18064-1-git-send-email-b45815@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;BN1AFFO11OLC002;1:KGfMiDGY1p5VniciN5traeDkmr439BEPFtWTvHfSBGCnCkZV3MN5HTU4gCDmVDnFKHV1CHurCN3/y+ZosiotwJvuDt8OvkewUdAy5m5sN0B7mvmw8pmARkOs6jnVWTKIUX/BIigwcjp07L+Xt6sNS9VGOqyjHF0TD+FMZEBrnycRcU62gC7tGUd1eABS/ID/op/qdNkF9ksczXwjXn1pyD4Tgii91+PLqcm1Nt4lDawchYAElpuJgfidQXrPLotpDOqihbM+pEL+AzE/cQtIcT+G79QU7+QQK5E399QqIgWDLuYHeUSsDfMt6L8btftIZpogDT9pzvrNzv0aeEf6+UPOT1n+CcoEHCp/lAaFzJQZG+jrWgv7X/JMOI8hSB7qbFTXlReSE+13UfsrM9lH38hb0GS4YQY2lWqOzEJ5uMH/c06IRNRiJa5kYPmEfeAW X-Forefront-Antispam-Report: CIP:192.88.168.50;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(6009001)(2980300002)(448002)(189002)(199003)(48376002)(19580405001)(87936001)(19580395003)(575784001)(5003940100001)(50466002)(106466001)(2950100001)(92566002)(33646002)(85326001)(77096005)(189998001)(50986999)(97736004)(5001960100002)(110136002)(76176999)(50226001)(81156007)(2351001)(229853001)(1096002)(36756003)(1220700001)(586003)(5008740100001)(6806005)(104016004)(11100500001)(47776003);DIR:OUT;SFP:1102;SCL:1;SRVR:DM2PR03MB559;H:tx30smr01.am.freescale.net;FPR:;SPF:PermError;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Exchange-Diagnostics: 1;DM2PR03MB559;2:kcZLVuuI1zP7ZSaK+Dxn2E7nrkebEOT9MghGbZp3pADbIgliNDlAjh2RyqDK2HLjD6qaPPgZBgu3eljutfhnwlCLfTlS9mSc4SLhvkMMuhJGZ8PJh5ezS0BEXxlZQuWE/5ZnC2uoKi6lXoObwUOUlQ==;3:0wmYyQ13vyBLdbHlawLLXvHx9XavXGChFKPFpdGdxYlZVDepv3db6sV3W1xx46nImBKWA98ajeqL/0mDC054M7bDVGZ4e1HqIEKbxKiwlfie37uALsqPWR7FM64AQZZzzul/NDiegPuewMH7DzGtZmVsJzuDe8yDQ3/8sASEi8vtkO9bN5XNumBdSsM5L7jk+++ceV1LSE/7rp83T3jiD7fM6oi8BzdlGAomrcxgs4w=;25:4Vr4s+C4+F3y9xYNCrXjz4CsITWe2UtPKjgtsTtSSCpGH7YOuINAs3x/Mj8wVYFz17qU0Gom++e58JgD6Pi9NU3WIkAZc28o99kh1sZBp4l7XhcDKNnpjVp2uLANO75fDTRiS3tbIqszoKmg81TMVVm/MzU5mdJmP4un4wgmAB92yuOPkY6bpQ6zZkYlUWhiIIb0yEMCq+yxnT/55+vulybq38udVLiVDOuAp+dUZh1EhgiCVWXyuS8C4O7bJOdn X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DM2PR03MB559; X-Microsoft-Exchange-Diagnostics: 1;DM2PR03MB559;20:KOb8J1yZtRMN+nd39yLY/57bz/uUVr4g+f7hRQrPmu0JWb2nXBP4cxGfO9PYijM7wfQfh7lDQFSYFTgq3CzuguXj+uMwEpl0EsbZLj6XYZ4sdTiipN1Ich/i4ZG74ukb/eGTETNY4DsAcumfGoudfzCTT7831VhiH81ygEfFDOKFKD18ieUL90Ae/uavJ1hwAM0+LI7q61vCOgiI6pFbEpFBW7f8y2+yahNJp2eM/ScLMW0uYrIN4TwxnurZws2vjZsOAacTRyL3ImUDxiD21OKve+w1Tqdn6Uru6ppFeQhOUbR7hnKx8V5absz7LxoZYVg2U3d0qBftPvITtpOpjuK9Li++Dl8AD8++HAeT200=;4:Q9zZeHN4fRYt7bg6uyB53qsC849fvG+SzWuEnS1aWVxKGtlzeG83LKJHBjHGUT3XxKysc1LboCw7z01u+Lx3d4SzC/mecp4SsWZSd4emOfr20T9yRkyGYc5Op6ZA62YyByJKQ/3cHTzqubUBE/kVyWXuYsnxx2Wx5czPL7+yJ8aDTQ1r/WqA04R0C0+PSdl9FXXUJHJEVUYhqKnuBgRA6YxhBEahe1JEgc1xQHU6PJjYaz+NmyhHvl2u+YoYoAHQOxW1oARCxUgpwRGQR88C1IjwhGtkyB5V20ScQ/LTVd9hOvQEcQ43Zud7FLFP28spKa7zQMij6tG8EzpLfBSqn3TkfOfVpO6NqPIqN7CTJw8pu4wYhsNVsqs+jZ1J3NXUJuxjqIgfTXBdPdty17gK9fI80jAtvU/m70HGZEQNV1w= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(101931422205132); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(5005006)(520078)(3002001)(10201501046);SRVR:DM2PR03MB559;BCL:0;PCL:0;RULEID:;SRVR:DM2PR03MB559; X-Forefront-PRVS: 077884B8B5 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DM2PR03MB559;23:gdKRiOwdySFwFkqeaKk/0VdMrGtXRqTg/chEI25c/b?= =?us-ascii?Q?iQr4BZGyyeLaN8t0NcsR25htZP8nDctH/SzLLclgC3cmPTSN+PF64f2+Cobx?= =?us-ascii?Q?luR/3ySxWnrHh6vFXokO2TmNH+tFjnAE0BAMfW1fZsGJbShqaq4TiwoY4SIN?= =?us-ascii?Q?bqab1tNjUAF0l1YPJeWvIjWWoVqRoBEOD1h0pscTtBu8lR0gHgXDeAmionWd?= =?us-ascii?Q?PuxIjjt5uVmq9UWo765+VMEregvdYLnLtqZOgTCVJjYp4xMIegeo3dKhf0Ym?= =?us-ascii?Q?1aiCkV4k07JBSFOPJCZS8Pab/NQY+MSF4zGU3jX0WGcSbnowjxUIMd2RCoY8?= =?us-ascii?Q?OdSdlmB1+EQUHj1N2NHSdh8HBGUf7iTso8i9r+thVeZlmnjBFgaFqI2nDhym?= =?us-ascii?Q?1fGY15COjc+lCdZUMDdAoOPxmBtTglKtnm/UBkqfKW6IUfD1ddjRWOcUuJe5?= =?us-ascii?Q?H84uavTt5CkprA/npkr2RsNX70N2ZT856HiFWkgb4vEi939QnZqWu6HHwHxK?= =?us-ascii?Q?bFiJ4gpl1Jk8rFV9eTmS/U0J4PNmU0AY7P3PiwStT4JQpltL5C7ghsTScMM1?= =?us-ascii?Q?How/g/lhZBRk9qbAJC5vWmpQwlhqMdZX5avLekAS4fjX318IMU7ziZpDBWeT?= =?us-ascii?Q?Bj3s4K4KEQzkndqGYwX3JXtbr0AW+onashxhNeeG0ML9s5AFmjfUTeRJ2hFO?= =?us-ascii?Q?Q9/8J1ib6gxmg3Cl47xbVwZQeiA/1xGtJXyeoT5uVDWs+VADbkQ3FslRPM05?= =?us-ascii?Q?b4kH/j0NHzM6UXncI/mEZ8cuq5o8nkxM0wNwFuAU2N08AQKY3sJ7jzeQ3uhe?= =?us-ascii?Q?swJBYwSRdtnZ/BtfyNeht2vsF0TiIk9GdxY2zQFFExvhorL2i4to4fJEnpWQ?= =?us-ascii?Q?FgULpboPH+m51pTtsHh8ZpwnLx5b+ctVDmF/WmmWcXgRoZZPxjJk1GeF2Y+s?= =?us-ascii?Q?qYm/LjRN1AUB1bcIlzDFMBE7F9msV88J5sE7z7pjIi+mJEpoe7I8AmAgsTT1?= =?us-ascii?Q?w=3D?= X-Microsoft-Exchange-Diagnostics: 1;DM2PR03MB559;5:R9pdYEkuDVW1SpwCGK7q/Ls8gsd+o3es7cODdKn9743R21yrkA3YdnK5vXRR4i1LHRRJWGCeQyOjC6Gv3pFx2BUdkA6XFR7ud/tXlPml6v6wr4+hdvudNis3ANRsh3LM0l/VJBTChbv4HFHcMgHknA==;24:jxHSeA9svNM/3sLpxf7kgk5PT7bnf7Img9loW8LcIP+XaiZgW3M/fg5MfCx4R5lTmz0eBokL7ggYtxA0cVq2TiwzZ3ko8m4t5iiuNqA9p14= X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Dec 2015 23:00:17.5253 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d;Ip=[192.88.168.50];Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR03MB559 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 | 24 +++++++++++++++++++++++- drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 5 ++++- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/gpmi-nand/bch-regs.h index 53e58bc..a84d72b 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 1f26a79..0548d84 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 9f67f0f..9dea56e 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -71,6 +71,12 @@ static const struct gpmi_devdata gpmi_devdata_imx6q = { .max_chain_delay = 12, }; +static const struct gpmi_devdata gpmi_devdata_imx6qp = { + .type = IS_MX6QP, + .bch_max_ecc_strength = 40, + .max_chain_delay = 12, +}; + static const struct gpmi_devdata gpmi_devdata_imx6sx = { .type = IS_MX6SX, .bch_max_ecc_strength = 62, @@ -1010,6 +1016,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, { struct gpmi_nand_data *this = chip->priv; 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; @@ -1018,6 +1025,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, unsigned char *status; unsigned int max_bitflips = 0; int ret; + int flag = 0; dev_dbg(this->dev, "page number is : %d\n", page); ret = read_page_prepare(this, buf, nfc_geo->payload_size, @@ -1050,9 +1058,16 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, status = auxiliary_virt + nfc_geo->auxiliary_status_offset; for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) { - if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED)) + if (*status == STATUS_GOOD) continue; + if (*status == STATUS_ERASED) { + if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7(this)) + if (readl(bch_regs + HW_BCH_DEBUG1)) + flag = 1; + continue; + } + if (*status == STATUS_UNCORRECTABLE) { mtd->ecc_stats.failed++; continue; @@ -1081,6 +1096,10 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, nfc_geo->payload_size, payload_virt, payload_phys); + /* if bitflip occurred in erased page, change data to all 0xff */ + if (flag) + memset(buf, 0xff, nfc_geo->payload_size); + return max_bitflips; } @@ -1990,6 +2009,9 @@ static const struct of_device_id gpmi_nand_id_table[] = { .compatible = "fsl,imx6q-gpmi-nand", .data = &gpmi_devdata_imx6q, }, { + .compatible = "fsl,imx6qp-gpmi-nand", + .data = (void *)&gpmi_devdata_imx6qp, + }, { .compatible = "fsl,imx6sx-gpmi-nand", .data = &gpmi_devdata_imx6sx, }, { diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 58b3d69..149a442 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h @@ -123,6 +123,7 @@ enum gpmi_type { IS_MX23, IS_MX28, IS_MX6Q, + IS_MX6QP, IS_MX6SX, IS_MX7D, }; @@ -306,9 +307,11 @@ void gpmi_copy_bits(u8 *dst, size_t dst_bit_off, #define GPMI_IS_MX23(x) ((x)->devdata->type == IS_MX23) #define GPMI_IS_MX28(x) ((x)->devdata->type == IS_MX28) #define GPMI_IS_MX6Q(x) ((x)->devdata->type == IS_MX6Q) +#define GPMI_IS_MX6QP(x) ((x)->devdata->type == IS_MX6QP) #define GPMI_IS_MX6SX(x) ((x)->devdata->type == IS_MX6SX) #define GPMI_IS_MX7D(x) ((x)->devdata->type == IS_MX7D) -#define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x)) +#define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6QP(x)\ + || GPMI_IS_MX6SX(x)) #define GPMI_IS_MX7(x) (GPMI_IS_MX7D(x)) #endif -- 1.9.1