From patchwork Mon Jun 6 15:21:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris Brezillon X-Patchwork-Id: 630956 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3rNdhZ1vsVz9t6F for ; Tue, 7 Jun 2016 01:21:33 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0D71AA751E; Mon, 6 Jun 2016 17:21:28 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id b1YwViK8BNx2; Mon, 6 Jun 2016 17:21:27 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 6DEC0A74DB; Mon, 6 Jun 2016 17:21:27 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7ABB3A74DB for ; Mon, 6 Jun 2016 17:21:23 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 5O8bQ-HKR857 for ; Mon, 6 Jun 2016 17:21:23 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail.free-electrons.com (down.free-electrons.com [37.187.137.238]) by theia.denx.de (Postfix) with ESMTP id 32821A74D0 for ; Mon, 6 Jun 2016 17:21:21 +0200 (CEST) Received: by mail.free-electrons.com (Postfix, from userid 110) id 9C3142E0; Mon, 6 Jun 2016 17:21:20 +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 bbrezillon.home (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id 3A6321F9; Mon, 6 Jun 2016 17:21:20 +0200 (CEST) From: Boris Brezillon To: Hans de Goede , Scott Wood Date: Mon, 6 Jun 2016 17:21:14 +0200 Message-Id: <1465226478-22252-3-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1465226478-22252-1-git-send-email-boris.brezillon@free-electrons.com> References: <1465226478-22252-1-git-send-email-boris.brezillon@free-electrons.com> Cc: Tom Rini , u-boot@lists.denx.de, linux-sunxi@googlegroups.com, Brian Norris Subject: [U-Boot] [PATCH 2/6] mtd: nand: add common DT init code X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 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: Brian Norris These are already-documented common bindings for NAND chips. Let's handle them in nand_base. If NAND controller drivers need to act on this data before bringing up the NAND chip (e.g., fill out ECC callback functions, change HW modes, etc.), then they can do so between calling nand_scan_ident() and nand_scan_tail(). The original commit has been slightly reworked to use the fdtdec_xxx() helpers (instead of the of_xxxx() ones). Signed-off-by: Brian Norris Signed-off-by: Boris Brezillon --- drivers/mtd/nand/nand_base.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/nand.h | 3 ++ 2 files changed, 73 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 74c563c..c72ff86 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -29,6 +29,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#if CONFIG_IS_ENABLED(OF_CONTROL) +#include +#endif #include #include #include @@ -3764,6 +3767,66 @@ ident_done: return type; } +#if CONFIG_IS_ENABLED(OF_CONTROL) +DECLARE_GLOBAL_DATA_PTR; + +static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node) +{ + int ret, ecc_mode = -1, ecc_strength, ecc_step; + const void *blob = gd->fdt_blob; + const char *str; + + ret = fdtdec_get_int(blob, node, "nand-bus-width", -1); + if (ret == 16) + chip->options |= NAND_BUSWIDTH_16; + + if (fdtdec_get_bool(blob, node, "nand-on-flash-bbt")) + chip->bbt_options |= NAND_BBT_USE_FLASH; + + str = fdt_getprop(blob, node, "nand-ecc-mode", NULL); + if (str) { + if (!strcmp(str, "none")) + ecc_mode = NAND_ECC_NONE; + else if (!strcmp(str, "soft")) + ecc_mode = NAND_ECC_SOFT; + else if (!strcmp(str, "hw")) + ecc_mode = NAND_ECC_HW; + else if (!strcmp(str, "hw_syndrome")) + ecc_mode = NAND_ECC_HW_SYNDROME; + else if (!strcmp(str, "hw_oob_first")) + ecc_mode = NAND_ECC_HW_OOB_FIRST; + else if (!strcmp(str, "soft_bch")) + ecc_mode = NAND_ECC_SOFT_BCH; + } + + + ecc_strength = fdtdec_get_int(blob, node, "nand-ecc-strength", -1); + ecc_step = fdtdec_get_int(blob, node, "nand-ecc-step-size", -1); + + if ((ecc_step >= 0 && !(ecc_strength >= 0)) || + (!(ecc_step >= 0) && ecc_strength >= 0)) { + pr_err("must set both strength and step size in DT\n"); + return -EINVAL; + } + + if (ecc_mode >= 0) + chip->ecc.mode = ecc_mode; + + if (ecc_strength >= 0) + chip->ecc.strength = ecc_strength; + + if (ecc_step > 0) + chip->ecc.size = ecc_step; + + return 0; +} +#else +static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node) +{ + return 0; +} +#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ + /** * nand_scan_ident - [NAND Interface] Scan for the NAND device * @mtd: MTD device structure @@ -3780,6 +3843,13 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, int i, nand_maf_id, nand_dev_id; struct nand_chip *chip = mtd_to_nand(mtd); struct nand_flash_dev *type; + int ret; + + if (chip->flash_node) { + ret = nand_dt_init(mtd, chip, chip->flash_node); + if (ret) + return ret; + } /* Set the default functions */ nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index b5a02c3..29aae43 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -590,6 +590,7 @@ struct nand_buffers { * flash device * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the * flash device. + * @flash_node: [BOARDSPECIFIC] device node describing this instance * @read_byte: [REPLACEABLE] read one byte from the chip * @read_word: [REPLACEABLE] read one word from the chip * @write_byte: [REPLACEABLE] write a single byte to the chip on the @@ -689,6 +690,8 @@ struct nand_chip { void __iomem *IO_ADDR_R; void __iomem *IO_ADDR_W; + int flash_node; + uint8_t (*read_byte)(struct mtd_info *mtd); u16 (*read_word)(struct mtd_info *mtd); void (*write_byte)(struct mtd_info *mtd, uint8_t byte);