Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753396AbbG1R6j (ORCPT ); Tue, 28 Jul 2015 13:58:39 -0400 Received: from mail-bn1bon0117.outbound.protection.outlook.com ([157.56.111.117]:40363 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752485AbbG1R6f (ORCPT ); Tue, 28 Jul 2015 13:58:35 -0400 Authentication-Results: spf=fail (sender IP is 192.88.168.50) smtp.mailfrom=freescale.com; vger.kernel.org; dkim=none (message not signed) header.d=none; From: Han Xu To: CC: , , , , , , , Subject: [PATCH 5/6] mtd: nand: gpmi: correct bitflip for erased NAND page Date: Tue, 28 Jul 2015 12:50:41 -0500 Message-ID: <1438105841-22314-1-git-send-email-b45815@freescale.com> X-Mailer: git-send-email 1.9.1 X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;BN1AFFO11FD052;1:0JvYVBtCEG3vJmPG4kNhpXDZH31/s/ljTaJ0xwRAlOuc8b8niL9CBe7YonNM5/OPYddJJV5YDTCiDL71LcrXOWJVy9X5pZpjGOrFtrCZ4dbae58xKUGPbfsdvtDKXyb+Q1h83qeMZ9yrVuaNC0L7QrrMQShpZNf0dYAT3wD3juQhIdDUYvLkwIcrizgQdvT7BknzR56NznYnjU768ydr6WXdq2J/cQ+PMCqd8c+iFYPJGUT8h1EboU6HFD8mnJjaF68SGcNYWddJE1RCFQE00Pxd9210s48fBI6N2u9wzbdO1Bd9quBJRRUVvc3VOMt6jPSCcp1evrOV7ZuOI5Ya2w== X-Forefront-Antispam-Report: CIP:192.88.168.50;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(6009001)(2980300002)(339900001)(189002)(199003)(19580405001)(62966003)(36756003)(229853001)(47776003)(85426001)(77156002)(104016003)(110136002)(575784001)(77096005)(105606002)(87936001)(2351001)(92566002)(19580395003)(50986999)(189998001)(6806004)(33646002)(46102003)(48376002)(106466001)(50226001)(5001960100002);DIR:OUT;SFP:1102;SCL:1;SRVR:BLUPR03MB551;H:tx30smr01.am.freescale.net;FPR:;SPF:Fail;MLV:sfv;MX:1;A:1;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB551;2:vHhfNGDnwoLqgmJ+ZruoQrv3+Hjrlu+YbuZSHcBX+G2pVakEkhzWrFZzJUaq8e7fV0mo+c+Ftz0KPiIPKvqqcVurjnue1ABntgtfZU3HEm7Fl0U5TdhG/H3xUHFyx5n+1QduwxUKmvwqc4kqMzG3OapEcaK422CdZQirqr/xxEA=;3:kCc+MB8lY1opGodDgbJTT49trSiSd/xJw6L+2jn+WbJKv59Hy2mWEtfvIzMvbD/Xi0vDqapJjfVSkUmTZDBM3z1Z6mexot2+49gSm/vQlhepDA5qA1tPQ3T/quKEPBt4xKyp8x10hyDvpL3g6G/zuqAur+AT5Zez0QPLLPC1kE+SubdlDIu8Zv9xjpIr24JHy8lzHg0/n+bgk88cSlRF53UAVOM9PxCzM42PJ6/Cwyw=;25:H0a7MM7c+BUCe8GFlsAZn+ISGLciyaoaYYAnxSOHwsiqRwGWDBHr/57xiBDzvuG5j8gVC/DHh2U/2fJ+wy2sUC9UWg571Hc6xSPnUzudnrvL3ZGCV+R3drs5JutPO9MmED/9Z2VKLIVC9EvVz0GivfZy05RkJBgFi+RT0Y/Klb7W5+gwsGM/CL2qp8A0aZ2qR74oYzCq331kJVlYitozHFnRi6wXOP1xXT4dRam9Ho8VXOFAaoyL85ZJWE9XBq2X X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB551; X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB551;20:x2pov8xXSTqzYP85gPFPf0xrEZIU2cCvkWL7pjoLJAHd2yyNeeNB+TpFQSOu3QNf/cz/bt8X+yYzYA/PQwnHnowZbvJOHnWVp7ww35NAnH8TerOqui+07xewEFv4MOfL75V00Gqs/yJSa0LcuMpSTPQtDs7r1GbHWtZWcBO6km16ffWUY17w6PGx/n0TgtVWdtazOg+Be8zwcJyjF7PYxwBdvcA4YqQHdUJyQfsW/yjkw97s48LfpDmNpYiPtcNW+wDWRBhYIVEDLNKUw77JcbC8fQwjdVmZ7E/38X5Um3UOC+bNzXvo8Jcq6ge1/lJOaHhQpQ15DMe2UZyHHJl+PDbEAanrx9xvF7MaC1C6gos=;4:kP21mxX8q1jlRkLk5A0rfsCeaJk3YRmeV9sweVbswCjABmKCWiBJCqb7rJzqg8SNmUtOregOtliKO1/iKTWRl3WLK/GV7K3gnUuMiYm9B4UyPh5RlSTuFGIQt1usAfmxHs0yoJF1PaZyXaj1eG/dZArDXwZ17cG56ZyQ3wrD2id65oh1pGu/9UfsRexzf32/MyMPNMPikVsSOgZdihS8tKuAdsoyH6sCg/jn5tnSPijHJAaQ7ErUdjzvKTAx4wB1Z3yOXHfPHuuYgz5C/ygh3cnGsEjSJiJO0XTh6lX8Tx4= BLUPR03MB551: X-MS-Exchange-Organization-RulesExecuted X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(5005006)(3002001);SRVR:BLUPR03MB551;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB551; X-Forefront-PRVS: 06515DA04B X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB551;23:23LVWYd6dw7YP05qCKW50KLfAbGg/HUN9mEAJvrbUlzExdws3Cp1ck6oXaz9u2l39fJtPdwGGWDHsmclXwvQj62sQmT6zHCJ5dQXSc7beHsgB8veMR4dV1d7N5YdsSoFXwSgl84Y6lyfUNxY7di/fdk1H1OIO+4bammSceMs+10MBahkGJix8zIxokk8iDFNxnW+AFdXVY3JznMZwmT/vzeNDik2pIzROf+5RxBUE135stpAAruS5gUHEs+f253BH7M82P9MeZKMk4KKUSXU0Yx0IQ36wKkmoyTD3KiJC3EA3uqeHhPxPAveM8zPFkOZ3FebB5TvrfAMS2UWXcPfr4YQqsvpUUbVEye/TAHlEPFBrGCedMXKIDomuatwbkFzBcaMZlAVIsFV3K6ZqkyzJsOAmnRPMX5NGKzIemlquGijFze5iCA7U3YIT9TLONIlijWdvO7k7vIjGZxlHzV29qKUVd9Y4Z29C6rnM93jSq8PjI3k4Im4tyZgQg0j75Wl3iApSa+7TdRrOm7y902EFQgm1RED0Oy9QVl1X4rwoPd0cf3jbZaLJPhYZ0Y9xxP7Z49DJIqN53N6ueO2Z09tA9smQN5443UCQkVerCohE/KUy3ob7yxAoZ6KJqjwAGHsD3k6F6n4GHfZVk2Im54SnLzFf5F6hYYUiA31CRw5zNgZsK97DkWXwz/PWqzlNhcEua6yZMXu25Sr6iJJmxHRCp5FKTOV7/6fEXsfdjXUQwun+DWGZPczGooW8B1iXJYhrM3zoeJ/vPzYUzgGgVa6JFI6XlFT/arZC1rNAMLg22lXApfDrYbkmkLp/4UFz7fJ X-Microsoft-Exchange-Diagnostics: 1;BLUPR03MB551;5:msVOSUKSJbAlc/n9Jx5ej4LrFxhlB79/XHRWhQ1EyD2ndSNSN73Lq2U08GkTcHz19AsPZj603GTi0Hw1M5be6ftPc9GXFDiNoNEdMEpBzxLyjz6BW6IsmgjvNqwQaBWc87RCM3CVMRtXYjCHTTluqQ==;24:VvePDgrRRdzBdf3VDuK2pCJFPRAByRls+c6coVwiIaTs80px2Z4f1HfQ3h5NkcCFYGIu2Ja6+tVWOwcvHYt9yRh6Y1WbGHzMDRd1ogi6NL8=;20:L4AMk8pj1F3/U4MMGXM1Ut00zHqUwFZcU7dFttuFc5lPdZlP0JVlAjaR8xAfBtkJh608VOZkL4iFZiMFDTVN+g== X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Jul 2015 17:58:23.6408 (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: BLUPR03MB551 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5818 Lines: 161 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. 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 6b37414..44433da 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 gf/2 for mx6qp and mx7 */ + if (GPMI_IS_MX6QP(this) || GPMI_IS_MX7(this)) + writel(BF_BCH_MODE_ERASE_THRESHOLD(gf_len/2), + 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 0462103..362cf4c 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; } @@ -1991,6 +2010,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 1e105f1..36ffeda 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/