From patchwork Tue Jan 9 10:11:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sascha Hauer X-Patchwork-Id: 857355 X-Patchwork-Delegate: boris.brezillon@free-electrons.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=65.50.211.133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="lEUwZ8Kh"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="vUE/kVe7"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.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 3zG7TD6p1Xz9s82 for ; Tue, 9 Jan 2018 21:21:04 +1100 (AEDT) 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=QzocvfSotfhc65p7A1a7JHtN4ySZg4UNDYZRHsCclqw=; b=lEUwZ8KhJuhUIt99uH9TKhjy9f ijeL1cJ/DeyyXWmJHeuG/o6HooFt12t4xydvXPMnK9U645TeAmY/1gugcw7yl6wUsAxDyYtapstOo 4/GSoD81txGuCRV9XergL9rWFYmhRyb++gWFJ1V85lVovefnf2x4yz5QT3ZSqqU5nDOLaXnu39YFq CJNakdSxs3kxlRh0MegzZHy6/8gi1Ow+jyBrqwYUyOhxnVhpVs/z5vswv1ltXj0dQpUz43Z07TGh3 htuE3J4p23vqbyhPe7X3eHp+8L+IAq+JnbgyXKyIR9DQgixIi0T7s5cgRFUpnatSLm3l0iS9j3SON IGnLd2/Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1eYr1a-0006tC-Oo; Tue, 09 Jan 2018 10:20:54 +0000 Received: from casper.infradead.org ([85.118.1.10]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eYqx2-0002QF-J1 for linux-mtd@bombadil.infradead.org; Tue, 09 Jan 2018 10:16:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=iDWsCSKRlxu73b/fGMrMlnM9KVQ54BkOYh/nG2zfsXQ=; b=vUE/kVe7YH+zudl61TBc5uxjv Omg6uhP4p1gqC2OGGugRbOlZ5jNTsBarhfobkstGaCkkZcVzo1CzG7YaxbVzHBG6dCSNExSDi1f9D Q6ZjpSHxQgHUshlXzxUH/8ihGSbUCd4zrFeVbBbvqMNk/ah454595QMlCBdEgvnj/GKFbH6ag40Oy 4elYnGWZTmpajwf+fMg81m5ITBDVZpprXTEAjMYFainzGd+UHefir+ijRuaoSapbx2LPMGFz+ePoL v8dO1s0uxye36SHDkcvKVBF3a1PkwcaOQOMlSpZxUY+CgT4vrLhcMIaWABwXyYkCCRrwY/XfXF26n fzUp4sd0Q==; Received: from metis.ext.pengutronix.de ([2001:67c:670:201:290:27ff:fe1d:cc33]) by casper.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1eYqt4-0007RQ-Tu for linux-mtd@lists.infradead.org; Tue, 09 Jan 2018 10:12:14 +0000 Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1eYqsr-000258-3Z; Tue, 09 Jan 2018 11:11:53 +0100 Received: from sha by dude.hi.pengutronix.de with local (Exim 4.89) (envelope-from ) id 1eYqsq-0007vR-MK; Tue, 09 Jan 2018 11:11:52 +0100 From: Sascha Hauer To: linux-mtd@lists.infradead.org Subject: [PATCH 5/8] mtd: nand: mxc: Fix failed/corrected values for v1 controllers Date: Tue, 9 Jan 2018 11:11:45 +0100 Message-Id: <20180109101148.13728-6-s.hauer@pengutronix.de> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180109101148.13728-1-s.hauer@pengutronix.de> References: <20180109101148.13728-1-s.hauer@pengutronix.de> X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: sha@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-mtd@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180109_101206_991666_68A32647 X-CRM114-Status: GOOD ( 24.76 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.1 on casper.infradead.org summary: Content analysis details: (-1.9 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2001:67c:670:201:290:27ff:fe1d:cc33 listed in] [list.dnswl.org] -0.0 T_RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 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: Boris Brezillon , Sascha Hauer , kernel@pengutronix.de, Richard Weinberger MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The v1 controller code has several flaws: - We do not forward the number of corrected bitflips to the upper layers - For 2k page NAND chips only the status results from the fourth subpage read are evaluated, so ECC failures in the other subpages remain uncovered - When there are uncorrectable errors we have to increase the statistics counter, but still have to return successfully. Currently we return an error This patch fixes this by introducing a v1 specific read_page function. Signed-off-by: Sascha Hauer --- drivers/mtd/nand/mxc_nand.c | 78 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index d698f7c6666c..83bb01ab7079 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -738,22 +738,68 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { + return 0; +} + +static int mxc_nand_read_page_v1(struct mtd_info *mtd, struct nand_chip *chip, + void *buf, void *oob, bool ecc, int page) +{ struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_get_controller_data(nand_chip); + struct mxc_nand_host *host = nand_get_controller_data(chip); + unsigned int max_bitflips = 0; + int no_subpages; + int i; - /* - * 1-Bit errors are automatically corrected in HW. No need for - * additional correction. 2-Bit errors cannot be corrected by - * HW ECC, so we need to return failure - */ - uint16_t ecc_status = get_ecc_status_v1(host); + host->devtype_data->enable_hwecc(nand_chip, ecc); + + host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); + mxc_do_addr_cycle(mtd, 0, page); + + if (mtd->writesize > 512) + host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true); - if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { - dev_dbg(host->dev, "HWECC uncorrectable 2-bit ECC error\n"); - return -EBADMSG; + no_subpages = mtd->writesize >> 9; + + for (i = 0; i < no_subpages; i++) { + int flips = 0; + uint16_t ecc_stats; + + /* NANDFC buffer 0 is used for page read/write */ + writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); + + writew(NFC_OUTPUT, NFC_V1_V2_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, true); + + ecc_stats = get_ecc_status_v1(host); + + ecc_stats >>= 2; + + if (buf && ecc) { + switch (ecc_stats & 0x3) { + case 0: + default: + break; + case 1: + mtd->ecc_stats.corrected++; + flips++; + break; + case 2: + mtd->ecc_stats.failed++; + break; + } + } + + max_bitflips = max_t(unsigned int, max_bitflips, flips); } - return 0; + if (buf) + memcpy32_fromio(buf, host->main_area0, mtd->writesize); + if (oob) + copy_spare(mtd, true, oob); + + return max_bitflips; } static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, @@ -1494,6 +1540,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { /* v1 + irqpending_quirk: i.MX21 */ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { .preset = preset_v1, + .read_page = mxc_nand_read_page_v1, .send_cmd = send_cmd_v1_v2, .send_addr = send_addr_v1_v2, .send_page = send_page_v1, @@ -1518,6 +1565,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { /* v1 + !irqpending_quirk: i.MX27, i.MX31 */ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = { .preset = preset_v1, + .read_page = mxc_nand_read_page_v1, .send_cmd = send_cmd_v1_v2, .send_addr = send_addr_v1_v2, .send_page = send_page_v1, @@ -1856,11 +1904,9 @@ static int mxcnd_probe(struct platform_device *pdev) switch (this->ecc.mode) { case NAND_ECC_HW: - if (host->devtype_data->read_page) { - this->ecc.read_page = mxc_nand_read_page; - this->ecc.read_page_raw = mxc_nand_read_page_raw; - this->ecc.read_oob = mxc_nand_read_oob; - } + this->ecc.read_page = mxc_nand_read_page; + this->ecc.read_page_raw = mxc_nand_read_page_raw; + this->ecc.read_oob = mxc_nand_read_oob; this->ecc.calculate = mxc_nand_calculate_ecc; this->ecc.hwctl = mxc_nand_enable_hwecc; this->ecc.correct = host->devtype_data->correct_data;