From patchwork Sat Nov 30 17:17:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ezequiel Garcia X-Patchwork-Id: 3260851 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2A41EBEEAD for ; Sat, 30 Nov 2013 17:19:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 15B0E20555 for ; Sat, 30 Nov 2013 17:19:28 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DBBC9204EB for ; Sat, 30 Nov 2013 17:19:26 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1VmoCQ-0003Cx-GT; Sat, 30 Nov 2013 17:19:22 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VmoCO-0003sv-2u; Sat, 30 Nov 2013 17:19:20 +0000 Received: from top.free-electrons.com ([176.31.233.9] helo=mail.free-electrons.com) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1VmoCJ-0003rM-Nb; Sat, 30 Nov 2013 17:19:16 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id E0C03880; Sat, 30 Nov 2013 18:18:58 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (unknown [190.2.98.212]) by mail.free-electrons.com (Postfix) with ESMTPA id 62985854; Sat, 30 Nov 2013 18:18:55 +0100 (CET) From: Ezequiel Garcia To: , , , Subject: [RFC/PATCH v2] mtd: nand: Fix ONFI detection of 16-bit width NAND devices Date: Sat, 30 Nov 2013 14:17:39 -0300 Message-Id: <1385831859-19170-2-git-send-email-ezequiel.garcia@free-electrons.com> X-Mailer: git-send-email 1.8.1.5 In-Reply-To: <1385831859-19170-1-git-send-email-ezequiel.garcia@free-electrons.com> References: <1385831859-19170-1-git-send-email-ezequiel.garcia@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131130_121915_970390_373E3F50 X-CRM114-Status: GOOD ( 17.63 ) X-Spam-Score: -1.2 (-) Cc: shc_work@mail.ru, Artem Bityutskiy , Pekon Gupta , Ezequiel Garcia , u.kleine-koenig@pengutronix.de, Brian Norris , David Woodhouse X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP This patch is alternative implementation for following commit which introduced NAND_BUSWIDTH_AUTO for detection of bus-width during device probe commit 64b37b2a63eb2f80b65c7185f0013f8ffc637ae3 Author: Matthieu CASTET AuthorDate: 2012-11-06 As NAND device is identified only during nand_scan_ident(), so this patch assumes that NAND driver may un-initialized or partially congigured while calling nand_scan_ident(). Hence, this patch does following: 1. Temporarily configures 'bus-width=x8' mode before reading ONFI parameters, as required by ONFI specification [1]. 2. Reconfigures the driver with correct bus-width determined by either reading ONFI param, or the nand_flash_id[] table. This patch removes any dependency on either 'DT binding' or 'platform data' to specify the NAND device bus-width. [*] Reference: ONFI spec version 3.1 (section 3.5.3. Target Initialization) "The Read ID and Read Parameter Page commands only use the lower 8-bits of the data bus. The host shall not issue commands that use a word data width on x16 devices until the host determines the device supports a 16-bit data bus width in the parameter page." Signed-off-by: Pekon Gupta Signed-off-by: Ezequiel Garcia --- drivers/mtd/nand/nand_base.c | 43 +++++++++++++------------------------------ 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bd39f7b..3ff9944 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2942,15 +2942,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') return 0; - /* - * ONFI must be probed in 8-bit mode or with NAND_BUSWIDTH_AUTO, not - * with NAND_BUSWIDTH_16 - */ - if (chip->options & NAND_BUSWIDTH_16) { - pr_err("ONFI cannot be probed in 16-bit mode; aborting\n"); - return 0; - } - chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); for (i = 0; i < 3; i++) { chip->read_buf(mtd, (uint8_t *)p, sizeof(*p)); @@ -3335,13 +3326,21 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, */ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, struct nand_chip *chip, - int busw, int *maf_id, int *dev_id, struct nand_flash_dev *type) { int i, maf_idx; + int busw = 0; u8 id_data[8]; + /* + * The device detection is done in 8-bit mode. The real bus width + * will be autodetected (either ONFI or flash-based), the + * defaults re-configured and the chip->options updated. + */ + nand_set_defaults(chip, 0); + chip->options &= ~NAND_BUSWIDTH_16; + /* Select the device */ chip->select_chip(mtd, 0); @@ -3431,22 +3430,10 @@ ident_done: break; } - if (chip->options & NAND_BUSWIDTH_AUTO) { - WARN_ON(chip->options & NAND_BUSWIDTH_16); + /* Configure driver using detected bus-width */ + if (busw) { chip->options |= busw; nand_set_defaults(chip, busw); - } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { - /* - * Check, if buswidth is correct. Hardware drivers should set - * chip correct! - */ - pr_info("NAND device: Manufacturer ID:" - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, - *dev_id, nand_manuf_ids[maf_idx].name, mtd->name); - pr_warn("NAND bus width %d instead %d bit\n", - (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, - busw ? 16 : 8); - return ERR_PTR(-EINVAL); } nand_decode_bbm_options(mtd, chip, id_data); @@ -3497,17 +3484,13 @@ ident_done: int nand_scan_ident(struct mtd_info *mtd, int maxchips, struct nand_flash_dev *table) { - int i, busw, nand_maf_id, nand_dev_id; + int i, nand_maf_id, nand_dev_id; struct nand_chip *chip = mtd->priv; struct nand_flash_dev *type; - /* Get buswidth to select the correct functions */ - busw = chip->options & NAND_BUSWIDTH_16; - /* Set the default functions */ - nand_set_defaults(chip, busw); /* Read the flash type */ - type = nand_get_flash_type(mtd, chip, busw, + type = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, table); if (IS_ERR(type)) {