From patchwork Tue Nov 21 17:38:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 840132 X-Patchwork-Delegate: yamada.m@jp.panasonic.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.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=nifty.com header.i=@nifty.com header.b="SiHNsYI/"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3yhChB282yz9s8J for ; Wed, 22 Nov 2017 04:46:50 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id DF6EAC21EA8; Tue, 21 Nov 2017 17:43:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id E10E4C21F7F; Tue, 21 Nov 2017 17:39:30 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 92740C21F80; Tue, 21 Nov 2017 17:39:07 +0000 (UTC) Received: from conuserg-07.nifty.com (conuserg-07.nifty.com [210.131.2.74]) by lists.denx.de (Postfix) with ESMTPS id 2B738C21F6A for ; Tue, 21 Nov 2017 17:39:05 +0000 (UTC) Received: from grover.sesame (FL1-125-199-20-195.osk.mesh.ad.jp [125.199.20.195]) (authenticated) by conuserg-07.nifty.com with ESMTP id vALHcbu2001225; Wed, 22 Nov 2017 02:38:43 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-07.nifty.com vALHcbu2001225 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1511285923; bh=2KPYoafeSwy47H+2Kiy1+mQ+uZRTOylyJXqtn1KCw3w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SiHNsYI/GrLLNhAId9YWCtbxxOJ33/cDEndqMSqqCu1CqmYiDrCiTme4d/ZjuShHL 4d46TxGr3ZZnaloxKNCWQwjhU4hlUQAuBAkTECtIL7aNGkECQHGbv/uqieC0IIwcwP UbUNfKFFk1J5Y/XL7ITMTx7AalJyKoJIyBFUzcdZyavJDlPBj7Ywq/nxLhUT1oJJba C7VTvtc6/HSunMVKECmm4+qPcxACd890y9KmDFSHCiz5jCmFOSG/EloPdQODPNhb9b rGCI42oSdVLROxBhcpeZtOQC7ihjC0CejTb3Z+bmMBAt6l1nHj9TpItIP38C28WZdF V2ekd0ax/j0Mw== X-Nifty-SrcIP: [125.199.20.195] From: Masahiro Yamada To: u-boot@lists.denx.de Date: Wed, 22 Nov 2017 02:38:22 +0900 Message-Id: <1511285912-12452-13-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1511285912-12452-1-git-send-email-yamada.masahiro@socionext.com> References: <1511285912-12452-1-git-send-email-yamada.masahiro@socionext.com> Cc: Scott Wood Subject: [U-Boot] [PATCH 12/22] mtd: nand: Support controllers with custom page X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Marc Gonzalez If your controller already sends the required NAND commands when reading or writing a page, then the framework is not supposed to send READ0 and SEQIN/PAGEPROG respectively. Signed-off-by: Marc Gonzalez Signed-off-by: Boris Brezillon [Linux commit: 3371d663bb4579f1b2003a92162edd6d90edd089] Signed-off-by: Masahiro Yamada --- drivers/mtd/nand/nand_base.c | 34 +++++++++++++++++++++++++++++++--- include/linux/mtd/nand.h | 12 ++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5054c0e..d9f0a75 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1732,7 +1732,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, __func__, buf); read_retry: - chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); + if (nand_standard_page_accessors(&chip->ecc)) + chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); /* * Now read the page into the buffer. Absent an error, @@ -2423,7 +2424,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, else subpage = 0; - chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); + if (nand_standard_page_accessors(&chip->ecc)) + chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); if (unlikely(raw)) status = chip->ecc.write_page_raw(mtd, chip, buf, @@ -2446,7 +2448,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, if (!cached || !NAND_HAS_CACHEPROG(chip)) { - chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); + if (nand_standard_page_accessors(&chip->ecc)) + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); status = chip->waitfunc(mtd, chip); /* * See if operation failed and additional status checks are @@ -4126,6 +4129,26 @@ static bool nand_ecc_strength_good(struct mtd_info *mtd) return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds; } +static bool invalid_ecc_page_accessors(struct nand_chip *chip) +{ + struct nand_ecc_ctrl *ecc = &chip->ecc; + + if (nand_standard_page_accessors(ecc)) + return false; + + /* + * NAND_ECC_CUSTOM_PAGE_ACCESS flag is set, make sure the NAND + * controller driver implements all the page accessors because + * default helpers are not suitable when the core does not + * send the READ0/PAGEPROG commands. + */ + return (!ecc->read_page || !ecc->write_page || + !ecc->read_page_raw || !ecc->write_page_raw || + (NAND_HAS_SUBPAGE_READ(chip) && !ecc->read_subpage) || + (NAND_HAS_SUBPAGE_WRITE(chip) && !ecc->write_subpage && + ecc->hwctl && ecc->calculate)); +} + /** * nand_scan_tail - [NAND Interface] Scan for the NAND device * @mtd: MTD device structure @@ -4145,6 +4168,11 @@ int nand_scan_tail(struct mtd_info *mtd) BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) && !(chip->bbt_options & NAND_BBT_USE_FLASH)); + if (invalid_ecc_page_accessors(chip)) { + pr_err("Invalid ECC page accessors setup\n"); + return -EINVAL; + } + if (!(chip->options & NAND_OWN_BUFFERS)) { nbuf = kzalloc(sizeof(struct nand_buffers), GFP_KERNEL); chip->buffers = nbuf; diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 8b76275..72b2328 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -154,6 +154,12 @@ typedef enum { */ #define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) #define NAND_ECC_MAXIMIZE BIT(1) +/* + * If your controller already sends the required NAND commands when + * reading or writing a page, then the framework is not supposed to + * send READ0 and SEQIN/PAGEPROG respectively. + */ +#define NAND_ECC_CUSTOM_PAGE_ACCESS BIT(2) /* Bit mask for flags passed to do_nand_read_ecc */ #define NAND_GET_DEVICE 0x80 @@ -202,6 +208,7 @@ typedef enum { /* Macros to identify the above */ #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ)) +#define NAND_HAS_SUBPAGE_WRITE(chip) !((chip)->options & NAND_NO_SUBPAGE_WRITE) /* Non chip related options */ /* This option skips the bbt scan during initialization. */ @@ -568,6 +575,11 @@ struct nand_ecc_ctrl { int page); }; +static inline int nand_standard_page_accessors(struct nand_ecc_ctrl *ecc) +{ + return !(ecc->options & NAND_ECC_CUSTOM_PAGE_ACCESS); +} + /** * struct nand_buffers - buffer structure for read/write * @ecccalc: buffer pointer for calculated ECC, size is oobsize.