From patchwork Thu Jul 19 15:23:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 946426 X-Patchwork-Delegate: miquel.raynal@bootlin.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Cuc8yU/4"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41WdFx5888z9s0w for ; Fri, 20 Jul 2018 01:28:37 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=xrzMGvkkSArSBhSeGQ6oFo6cA3mcFWKvZkpL54mnSQ4=; b=Cuc8yU/4WrHciFQs2BqPgka4Rr gAbwWEPUiO7Kos/QARpoz6cN/nsmK77tnyQ9GdzxrJQ/wIZuJYifEVSxrhdAPaax4iueMI+61jfYT uy2z1wpoH8t8eMwvKVyPCE8zkuGNXbeObt0D+dLgLcEMx1L7LKDSso5AEcz5OXVoLmFkdVU9jeL08 eP83S+DnzKkG+DyV/LTVrhIByRnQN0ymFaJTPxHQwx4on5Ryb/aGJGMuBqkpnobT+YWhf9+SVqGru BD4yQerffXxIe6FEaPEr3HUz74O97OJtboeMRypU55a5iFbhLaCywjVnxK9QT9oIGczhR/Hohj3kf S675UoiA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fgAqy-00027Y-I8; Thu, 19 Jul 2018 15:28:28 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fgAmT-00068r-TT for linux-mtd@lists.infradead.org; Thu, 19 Jul 2018 15:23:53 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 02B44207E8; Thu, 19 Jul 2018 17:23:39 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (AAubervilliers-681-1-27-161.w90-88.abo.wanadoo.fr [90.88.147.161]) by mail.bootlin.com (Postfix) with ESMTPSA id A54AF206F6; Thu, 19 Jul 2018 17:23:38 +0200 (CEST) From: Miquel Raynal To: Boris Brezillon , Richard Weinberger , David Woodhouse , Brian Norris , Marek Vasut Subject: [PATCH 1/3] mtd: rawnand: marvell: rework BCH engine failure path Date: Thu, 19 Jul 2018 17:23:35 +0200 Message-Id: <20180719152337.6372-2-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180719152337.6372-1-miquel.raynal@bootlin.com> References: <20180719152337.6372-1-miquel.raynal@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180719_082350_277244_083D4BDD X-CRM114-Status: GOOD ( 20.78 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [62.4.15.54 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antoine Tenart , Gregory Clement , Maxime Chevallier , Nadav Haklai , linux-mtd@lists.infradead.org, Thomas Petazzoni , Miquel Raynal , Ofer Heifetz MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org We are about to support a new layout that triggers a faulty mechanism in BCH engine that creates bitflips in erased pages. Before adding the quirk that will workaround this issue, this patch just reworks a bit the section that handles ECC failures in BCH read path. Signed-off-by: Miquel Raynal --- drivers/mtd/nand/raw/marvell_nand.c | 75 +++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 80a074cccb82..954b5755ba59 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -1234,11 +1234,11 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct mtd_info *mtd, int page) { const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout; - int data_len = lt->data_bytes, spare_len = lt->spare_bytes, ecc_len; - u8 *data = buf, *spare = chip->oob_poi, *ecc; + int data_len = lt->data_bytes, spare_len = lt->spare_bytes; + u8 *data = buf, *spare = chip->oob_poi; int max_bitflips = 0; u32 failure_mask = 0; - int chunk, ecc_offset_in_page, ret; + int chunk, ret; /* * With BCH, OOB is not fully used (and thus not read entirely), not @@ -1279,46 +1279,63 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct mtd_info *mtd, * the controller in normal mode and must be re-read in raw mode. To * avoid dropping the performances, we prefer not to include them. The * user should re-read the page in raw mode if ECC bytes are required. + */ + + /* + * In case there is any subpage read error reported by ->correct(), we + * usually re-read only ECC bytes in raw mode and check if the whole + * page is empty. In this case, it is normal that the ECC check failed + * and we just ignore the error. * * However, for any subpage read error reported by ->correct(), the ECC * bytes must be read in raw mode and the full subpage must be checked * to see if it is entirely empty of if there was an actual error. */ for (chunk = 0; chunk < lt->nchunks; chunk++) { + int data_off_in_page, spare_off_in_page, ecc_off_in_page; + int data_off, spare_off, ecc_off; + int data_len, spare_len, ecc_len; + /* No failure reported for this chunk, move to the next one */ if (!(failure_mask & BIT(chunk))) continue; - /* Derive ECC bytes positions (in page/buffer) and length */ - ecc = chip->oob_poi + - (lt->full_chunk_cnt * lt->spare_bytes) + - lt->last_spare_bytes + - (chunk * ALIGN(lt->ecc_bytes, 32)); - ecc_offset_in_page = - (chunk * (lt->data_bytes + lt->spare_bytes + - lt->ecc_bytes)) + - (chunk < lt->full_chunk_cnt ? - lt->data_bytes + lt->spare_bytes : - lt->last_data_bytes + lt->last_spare_bytes); - ecc_len = chunk < lt->full_chunk_cnt ? - lt->ecc_bytes : lt->last_ecc_bytes; + /* + * Only re-read the ECC bytes, unless we are using the 2k/8b + * layout which is buggy in the sense that the ECC engine will + * try to correct data bytes anyway, creating bitflips. In this + * case, re-read the entire page. + */ + data_off_in_page = chunk * (lt->data_bytes + lt->spare_bytes + + lt->ecc_bytes); + spare_off_in_page = data_off_in_page + + (chunk < lt->full_chunk_cnt ? lt->data_bytes : + lt->last_data_bytes); + ecc_off_in_page = spare_off_in_page + + (chunk < lt->full_chunk_cnt ? lt->spare_bytes : + lt->last_spare_bytes); - /* Do the actual raw read of the ECC bytes */ - nand_change_read_column_op(chip, ecc_offset_in_page, - ecc, ecc_len, false); + data_off = chunk * lt->data_bytes; + spare_off = chunk * lt->spare_bytes; + ecc_off = (lt->full_chunk_cnt * lt->spare_bytes) + + lt->last_spare_bytes + + (chunk * (lt->ecc_bytes + 2)); - /* Derive data/spare bytes positions (in buffer) and length */ - data = buf + (chunk * lt->data_bytes); - data_len = chunk < lt->full_chunk_cnt ? - lt->data_bytes : lt->last_data_bytes; - spare = chip->oob_poi + (chunk * (lt->spare_bytes + - lt->ecc_bytes)); - spare_len = chunk < lt->full_chunk_cnt ? - lt->spare_bytes : lt->last_spare_bytes; + data_len = chunk < lt->full_chunk_cnt ? lt->data_bytes : + lt->last_data_bytes; + spare_len = chunk < lt->full_chunk_cnt ? lt->spare_bytes : + lt->last_spare_bytes; + ecc_len = chunk < lt->full_chunk_cnt ? lt->ecc_bytes : + lt->last_ecc_bytes; + + nand_change_read_column_op(chip, ecc_off_in_page, + chip->oob_poi + ecc_off, ecc_len, + false); /* Check the entire chunk (data + spare + ecc) for emptyness */ - marvell_nfc_check_empty_chunk(chip, data, data_len, spare, - spare_len, ecc, ecc_len, + marvell_nfc_check_empty_chunk(chip, buf + data_off, data_len, + chip->oob_poi + spare_off, spare_len, + chip->oob_poi + ecc_off, ecc_len, &max_bitflips); } From patchwork Thu Jul 19 15:23:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 946425 X-Patchwork-Delegate: miquel.raynal@bootlin.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="nONrkHxe"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41WdFr68F0z9s0w for ; Fri, 20 Jul 2018 01:28:32 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=zO0+4aoRzsSazxU7pxJ/T9qE2QLCKIyvhLQAPzwOzJs=; b=nONrkHxegzBnHL1fFAVLlXBqoR js2aqNr91M3mSVXmi04hNhLIMpvOx4oEAkS3lH79Fz3HEmPY0mIKMXwood2b1dnYoXnl05o5z/Q+z V68Hz9lUX/ujOCKzmCb11pHuv7wHRlqaCiBQmU5FME8QRvtwNdtrxaxiVgLVwkhOxIFYGJg5wMAhX IYkVnOGuyhBvo7PCIZU2WaL/g9SEH+Eb9rPc0daDqOuKPdmJfPOT1RF5BJslz9RyoTrzDLEbiVxYG MQvGwCRkajtEiUwLb/5ms1mDfH9w45NAWG+MFWu4F/0a+AZ8lnvchDlcl8WPy3SfbzDTh/AYYlpul qVyWfd4w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fgAqr-0001xg-8T; Thu, 19 Jul 2018 15:28:21 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fgAmT-00068s-TR for linux-mtd@lists.infradead.org; Thu, 19 Jul 2018 15:23:53 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 4556720884; Thu, 19 Jul 2018 17:23:39 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (AAubervilliers-681-1-27-161.w90-88.abo.wanadoo.fr [90.88.147.161]) by mail.bootlin.com (Postfix) with ESMTPSA id E8242206EE; Thu, 19 Jul 2018 17:23:38 +0200 (CEST) From: Miquel Raynal To: Boris Brezillon , Richard Weinberger , David Woodhouse , Brian Norris , Marek Vasut Subject: [PATCH 2/3] mtd: rawnand: marvell: support 8b/512B strength for 2kiB pages layout Date: Thu, 19 Jul 2018 17:23:36 +0200 Message-Id: <20180719152337.6372-3-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180719152337.6372-1-miquel.raynal@bootlin.com> References: <20180719152337.6372-1-miquel.raynal@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180719_082350_257516_9FAE4E6A X-CRM114-Status: GOOD ( 21.52 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [62.4.15.54 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antoine Tenart , Gregory Clement , Maxime Chevallier , Nadav Haklai , linux-mtd@lists.infradead.org, Thomas Petazzoni , Miquel Raynal , Ofer Heifetz MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add support for the layout used by 2kiB page NAND chips requesting at least 8-bit of correction per 512 bytes. This layout requires a bit of handling as: 1/ It can only fit if the NAND chip has at least 128 OOB bytes. 2/ The Bad Block Markers are located in the middle of the data bytes and shall not be used. 3/ It has been experimentally observed that, for certain layouts, the ECC engine tries to correct data while it should not because the errors are uncorrectable. While this is harmless for truly bad pages, it creates bitflips in empty pages. To avoid such scenario that augments artificially the number of bitflips we re-read in raw mode the entire page instead of just the ECC bytes. This is done only for this layout to avoid an unneeded penalty with other setups. Signed-off-by: Miquel Raynal --- drivers/mtd/nand/raw/marvell_nand.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 954b5755ba59..83bb4ef9baa6 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -217,6 +217,7 @@ static const struct marvell_hw_ecc_layout marvell_nfc_layouts[] = { MARVELL_LAYOUT( 512, 512, 1, 1, 1, 512, 8, 8, 0, 0, 0), MARVELL_LAYOUT( 2048, 512, 1, 1, 1, 2048, 40, 24, 0, 0, 0), MARVELL_LAYOUT( 2048, 512, 4, 1, 1, 2048, 32, 30, 0, 0, 0), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,32, 30), MARVELL_LAYOUT( 4096, 512, 4, 2, 2, 2048, 32, 30, 0, 0, 0), MARVELL_LAYOUT( 4096, 512, 8, 5, 4, 1024, 0, 30, 0, 64, 30), }; @@ -1287,9 +1288,11 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct mtd_info *mtd, * page is empty. In this case, it is normal that the ECC check failed * and we just ignore the error. * - * However, for any subpage read error reported by ->correct(), the ECC - * bytes must be read in raw mode and the full subpage must be checked - * to see if it is entirely empty of if there was an actual error. + * However, it has been empirically observed that for some layouts (e.g + * 2k page, 8b strength per 512B chunk), the controller tries to correct + * bits and may create itself bitflips in the erased area. To overcome + * this strange behavior, the whole page is re-read in raw mode, not + * only the ECC bytes. */ for (chunk = 0; chunk < lt->nchunks; chunk++) { int data_off_in_page, spare_off_in_page, ecc_off_in_page; @@ -1328,6 +1331,15 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct mtd_info *mtd, ecc_len = chunk < lt->full_chunk_cnt ? lt->ecc_bytes : lt->last_ecc_bytes; + if (lt->writesize == 2048 && lt->strength == 8) { + nand_change_read_column_op(chip, data_off_in_page, + buf + data_off, data_len, + false); + nand_change_read_column_op(chip, spare_off_in_page, + chip->oob_poi + spare_off, spare_len, + false); + } + nand_change_read_column_op(chip, ecc_off_in_page, chip->oob_poi + ecc_off, ecc_len, false); @@ -2112,6 +2124,16 @@ static int marvell_nand_hw_ecc_ctrl_init(struct mtd_info *mtd, return -ENOTSUPP; } + /* Special care for the layout 2k/8-bit/512B */ + if (l->writesize == 2048 && l->strength == 8) { + if (mtd->oobsize < 128) { + dev_err(nfc->dev, "Requested layout needs at least 128 OOB bytes\n"); + return -ENOTSUPP; + } else { + chip->bbt_options |= NAND_BBT_NO_OOB_BBM; + } + } + mtd_set_ooblayout(mtd, &marvell_nand_ooblayout_ops); ecc->steps = l->nchunks; ecc->size = l->data_bytes; From patchwork Thu Jul 19 15:23:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 946423 X-Patchwork-Delegate: miquel.raynal@bootlin.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Cq5as0cy"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Wd8h5Jfmz9s55 for ; Fri, 20 Jul 2018 01:24:04 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=otlRqMU3wzk2i3tOCCbnxrGl88I/3P8tpgn2mpFtPBM=; b=Cq5as0cyvBK3wWtK7cHGjGE6TC /NIemgTy8rvt6dbns2ZfGqjOgaRNsjNrNdCO2N5PS/D2s8QxQdDZLYWXUcstTzj8KTZ0E2/ezwn8x 5FOOr4KqgZ8OreU06mLPqwPbPT7YBqMi8p08rCbjmwBmWjixumHH3T2AplyR64ZPz/W92G2NOT0Ij EL93QL9B4JyPMcboNaAMOVW78egyNcWwfb9+quSbz2oVuohef+uSi/00BpKt+VpQb9zWeHCSGzOEb BAN/u2vdZrKYHujRs4G0pVE//HkVgoQtZb/TbON36p47ckrfHsh2BipmhcBI2F9lcQdTwGWsy5XnZ xt8vzU5g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fgAmd-0006Hv-Dx; Thu, 19 Jul 2018 15:23:59 +0000 Received: from mail.bootlin.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fgAmT-00068t-TU for linux-mtd@lists.infradead.org; Thu, 19 Jul 2018 15:23:51 +0000 Received: by mail.bootlin.com (Postfix, from userid 110) id 87F5420717; Thu, 19 Jul 2018 17:23:39 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost.localdomain (AAubervilliers-681-1-27-161.w90-88.abo.wanadoo.fr [90.88.147.161]) by mail.bootlin.com (Postfix) with ESMTPSA id 37801206F6; Thu, 19 Jul 2018 17:23:39 +0200 (CEST) From: Miquel Raynal To: Boris Brezillon , Richard Weinberger , David Woodhouse , Brian Norris , Marek Vasut Subject: [PATCH 3/3] mtd: rawnand: marvell: speed-up hamming failure path Date: Thu, 19 Jul 2018 17:23:37 +0200 Message-Id: <20180719152337.6372-4-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180719152337.6372-1-miquel.raynal@bootlin.com> References: <20180719152337.6372-1-miquel.raynal@bootlin.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180719_082350_112386_6559650C X-CRM114-Status: GOOD ( 18.57 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [62.4.15.54 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Antoine Tenart , Gregory Clement , Maxime Chevallier , Nadav Haklai , linux-mtd@lists.infradead.org, Thomas Petazzoni , Miquel Raynal , Ofer Heifetz MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org When a read triggers an ECC error it might have two causes: * Either there was too much bitflips and the data cannot be sanitized. * Or the page is empty. For the latter case, we need to re-read the page in raw mode to check for the ECC bytes to be 0xFF. This is done with a call to marvell_nfc_hw_ecc_hmg_do_read_page() which will trigger a new read inside the NAND chip and implies strong delays. As the data is already laying in the NAND cache, let's just retrieve it with the ECC engine turned off. As we are only reading a small section of the page, we can write directly in the OOB buffer at the right offset, there is no need to allocate a buffer for that. Signed-off-by: Miquel Raynal --- drivers/mtd/nand/raw/marvell_nand.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 83bb4ef9baa6..29cb3d2e121f 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -974,9 +974,7 @@ static int marvell_nfc_hw_ecc_hmg_read_page(struct mtd_info *mtd, int page) { const struct marvell_hw_ecc_layout *lt = to_marvell_nand(chip)->layout; - unsigned int full_sz = lt->data_bytes + lt->spare_bytes + lt->ecc_bytes; int max_bitflips = 0, ret; - u8 *raw_buf; marvell_nfc_enable_hw_ecc(chip); marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi, false, @@ -988,18 +986,16 @@ static int marvell_nfc_hw_ecc_hmg_read_page(struct mtd_info *mtd, return max_bitflips; /* - * When ECC failures are detected, check if the full page has been - * written or not. Ignore the failure if it is actually empty. + * When ECC failures are detected, check if the page has been + * written or not by re-reading the ECC bytes in raw mode. + * Ignore the failure if it is actually empty. */ - raw_buf = kmalloc(full_sz, GFP_KERNEL); - if (!raw_buf) - return -ENOMEM; - - marvell_nfc_hw_ecc_hmg_do_read_page(chip, raw_buf, raw_buf + - lt->data_bytes, true, page); - marvell_nfc_check_empty_chunk(chip, raw_buf, full_sz, NULL, 0, NULL, 0, + nand_change_read_column_op(chip, lt->data_bytes + lt->spare_bytes, + chip->oob_poi + lt->spare_bytes, + lt->ecc_bytes, false); + marvell_nfc_check_empty_chunk(chip, buf, lt->data_bytes, chip->oob_poi, + lt->spare_bytes + lt->ecc_bytes, NULL, 0, &max_bitflips); - kfree(raw_buf); return max_bitflips; }