From patchwork Thu Jul 16 21:59:43 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: nsnehaprabha@ti.com X-Patchwork-Id: 35947 Received: from devils.ext.ti.com (devils.ext.ti.com [198.47.26.153]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n6GLxvop010328 for ; Thu, 16 Jul 2009 21:59:57 GMT Received: from dlep33.itg.ti.com ([157.170.170.112]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id n6GLxqrt006069 for ; Thu, 16 Jul 2009 16:59:57 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep33.itg.ti.com (8.13.7/8.13.7) with ESMTP id n6GLxoJR008899 for ; Thu, 16 Jul 2009 16:59:51 -0500 (CDT) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id A00FF8065D for ; Thu, 16 Jul 2009 16:59:49 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dlep33.itg.ti.com (dlep33.itg.ti.com [157.170.170.112]) by linux.omap.com (Postfix) with ESMTP id 5C8EE80626 for ; Thu, 16 Jul 2009 16:59:44 -0500 (CDT) Received: from legion.dal.design.ti.com (localhost [127.0.0.1]) by dlep33.itg.ti.com (8.13.7/8.13.7) with ESMTP id n6GLxhN8008787; Thu, 16 Jul 2009 16:59:43 -0500 (CDT) Received: from gt9szxw61.gt.design.ti.com (gt9szxw61.gt.design.ti.com [158.218.100.25]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id n6GLxh907333; Thu, 16 Jul 2009 16:59:43 -0500 (CDT) Received: from gt9szxw61.gt.design.ti.com (localhost [127.0.0.1]) by gt9szxw61.gt.design.ti.com (8.13.1/8.13.1) with ESMTP id n6GLxheR011270; Thu, 16 Jul 2009 17:59:43 -0400 Received: (from a0869522@localhost) by gt9szxw61.gt.design.ti.com (8.13.1/8.13.1/Submit) id n6GLxhWb011267; Thu, 16 Jul 2009 17:59:43 -0400 From: nsnehaprabha@ti.com To: linux-mtd@lists.infradead.org, davinci-linux-open-source@linux.davincidsp.com, dwmw2@infradead.org, tglx@linutronix.de, akpm@linux-foundation.org Date: Thu, 16 Jul 2009 17:59:43 -0400 Message-Id: <1247781583-11239-1-git-send-email-nsnehaprabha@ti.com> X-Mailer: git-send-email 1.6.0.4 Cc: Subject: [PATCH v3 2/3] mtd-nand: Add new ECC mode - ECC_HW_OOB_FIRST X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.4 Precedence: list List-Id: davinci-linux-open-source.linux.davincidsp.com List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: davinci-linux-open-source-bounces+patchwork-davinci=patchwork.kernel.org@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces+patchwork-davinci=patchwork.kernel.org@linux.davincidsp.com From: Sneha Narnakaje This patch adds the new mode NAND_ECC_HW_OOB_FIRST in the nand code to support 4-bit ECC on TI DaVinci devices with large page (up to 2K) NAND chips. This ECC mode is similar to NAND_ECC_HW, with the exception of read_page API that first reads the OOB area, reads the data in chunks, feeds the ECC from OOB area to the ECC hw engine and perform any correction on the data as per the ECC status reported by the engine. "ECC_HW_OOB_FIRST" name suggested by Thomas Gleixner This patch series applies to linux-mtd next (mmotm) GIT tree. This patch is the same as v2 version of this patch. Reviewed-by: David Brownell Signed-off-by: Sneha Narnakaje Signed-off-by: Sandeep Paulraj --- drivers/mtd/nand/nand_base.c | 59 ++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/nand.h | 1 + 2 files changed, 60 insertions(+), 0 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 979988a..5140ca2 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -980,6 +980,54 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, } /** + * nand_read_page_hwecc_oob_first - [REPLACABLE] hw ecc, read oob first + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data + * + * Hardware ECC for large page chips, require OOB to be read first. + * For this ECC mode, the write_page method is re-used from ECC_HW. + * These methods read/write ECC from the OOB area, unlike the + * ECC_HW_SYNDROME support with multiple ECC steps, follows the + * "infix ECC" scheme and reads/writes ECC from the data area, by + * overwriting the NAND manufacturer bad block markings. + */ +static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, + struct nand_chip *chip, uint8_t *buf, int page) +{ + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *p = buf; + uint8_t *ecc_code = chip->buffers->ecccode; + uint32_t *eccpos = chip->ecc.layout->eccpos; + uint8_t *ecc_calc = chip->buffers->ecccalc; + + /* Read the OOB area first */ + chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); + chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); + + for (i = 0; i < chip->ecc.total; i++) + ecc_code[i] = chip->oob_poi[eccpos[i]]; + + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + int stat; + + chip->ecc.hwctl(mtd, NAND_ECC_READ); + chip->read_buf(mtd, p, eccsize); + chip->ecc.calculate(mtd, p, &ecc_calc[i]); + + stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); + if (stat < 0) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; + } + return 0; +} + +/** * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read * @mtd: mtd info structure * @chip: nand chip info structure @@ -2673,6 +2721,17 @@ int nand_scan_tail(struct mtd_info *mtd) */ switch (chip->ecc.mode) { + case NAND_ECC_HW_OOB_FIRST: + /* Similar to NAND_ECC_HW, but a separate read_page handle */ + if (!chip->ecc.calculate || !chip->ecc.correct || + !chip->ecc.hwctl) { + printk(KERN_WARNING "No ECC functions supplied, " + "Hardware ECC not possible\n"); + BUG(); + } + if (!chip->ecc.read_page) + chip->ecc.read_page = nand_read_page_hwecc_oob_first; + case NAND_ECC_HW: /* Use standard hwecc read page function ? */ if (!chip->ecc.read_page) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 686f370..7a232a9 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -121,6 +121,7 @@ typedef enum { NAND_ECC_SOFT, NAND_ECC_HW, NAND_ECC_HW_SYNDROME, + NAND_ECC_HW_OOB_FIRST, } nand_ecc_modes_t; /*