From patchwork Sat Apr 29 09:06:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Petazzoni X-Patchwork-Id: 756704 X-Patchwork-Delegate: boris.brezillon@free-electrons.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3wFPws3H8Mz9s4s for ; Sat, 29 Apr 2017 19:08:13 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="T4Jke514"; dkim-atps=neutral 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=pQMFeu8VApS1M8/dL1/ub2H7CnCTiBxI7ttnKJQuTRo=; b=T4Jke514/6ev72zMkb7l/Xe+Rp R0fGK37HkbIxdbLTjh5/kC/pCE/ZIStmdripwiJufHLGZAd3LX7lyviFE+hLImhqH7O9/O1hsOuB2 opzZcwqG0g0qOMyiAu55eEggJnxyBZfgpRnpcBDNV4e5okUQa45NC3mRwG3XVXCNbzowyshYTMAdl DK1BHUVk88GUMxL0+l4CAdkX/sH9Vk9TPzcf4yupwOTVURMU6kO7EhhXWP24T//PwYzGyDB61f8/l YbVatqH3kjDn6ZU7PBa31YEpso6k5caVgETPVC8/9eYAjDnuCMCFGKB7zLENXMGj06WBGvbYzJsq2 hp7PAlxA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1d4OMM-0002tP-Ps; Sat, 29 Apr 2017 09:08:10 +0000 Received: from mail.free-electrons.com ([62.4.15.54]) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1d4OLW-0002Eq-FZ for linux-mtd@lists.infradead.org; Sat, 29 Apr 2017 09:07:20 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id 796292081E; Sat, 29 Apr 2017 11:06:59 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.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 (132.230.147.77.rev.sfr.net [77.147.230.132]) by mail.free-electrons.com (Postfix) with ESMTPSA id 01316207D1; Sat, 29 Apr 2017 11:06:58 +0200 (CEST) From: Thomas Petazzoni To: Boris Brezillon , Marek Vasut , Richard Weinberger , Cyrille Pitchen , David Woodhouse , Brian Norris , linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, Rob Herring , Ian Campbell , Pawel Moll , Mark Rutland , Kumar Gala Subject: [PATCH v2 2/5] mtd: nand: add core support for on-die ECC Date: Sat, 29 Apr 2017 11:06:43 +0200 Message-Id: <1493456806-18898-3-git-send-email-thomas.petazzoni@free-electrons.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493456806-18898-1-git-send-email-thomas.petazzoni@free-electrons.com> References: <1493456806-18898-1-git-send-email-thomas.petazzoni@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170429_020718_857413_7F588DF2 X-CRM114-Status: GOOD ( 17.38 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 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: Thomas Petazzoni MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org A number of NAND flashes have a capability called "on-die ECC" where the NAND chip itself is capable of detecting and correcting errors. Linux already has support for using the ECC implementation of the NAND controller, or a software based ECC implementation, but not for using the ECC implementation of the NAND controller. However, such an implementation is sometimes useful in situations where the NAND controller provides ECC algorithms that are not strong enough for the NAND chip used on the system. A typical case is a NAND chip that requires a 4-bit ECC, while the NAND controller only provides a 1-bit ECC algorithm. This commit introduces the support for the NAND_ECC_ON_DIE ECC mode: - Parsing of the "on-die" value for the "nand-ecc-mode" Device Tree property - Handling NAND_ECC_ON_DIE case in nand_scan_tail(). The idea is that the vendor specific code for the NAND chip must implement ->read_page() and ->write_page(). It may optionally provide its own ->read_page_raw() and ->write_page_raw() as well. For OOB operation, we assume the standard operations are good enough, but they can be overridden by the vendor specific code if needed. Signed-off-by: Thomas Petazzoni Reviewed-by: Richard Weinberger --- drivers/mtd/nand/nand_base.c | 13 +++++++++++++ include/linux/mtd/nand.h | 1 + 2 files changed, 14 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ed49a1d..b639e88 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -4109,6 +4109,7 @@ static const char * const nand_ecc_modes[] = { [NAND_ECC_HW] = "hw", [NAND_ECC_HW_SYNDROME] = "hw_syndrome", [NAND_ECC_HW_OOB_FIRST] = "hw_oob_first", + [NAND_ECC_ON_DIE] = "on-die", }; static int of_get_nand_ecc_mode(struct device_node *np) @@ -4649,6 +4650,18 @@ int nand_scan_tail(struct mtd_info *mtd) } break; + case NAND_ECC_ON_DIE: + if (!ecc->read_page || !ecc->write_page) { + WARN(1, "No ECC functions supplied; on-die ECC not possible\n"); + ret = -EINVAL; + goto err_free; + } + if (!ecc->read_oob) + ecc->read_oob = nand_read_oob_std; + if (!ecc->write_oob) + ecc->write_oob = nand_write_oob_std; + break; + case NAND_ECC_NONE: pr_warn("NAND_ECC_NONE selected by board driver. This is not recommended!\n"); ecc->read_page = nand_read_page_raw; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 8f67b15..6035220 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -116,6 +116,7 @@ typedef enum { NAND_ECC_HW, NAND_ECC_HW_SYNDROME, NAND_ECC_HW_OOB_FIRST, + NAND_ECC_ON_DIE, } nand_ecc_modes_t; enum nand_ecc_algo {